본문 바로가기
SSR/Servlet & JSP

서블릿 3.0 파일 업로드

by oncerun 2020. 5. 30.
반응형

서블릿 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

댓글