사용자가 업로드한 파일을 저장하고, 화면에 출력하며, 다운로드 하는 방법을 배웠다.
1) 먼저 사용자가 파일을 업로드하는 페이지를 만든다. 파일 업로드를 하기 위해선 인코딩 타입을 변경해주는 enctype 속성을 multipart/form-data로 변경해주어야 한다. 기본값은 application/x-www-form-urlencoded으로 되어있다.
2) 그리고 사용자의 요청과 함께 보내온 파일을 처리하기 위한 Servlet을 만든다. 클래스 위에 @MultipartConfig 설정을 통해 파일의 크기를 지정하거나 전체 크기를 지정할 수 있다.
3) 사용자가 다중 파일을 보내오는걸 받기 위해 getParts 메소드를 사용해서(하나의 파일일 경우 getPart) Collection 객체의 변수에 저장하고 다 중 파일을 불러오기 위해 향상된 for문을 사용한다. 이때 위에서 만든 form 안에 name 속성이 id인 text 박스도 있기 때문에 if문을 통해 text 박스의 값은 반복되지 않도록 설정한다. getSubmittedFileName 메소드를 통해 파일 이름을 불러오고 사용자가 업로드한 파일의 데이터를 가지고 오기 위해(읽어오기 위해) InputStream을 생성한다. 그 파일을 저장한 경로를 설정하고 경로에 파일을 저장하기 위한 OutputStream 생성, InputStream으로 연결된 fis 변수에서 데이터를 read 메소드를 통해 읽어와 OutputStream에 그 데이터를 write 메소드를 통해 저장한다. 사용한 스트림은 close 메소드를 통해 닫아준다.
4) 위에서 설정한 저장 경로를 만들어준다. 그리고 사용자가 보낸 파일이 잘 전달되는지 확인해본다.
5) 이제 저장한 파일을 화면에 출력하기 위해 저장한 파일중 하나를 request에 올려주고 forwarding 해준다.
6) 요청과 함께 전달된 데이터를 받은 페이지에 EL을 통해 key값을 설정해 이미지를 불러오고, a태그의 download 속성으로 다운로드를 활성화한다.
7) 결과를 확인하면 이미지가 출력되고 다운로드도 가능한 것을 확인할 수 있다.
*단일 파일 코드
Part file = req.getPart("f");
// 사용자가 업로드한 파일 이름 알아오기
String originName = file.getSubmittedFileName();
// 사용자가 업로드한 파일에 input 스트림 연결
InputStream fis = file.getInputStream();
// 저장할 경로
String realPath = req.getServletContext().getRealPath("/upload");
// 파일 경로
String filePath = realPath + File.separator + originName;
// 파일 저장
FileOutputStream fos = new FileOutputStream(filePath);
byte[] buf = new byte[1024];
int size = 0;
while((size = fis.read(buf)) != -1) {
fos.write(buf, 0, size);
}
fis.close();
fos.close();