BackEnd/JSP

15장. JSP 페이지를 풍부하게 하는 오픈 소스 기능

제이드Jade 2022. 2. 23. 18:25

15.1 JSP에서 파일 업로드

- JSP는 대부분의 기능을 오픈 소스로 제공(파일 업로드/다운로드, 이메일 등)

 

<파일 업로드 구현하기 위한 절차>

  1) 파일 업로드 라이브러리&commons-io-2.6.jar 파일 설치 

  2) enctype="multipart/form-data"로 지정 & input type이 file인 태그를 포함한 요청 jsp파일 작성

  3) 업로드 기능 수행하는 서블릿 작성

 

<파일 업로드 관련 API>

- 파일 업로드 라이브러리에서  DiskFileItemFactory 클래스 ServletFileUpload 클래스 가 있다.

 

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

메서드  기능 
setRepository()  파일을 저장할 디렉터리 설정 
setSizeThreadhold()  최대 업로드 가능한 파일 크기를 설정 

 

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

메서드  기능 
parseRequest()  전송된 매개변수(param)를 List 객체로 얻음 
getItemIterator()  전송된 매개변수를 Iterator 타입으로 얻음

 

 

1-1) 파일 업로드 라이브러리 설치

jakarta.apache.ort로 접속 > Commons > FileUpload > FileUpload 1.3.3 의 here

> 디렉터리 구조에서 binaries/ 선택 > commons-fileupload-1.3.3-bin.zip 클릭 해 다운로드

> 압축 풀고 commons-fileupload-1.3.3.jar 파일 복사 후 WEB-INF/lib폴더에 붙여넣기

 

1-2)  commons-io-2.6.jar 파일 설치

 https://commons.apache.org/proper/commons-io/download_io.cgi 로 접속

> commons-fileupload-2.6.jar 클릭

> 압축풀고 commons-fileupload-2.6.jar 파일을 복사 후 WEB-INF/lib 폴더에 붙여 넣기

 

2) enctype="multipart/form-data"로 지정 & input type이 file인 태그를 포함한 요청 jsp파일 작성

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="contextPath" value="${pageContext.request.contextPath }"/>
...
<form action="${contextPath }/upload.do" method="post" encType="multipart/form-data"> //encType 반드시 확인
  파일1: <input type="file" name="file1"><br> //inputType이 file
  <%--파일 선택 버튼이 나타나고, 선택 후에는 파일 이름이 옆에 표시됨 --%>
  파일2: <input type="file" name="file2" > <br>
  파라미터1: <input type="text" name="param1" > <br> 
  파라미터2: <input type="text" name="param2" > <br>
  파라미터3: <input type="text" name="param3" > <br>
  <input type="submit" value="업로드" >
</form>

 

 

 3) 업로드 기능 수행하는 서블릿 작성

 

-FileUpload.java

protected void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
request.setCharacterEncoding("utf-8");

String encoding="utf-8";

File currentDirPath =new File("C:\\file_repo"); //파일 업로드 될 위치(폴더 생성 필요)

DiskFileItemFactory factory=new DiskFileItemFactory(); //라이브러리에서 제공하는 클래스1
factory.setRepository(currentDirPath); //파일 업로드 위치 설정
factory.setSizeThreshold(1024*1024); //업로드 가능한 파일 최대 크기 설정

ServletFileUpload upload =new ServletFileUpload(factory); //라이브러리에서 제공하는 클래스2
try {
    List items=upload.parseRequest(request); //요청 매개변수를 리스트로 파싱
    for(int i=0;i<items.size();i++) {
        FileItem fileItem=(FileItem)items.get(i);

        if(fileItem.isFormField()) { //매개변수가 폼필드(text,,)이면 매개변수이름=값(encoding해서 가져옴)을 출력
            System.out.println(fileItem.getFieldName() + "=" + fileItem.getString(encoding));
        }else { //폼 필드가 아니면(file) 파일 업로드 기능 수행
            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); // \\나 / 뒤에 있는 파일 이름을 가져옴
                File uploadFile = new File(currentDirPath + "\\" + fileName); // 저장소위치\\파일이름이 경로임
                fileItem.write(uploadFile); //저장소에 파일 업로드
            }
        }
    }

}catch (Exception e) {
    e.printStackTrace();
}
	}

>>C://file_repo에 파일이 있는 것을 확인할 수 있음

 

 

* 참고) FileItem 클래스

FileItem 인터페이스는 multipart/form-data 형식으로 전송된 폼 데이터를 파일 또는 폼 아이템으로 표현하는 객체

* FileItem 인터페이스 메서드
1) getFieldName() : 필드 이름 반환, name 속성의 값을 반환
2) getName() : 클라이언트에 저장되어 있던 파일의 이름을 반환(경로/파일명)
3) getSize() : 파일의 사이즈 반환
4) getString(String encoding) : 지정한 인코딩으로 파일 아이템 내용을 반환
5) isFormField() : 일반 파라미터인지 여부
6) write(file) : 업로드 된 파일을 디스크에 저장

출처 : https://blog.daum.net/question0921/654

 

 

15.2 JSP에서 파일 다운로드

1) first.jsp - hidden으로 사진이름을 설정, result.jsp로 보냄

2) result.jsp - 이미지 보여주기, 이미지 다운로드 링크 (~/download.do?fileName=${}로 이미지를 불러옴)

3) download.do 서블릿 - 자바IO를 이용해서 다운로드 기능 구현(inputStream으로 버퍼에 데이터를 넣고, outputStream으로 브라우저에 출력)

 

-first.jsp

<form method="post" action="result.jsp">
<input type=hidden name="param1" value="duke.png"/><br>
<input type=hidden name="param2" value="duke2.jpg"/><br>
<input type="submit" value="이미지 다운로드">

 

-result.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="contextPath" value="${pageContext.request.contextPath }"/>
...
<c:set var="file1" value="${param.param1 }"/>
<c:set var="file2" value="${param.param2 }"/>
..
<body>
매개변수1 : <c:out value="${file1 }"/><br>
매개변수2 : <c:out value="${file2 }" /><br>
<img src="${contextPath }/download.do?fileName=${file1 }" width=300 height=300/><br>
<a href="${contextPath }/download.do?fileName=${file1 }">파일 내려 받기</a><br><br>

<img src="${contextPath }/download.do?fileName=${file2 }" width=300 height=300/><br>
<a href="${contextPath }/download.do?fileName=${file2 }">파일 내려 받기</a><br><br>
<!--이미지 경로(서블릿요청)를 소스파일 이름으로 설정하면 화면에 나타내는거고, 링크로 접속하면 다운받아 지는 것 -->
</body>

 

-download.do

protected void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
    request.setCharacterEncoding("utf-8");
    response.setContentType("text/html; charset=utf-8");

    //파일경로 만들기
    File DirPath =new File("C:\\file_repo");
    String fileName=(String)request.getParameter("fileName");
    String downFile=DirPath+"\\"+fileName;
    File f=new File(downFile);

    //헤더설정
    response.setHeader("Cache-Control", "no-cache");
    response.addHeader("Content-disposition", "attachment;fileName="+fileName);

    //인풋스트림을 통해 파일을 버퍼에 저장
        //아웃풋 스트림을 통해서 버퍼에 있는걸 브라우저로 출력
    FileInputStream in=new FileInputStream(f);
    OutputStream out=response.getOutputStream();
    byte[] buffer=new byte[1024*8]; //8kb

    while(true) {
        int count=in.read(buffer); //buffer크기만큼 inputStream으로 부터 읽어와서 버퍼(바이트배열)에 저장
                                    // 읽어드린 길이를 반환
        if(count==-1)
            break;
        out.write(buffer,0,count); //아까 버퍼로 넣은 만큼 다시 버퍼에서 꺼내 브라우저에 출력
    }

    in.close();
    out.close();
}