본문 바로가기

개발/Programming

[JSP/서블릿] 파일 업로드/ 다운로드 라이브러리

반응형

▣ 파일 업로드


게시글의 첨부파일, 프로필, 쇼핑몰 상품 이미지 등록 등 웹 환경에서 파일 업로드는  많은 곳에서 사용

Servlet 3.0 이전에는 전송된 File을 쉽게 처리할 수 있도록 지원해주는 API가 없음.

따라서 Servlet/Jsp 환경에서 파일업로드를 구현할 때는 파일 업로드와 관련된 라이브러리를 사용

 

* 라이브러리를 사전 설치 필요

http://jakarta.apache.org/ 접속 후 FileUploadcommons-io 라이브러리 설치
② 각 jar를 lib에 추가

 


⭐ 반드시 form 태그에 enctype="multipart/form-data" 설정

- 이 방식은 <form> 요소가 파일이나 이미지를 서버로 전송할 때 주로 사용

<form action="${contextPath}/upload.do" method="post" enctype="multipart/form-data">
</form>

HTML에서는 기본적으로 파일을 첨부할 수 있는 API를 제공

<INPUT> 태그의 type 속성값을 fille 로 지정 

또한 <FORM>태그의 method 속성이 post여야 함.


 

파일 업로드를 처리할 서블릿 작성


import ... //생략

@WebServlet("/upload.do")
public class FileUploadServlet extends HttpServlet {
	
    private static final long serialVersionUID = 1L;
    private static String FILE_REPO = "C:\\file_repos";
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
            
		
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html; charset=utf-8");
        
        String encoding = "utf-8";
        
        //업로드할 파일 경로 지정
        File currentDirPath = new File(FILE_REPO);
        
        DiskFileItemFactory facotry = new DiskFileItemFactory();
        factory.setRepository(currentDirPath); // 파일 경로 설정
        factory.setSizeThreshold(1024*1024); // 최대 업로드 가능한 파일 크기 설정
        ServletFileUpload fileUpload = new ServletFileUpload(Factory);
        List fileList = new ArrayList();
        try { 
        	
            List items = fileUpload.parseRequest(request); // request 객체에서 매개변수를 List로 가져옴
       		
            for(int i = 0; i < items.size(); i++) {
          	   FileItem fileItem = (FileItem) items.get(i)
                
                if (fileItem.isFormField()) {
                   System.out.println(fileItem.getFieldName() + "=" + fileItem.getString(encoding));
                } else { 
               	    System.out.println("매개변수이름: " + fileItem.getFieldName());
                    System.out.println("파일이름: " + fileItem.getName());
                    System.out.println("파일크기: " + fileItem.getSize() + "bytes");
                    
                    // 업로드한 파일 이름을 가져옴
                    if(fileItem.getSize() > 0) {
                    	int idx = fileItem.getName().lastIndexOf("\\"); 
                        if (idx == -1) {
                        idx = fileItem.getName().lastIndexOf("/");
                        }
                        String fileName = fileItem.getName().substring(idx+1);
                        fileList.add(fileName);
                        File uploadFile = new File(currentDirPath + "\\" + fileName);
                        fileItem.write(uploadFile);
                    } //end if
                    
                } // end if
            } // end for
        } catch (Exception e) {
        	e.printStackTrace();
        }
        
        request.setAttribute("fileList",fileList);
        RequestDispatcher dispatch = request.getRequestDispatcher("upload.jsp");
        dispatch.forward(request,response);
	}
}

 

파일 업로드 관련 API


① DiskFileItemFactory 클래스가 제공하는 메서드

 -DiskFileItemFactory는 업로드된 파일을 저장할 저장소와 관련된 클래스


setRepository( ) 

  • 파일을 저장할 디렉터리를 설정, 업로드 된 파일을 저장할 위치를 File 객체로 지정

setSizeThreshold()

  • 최대 업로드 가능한 파일 크기를 설정( byte 단위로 지정 )

≫ 예를 들어 이 값을 1024로 지정한 경우 1024byte 이상의 파일을 업로드 했을 때 메모리에 있던 파일의 바이너리 데이터를 저장소에 임시파일로 잠시 저장함.

이렇게 임시파일로 저장하는 이유는 대용량 파일을 업로드 했을 때 그만한 크기의 데이터를 웹어플리케이션이 동작하는 JVM 메모리상에 모두 로드하는 것은 부담이 되기 때문

임시파일로 저장되었던 파일은 이후에 FileItem. write( )와 delete( ) 메서드를 통해 실제 파일로 변경되거나 제거

 

 

② ServletFileUpload 클래스가 제공하는 메서드

- ServletFileUpload 클래스는 HTTP 요청에 대한 HttpServletRequest 객체로부터 multipart/form-data 형식으로 넘어온 HTTP Body 부분을 다루기 쉽게 변환(parse)해주는 역할을 수행 


parseRequest( )

  • 전송괸 매개변수를 List 객체로 얻음.
  • parseRequest() 메서드 수행시 FileItem이라는 형식으로 변환

getItemIterator( )

  • 전송된 매개변수를 Iterator 타입으로 얻음.

 

FileItem


사용자가 업로드한 File 데이터나 사용자가 input text에 입력한 일반 요청 데이터에 대한 객체

FileItem 메서드

isFormField() 메서드의 리턴값이 true이면 text 같은 일반 입력 데이터, false 이면 파일 데이터

 

파일 저장코드 


File.separator는 운영체제별로 다른 파일경로로 구분자를 갖고있음

  1. window 환경 디렉터리 구분 :  \  (\) , \\
  2. linux 계열 : /

따라서 업로드한 파일 경로의 마지막 separator 뒤에 오는 값이 실제 파일명

(ex: C:\\app\\test.txt 에서 test.txt가 실제 파일명)

크롬의 경우 POST로 파일 전송시 실제 파일명만 넘겨주는 반면 인터넷 익스플로러의 경우 사용자의 드라이버 경로,절대경로 전부를 리턴해주기 때문에 파일명을 추출할 때 이를 주의


 

파일 다운로드


파일 다운로드를 처리할 서블릿 작성

import .. //생략

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;chareset=utf-8");
        
        String file_repo = "C:\\file_repo";
        String fileName = (String)request.getParameter("fileName");
        System.out.println("fileName= " + fileName);
        
        // response에서 OutputStream 객체를 가져옴
        OutputStream out = response.getOutputStream();
        String downFile = file_repo + "\\" + fileName;
        File f = new File(downFile);
        
        response.setHeader("Cache-Control","no-cache");
        response.addHeader("Cache-disposition", "attachment; fileName="+fileName);
        
        FileInputStream in = new FileInputStream(f);
        
        //버퍼 기능을 이용해 파일에서 버퍼로 데이터를 읽어와 한꺼번에 출력
        byte[] buffer = new byte[1024*8]; //8kbyte씩 일음
        while(true) {
        	int count = in.read(buffer);
            if(count==-1)
            	break;
            out.write(buffer,0,count);
        }
        in.close();
        out.close();
        
	}

 

케시 제어를 위한 응답 헤더

response.setHeader("Cache-Control", "no-cache");

  • 데이터가 변경되었음에도 불구하고 웹 브라우저는 캐시에 저장된 데이터를 출력하기 때문에 변경된 내용으로 적용 안됨.
  • 게시판과 같이 내용이 자주 변경되는 사이트는 웹 브라우저 캐시가 적용되면 사용자는 변경된 내용을 확인할 수 없음
  • Cache-control 응답헤더 : HTTP 1.1 버전에서 지원하는 헤더. 값을 'no-cache'로 지정하면 캐시에 저장하지 않음

Content-Disposition

  • ContentDisposition은 HTTP Response Body에 오는 컨텐츠의 기질/성향을 알려주는 속성
Content-Disposition : attachment; filename="hello.jps"

이때 Body에 오는 filename을 다운로드 받으라는 뜻


FileInputStream 클래스

FileInputStream(File file) : 주어진 File 객체가 가리키는 파일을 바이트 스트림으로 읽기 위한 객체 생성

FileInputStream(String name) : 주어진 이름이 가리키는 파일을 바이트 스트림으로 읽기 위한 객체 생성

 

outputStream 클래스

outputStream 클래스의 주요 메서드

 

반응형

'개발 > Programming' 카테고리의 다른 글

한글 인코딩 UTF-8 설정  (0) 2021.09.17
Flow chart (순서도)  (0) 2021.09.15
제이쿼리(Jquery)  (0) 2021.07.21
[JSP] 표현언어와 JSTL  (0) 2021.07.14
[JSP] 액션 태그  (0) 2021.07.04