웹페이지에서 전송 받음.
commons-fileupload2-jakarta
일반적인 양식 전송 형태 content-type: application/w-www-form-urlencoded;
-텍스트 형태의 양식 데이터 종류
이름=값&이름=값&file=1.png
문제 -> 파일 데이터는 바이트 데이터형식 / 일반 양식 형식과는 다름
-파트를 나눠서
일부 파트는 양식 데이터
일부 파트는 파일 데이터
-> 멀티 파트 (multipart)
멀티 파트 형태로 전송하려면?
form 태그의 속성 중 enctype="multipart/form-data"
JakartaServletDiskFileUpload
DiskFileItem
D:/uploads/1.png : 브라우저에서 접근 불가
-> 서블릿 쪽에서 파일을 읽어와서 body에 출력 / 형식을 정확하게 알려줘야 제대로 출력
웹 경로 /upload/1.png
package org.choongang.file.controllers;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@WebServlet("/upload/*")
public class FileSearchController extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String uri = req.getRequestURI().replace(req.getContextPath(), ""); // 현재 접속 주소
// /upload/파일경로
Pattern pattern = Pattern.compile("^/upload/(.+)");
Matcher matcher = pattern.matcher(uri);
if (matcher.find()) {
String fileName = matcher.group(1);
System.out.println(fileName);
File file = new File("D:/uploads/"+fileName);
if (file.exists()) {
Path source = file.toPath();
String contentType = Files.probeContentType(source);
resp.setContentType(contentType);
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
OutputStream out = resp.getOutputStream();
out.write(bis.readAllBytes());
}
return;
}
}
// 파일이 없는 경우 - 404 응답 코드
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
-출력 방향을 브라우저 화면 X, 지정된 파일로 변경 -> 다운로드
응답 헤더
Content-Disposition: attachment; filename=파일명
-캐싱이 되면 기존 파일 내용이 변경 X -> 캐싱 사용 X
Cache-Control: must-revalidate - 캐시 갱신(new)
Pragma: public - 캐시 갱신(old)
오랜시간 다운로드 하면? 브라우저가 연결 종료(Time out)
-> 정상적인 다운로드가 불가
Expires: 0 -> 만료시간 없음
파일 전체 용량?
Content-Length
파일 형식
Content-Type
package org.choongang.file.controllers;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@WebServlet("/file/download")
public class FileDownloadController extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
File file = new File("D:/uploads/1.png");
String contentType = Files.probeContentType(file.toPath());
String fileName = new String(file.getName().getBytes(StandardCharsets.UTF_8), "ISO8859_1"); // 윈도우즈 한글 깨짐문제 발생, 인코딩 UTF-8 -> CPC949, EUC-KR, ISO8859_1
resp.setHeader("content-Disposition", "attachment; filename=" + fileName);
resp.setContentType(contentType);
resp.setHeader("Cache-Control", "must-revalidate");
resp.setIntHeader("Expires", 0);
resp.setContentLengthLong(file.length());
try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
OutputStream out = resp.getOutputStream();
out.write(bis.readAllBytes());
}
}
}