15장. JSP 페이지를 풍부하게 하는 오픈 소스 기능
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();
}