서블릿 3.0에는 InputStream이나 외부 라이브러리를 사용하지 않고 웹 브라우저가 업로드한 파일을 읽어올 수 있는 기능이 추가되었습니다.
HttpServletRequest의 getPart() 메서드를 이용해서 업로드 데이터에 접근합니다.
서블릿이 multipart 데이터를 처리할 수 있도록 설정합니다.
Part 인터페이스는 miltipart/form-data POST 요청으로 수신받은 from 아이템이나 하나의 Part를 나타냅니다.
@MultipartConfig 어노테이션을 사용하거나 web.xml에서 <multipart-config> 태그를 사용합니다.
어노테이션 사용방법
@MultipartConfig(
fileSizeThreshold = 1024*1024,
maxFileSize = 1024*1024*5,
maxRequestSize = 1024*1024*5*5
)
location 은 운영체제마다 절대 경로를 표현하는 것이 다르므로 기본의 자바 파일에 자동 임시 저장되도록 하는 것이 좋습니다.
web.xml 사용방법
<multipart-config>
<location>""</location>
<max-file-size>-1</max-file-siez>
<max-request-size></max-request-size>
<file-size-threshold>1024</file-size-threshold>
- loaction : 업로드한 파일이 임시로 저장될 위치를 지정합니다 절대경로만가능하며 기본값은 해당 자바가 실행되는 temp 폴더입니다.
- maxFileSize : 업로드 가능한 파일의 최대 크기를 바이트 단위로 지정합니다. -1은 제한이 없음을 의미하며 기본값입니다.
- maxRequestSize : 전체 Multipart 요청 데이터의 최대 제한 크기를 지정합니다. -1은 제한이 없음을 의 마하며 기본값입니다.
- fileSizeThreshold : 업로드한 파일의 크기가 태그 값보다 크면 loaction에 지정한 디렉터리에 임시로 파일을 복사합니다.
작다면 메모리에 파일을 저장합니다 기본값은 0 입니다.
먼저 Part를 이용해 업로드되는 데이터에 접근합니다.
multipart/form-data 형식으로 전송된 데이터는 request.getParameter()와 같은 메서드로 접근할 수 없으며 Part Interface를 사용해 접근해야 합니다.
HttpServletRequest.getContentType()을 이용하여 multipart/form-data인지 확인합니다.
getContentType()은 클라이언트가 요청 정보를 전송할 때 사용한 Content type을 구합니다.
리턴 타입은 String입니다.
1.HttpServletRequest의 getParts()나 getPart(name) 메서드를 이용해 Part를 구합니다
getParts()로 한 번에 받는 경우는 Collection을 이용해 받아야 합니다.
Collection<Part> parts = request.getParts();
2.Part의 Content-Disposition 헤더가 "filename="을 포함하면 파일로 구분 짓습니다.
보통 우리는 form안에 텍스트와 파일을 같이 입력받는 경우가 많습니다. 이러한 경우 텍스트와 파일을 구분할 수 있는 기능은 part.requestHeader("Content-Dispostion")입니다.
3. 파일 업로드를 위한 파일 경로 얻기
사용자가 파일을 업로드했는데 fileSizeThreshold에서 지정한 값보다 큰 경우 외부 디스크에 저장해야 합니다.
외부에 저장할 폴더의 절대 경로가 필요한데 서블릿 콘텍스트의 realPath() 메서드로 지정된 파일의 ROOT를 기준으로 절대 경로를 구할 수 있습니다.
String realPath =request.getServletContext().getRealPath("/upload");
System.out.println(realPath);
이클립스를 사용할 경우 톰캣과 유사한 임시 폴더에 저장되므로 실 서비스를 위한 톰캣을 사용하고 있는 경우에는 폴더는 이곳에 저장될 것입니다.
4. 만약 업로드할 파일을 복사할 폴더가 존재하지 않는 경우
File fileSaveDir = new File(realPath);
// 파일 경로 없으면 생성
if (!fileSaveDir.exists())
fileSaveDir.mkdirs();
이제 저장될 폴더를 생성했으므로 파일을 복사해야 합니다.
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
Collection<Part> parts = request.getParts();
String realPath =request.getServletContext().getRealPath("/uploads");
File fileSaveDir = new File(realPath);
// 파일 경로 없으면 생성
if (!fileSaveDir.exists())
fileSaveDir.mkdirs();
for (Part p : parts) {
System.out.println(p.getName());
if(p.getHeader("Content-Disposition").contains("filename=")) {
if(p.getSize()>0) {
String fileName = p.getSubmittedFileName();
String filePath = realPath + File.separator + fileName;
p.write(filePath);
}
}
}
part가 파일일 경우 저장 폴더에 읽어 들인 파일을 복사합니다.
'SSR > Servlet & JSP' 카테고리의 다른 글
서블릿 예외 페이지 (0) | 2022.01.13 |
---|---|
Filter (0) | 2020.05.24 |
DBCP를 이용해서 커넥션 풀 사용하기 (0) | 2020.05.20 |
JSP SCOPE (0) | 2020.05.13 |
HttpServletRequest/Response (0) | 2020.05.09 |
댓글