<!-- 파일 업로드 처리 --> <% //1. 파일 저장 위치 (가상경로) 만들기 // D:\workspace_jsp7\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\fileUpload/upload //System.out.println("가상경로 : "+request.getRealPath("/upload")); String uploadPath = request.getRealPath("/upload");
//2. 저장 크기 지정 (10MB) int maxSize = 10 * 1024 * 1024;
//3. 정보를 저장하는 변수 만들기 String name =""; String subject =""; String filename = ""; //서버에 올라갈 파일명 String OFilename = ""; //오리지널 파일명
//6. 예외처리 try{ //4. MultipartRequest 객체생성 //4-1. cos 라이브러리 추가 //4-2. 객체 생성 //request정보를 직접가져올 수 없고 multi를 통해서 가져올 수 있다. MultipartRequest multi = new MultipartRequest(request, uploadPath, maxSize, "UTF-8", new DefaultFileRenamePolicy());
//5. 파일업로드완료 //5-1. 전달되는 이름, 제목 저장 name = multi.getParameter("name"); subject = multi.getParameter("subject"); //5-2. 전달된 파일의 이름 확인 Enumeration files = multi.getFileNames(); //업캐스팅 String file1 = (String) files.nextElement(); //위의 업캐스팅한 걸 다운캐스팅 //5-3. 서버에 저장되는 파일 이름 filename = multi.getFilesystemName(file1); System.out.println("filename : "+filename); //5-4. 원래 파일이름 OFilename = multi.getOriginalFileName(file1); System.out.println("OFilename : "+OFilename); //여기까지 업로드 기능 구현 완료! => 6. 파일업로드는 예외가 많이때문에 예외처리를 해야한다 }catch(Exception e){ e.printStackTrace(); } %>
<!-- 데이터를 전달하기 enctype안적어도 될까? 업로드 유무로 판단! 업로드할꺼면 필요, 업로드하지않을거면 필요하지않다 아래처럼 input type을 text로 그냥 가져가면 중요한 정보들이 유출될 수있다. 보안을 위해 2가지 방법이 있다. 1안은 submit버튼사용 2안은 a태그사용한 방법이다. 편한 걸로하면되지만 보통 2안으로 많이한다 -->
MIME타입 : 클라이언트에게 전송되는 데이터(문서)를 다양하게 처리 가능하도록 하는 메커니즘 웹에서 파일의 확장자는 큰 의미가 없음(스트림형태로 데이터가 전달) -> 스트림형태일때는 데이터 구분못함. 따라서 각 데이터(문서)에서 올바른 형태의 데이터를 전달하도록 MIME 타입을 지정 브라우저들이 응답정보(리소스)를 받았을때 어떤 형태로 처리해야하는지 판단하는 기준 마임타입을 가져오는 방법은 getServletContext().getMimeType()으로 가능
브라우저에 따른 데이터 처리(대응)
왜 인터넷익스플로러를 기준으로 나눌까?
인터넷익스폴러는 다운로드시 한글파일이 깨짐 -> 따라서 파일을 인코딩해서 다운로드함
이때 공백문자가 플러스(+)기호로 나옴 -> 이걸 %20으로 변경
인터넷익스플로러인지 아닌지는 어떻게 구분할까?
접속한 사용자정보(User-Agent)를 불러와서 indexOf사용하여 MSIE이나 Trident이 들어가 있으면 익스플로러이다.
<%@pageimport="java.net.URLEncoder"%> <%@pageimport="javax.activation.MimeType"%> <%@pageimport="java.io.FileInputStream"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% //1. 전달받은 데이터 저장 String filename = request.getParameter("file_name"); System.out.println(" 전달된 파일 명 : "+filename);
//2. 파일 다운로드할 위치(= 파일 업로드 위치) =>가상경로 //savepath는 저장되는 폴더명 String savepath = "upload";
//3. 내 프로젝트 정보(ServletContext)안에서 가상경로를 실제경로로 계산해줘야한다. //3-1. 서버안에 있는 물리적 위치 확인 ServletContext context = getServletContext(); String DownloadPath = context.getRealPath(savepath); System.out.println("DownloadPath : "+DownloadPath); //3-2. 다운로드할 파일의 전체 경로 //역슬러시 두개는 이스케이프문자로서 역슬러시 1개만 표현됨 String FilePath = DownloadPath+"\\"+filename; //여기까지다운로드기능완료
//4. 데이터 응답처리를 다운로드 형태로 구현 //4-1. 파일을 한번에 처리하기위한 배열 byte[] b = newbyte[4069];
//4-2. 파일입출력을 처리하는 파일 입력 스트림 객체생성(즉, 파일을 읽어오는 통로만들기) FileInputStream fis = new FileInputStream(FilePath);
//4-3. 다운로드할 파일의 마임타입 확인(mime) //=> 클라이언트에게 전송되는 데이터(문서)를 다양하게 처리 가능하도록 하는 메커니즘 String MimeType = getServletContext().getMimeType(FilePath); System.out.println("Mime type: "+MimeType);
if(MimeType == null){ //기본값 지정 - 이진파일을 처리하기위한 기본타입 //-> 잘 알려지지 않은 파일을 의미하기때문에 //-> 브라우저는 보통 자동실행을 안하고 대화상자를 이용하여 사용자에게 실행할지 질문함 MimeType = "application/octet-stream"; }
//4-4내 응답정보를 마임타입으로 지정 response.setContentType(MimeType);
//5. 브라우저에 따른 데이터 처리(대응) //왜 인터넷익스플로러를 기준으로 나눌까? //인터넷익스폴러는 다운로드시 한글파일이 깨짐 -> 따라서 파일을 인코딩해서 다운로드함 //이때 공백문자가 플러스(+)기호로 나옴 -> 이걸 %20(공백)으로 변경
//6. 데이터다운로드 처리 //브라우저가 응답정보를 읽어서(해석) 처리시 //"Content-Disposition" 설정값이 "attachment;" 모든 데이터 다운로드 처리 response.setHeader("Content-Disposition", "attachment; filename="+filename);
//7. 데이터출력(다운로드) ServletOutputStream out2 = response.getOutputStream(); //7-1. 데이터출력 통로 생성 int data = 0; while((data = fis.read(b,0,b.length)) != -1){ //데이터출력시 파일이 있을동안 계속 진행 out2.write(b,0,data); //배열에다가 data를 담아서 출력 out2.flush(); } //8. 자원해제
out2.close(); fis.close();
//9. java.lang.IllegalStateException: //이 응답을 위해 getOutputStream()이 이미 호출되었습니다. // => JSP->Servlet 변환시 out 객체가 자동생성, 추가로 OutputStream 객체 생성시 // 오류 메세지 출력( 다운로드 문제 X, 서버에 에러 메세지 로그 쌓임)
out.clear(); out = pageContext.pushBody(); %>
5-1. java.lang.IllegalStateException에러
java.lang.IllegalStateException: 이 응답을 위해 getOutputStream()이 이미 호출되었습니다.
jsp가 실행될때 java파일로 변환되어 실행되고 그 바뀌는 걸 servlet이라고 한다. 이 변환시에 out이라는 객체가 자동 생성된다. 만약 추가로 OutputStream 객체생성시 IllegalStateException에러가 발생한다.
다운로드기능에는 문제가 없으나 에러가 실행될때마다 서버에 에러 메세지 로그 쌓이기때문에 처리해야한다.