1. 개요
웹 애플리케이션의 일반적인 기능은 파일을 다운로드하는 기능입니다.
이 사용방법(예제)에서는 다운로드 가능한 파일을 만들고 Java Servlet 애플리케이션에서 제공하는 간단한 예제를 다룰 것 입니다.
우리가 사용하고 있는 파일은 webapp 리소스에서 가져온 것입니다.
2. 메이븐 의존성
Jakarta EE를 사용하는 경우 의존성을 추가할 필요가 없습니다. 그러나 Java SE를 사용하는 경우 javax.servlet-api 의존성이 필요합니다.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
의존성의 최신 버전은 여기 에서 찾을 수 있습니다 .
3. 서블릿
먼저 코드를 살펴보고 무슨 일이 일어나는지 알아봅시다.
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
private final int ARBITARY_SIZE = 1048;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain");
resp.setHeader("Content-disposition", "attachment; filename=sample.txt");
try(InputStream in = req.getServletContext().getResourceAsStream("/WEB-INF/sample.txt");
OutputStream out = resp.getOutputStream()) {
byte[] buffer = new byte[ARBITARY_SIZE];
int numBytesRead;
while ((numBytesRead = in.read(buffer)) > 0) {
out.write(buffer, 0, numBytesRead);
}
}
}
}
3.1. Endpoints 요청
@WebServlet("/download") 어노테이션은 DownloadServlet 클래스가 "/download" 엔드포인트 로 향하는 요청을 처리하도록 표시합니다.
또는 web.xml 파일에서 매핑을 설명하여 이를 수행할 수 있습니다.
3.2. 응답 콘텐츠 유형
HttpServletResponse 개체 에는 HTTP 응답의 Content-Type 헤더 를 설정하는 데 사용할 수 있는 setContentType 이라는 메서드 가 있습니다.
Content-Type 은 헤더 속성의 이전 이름입니다. 또 다른 이름은 MIME 유형(Multipurpose Internet Mail Extensions)입니다. 이제 간단히 미디어 유형으로 값을 참조합니다.
이 값은 "application/pdf", "text/plain", "text/html", "image/jpg" 등 이 될 수 있습니다. 공식 List은 IANA(Internet Assigned Numbers Authority)에서 관리하며 여기 에서 찾을 수 있습니다. .
이 예에서는 간단한 텍스트 파일을 사용하고 있습니다. 텍스트 파일 의 Content-Type 은 "text/plain"입니다.
3.3. 응답 내용-처리
응답 객체에 Content-Disposition 헤더를 설정하면 브라우저가 액세스하는 파일을 처리하는 방법을 알 수 있습니다.
브라우저는 Content-Disposition 의 사용을 관례로 이해하지만 실제로는 HTTP 표준의 일부가 아닙니다. W3에는 여기 에서 읽을 수 있는 Content-Disposition 사용에 대한 메모가 있습니다 .
Response body의 Content-Disposition 값은 "인라인"(렌더링할 웹 페이지 콘텐츠의 경우) 또는 "첨부 파일"(다운로드 가능한 파일의 경우) 입니다 .
지정하지 않으면 기본 Content-Disposition 은 "인라인"입니다.
선택적 헤더 매개변수를 사용하여 파일 이름 "sample.txt"를 지정할 수 있습니다.
일부 브라우저는 지정된 파일 이름을 사용하여 파일을 즉시 다운로드하고 다른 브라우저는 사전 정의된 값이 포함된 다운로드 대화 상자를 표시합니다.
수행되는 정확한 조치는 브라우저에 따라 다릅니다.
3.4. 파일에서 읽기 및 출력 스트림에 쓰기
나머지 코드 줄에서는 요청에서 ServletContext 를 가져오고 "/WEB-INF/sample.txt"에서 파일을 가져오는 데 사용합니다.
HttpServletResponse # getOutputStream() 을 사용 하여 리소스의 입력 스트림에서 읽고 응답의 OutputStream 에 씁니다 .
우리가 사용하는 바이트 배열의 크기는 임의적입니다. InputStream 에서 OutputStream 으로 데이터를 전달하기 위해 할당하기에 합당한 메모리 양에 따라 크기를 결정할 수 있습니다 . 숫자가 작을수록 더 많은 루프가 있습니다. 숫자가 클수록 메모리 사용량이 많습니다.
이 주기는 파일의 끝을 나타내는 numByteRead 가 0이 될 때까지 계속됩니다.
3.5. 닫기 및 플러시
현재 보유하고 있는 리소스를 해제하려면 사용 후 스트림 인스턴스를 닫아야 합니다. 버퍼링된 나머지 바이트를 대상에 쓰려면 작성기 인스턴스도 플러시해야 합니다.
try-with-resources 문을 사용 하여 응용 프로그램은 try 문의 일부로 정의된 AutoCloseable 인스턴스 를 자동 으로 닫습니다 . try-with-resources에 대한 자세한 내용은 여기를 참조하십시오 .
우리는 이 두 가지 방법을 사용하여 메모리를 해제하고 준비한 데이터가 애플리케이션에서 전송되도록 합니다.
3.6. 파일 다운로드
모든 것이 준비되었으므로 이제 서블릿을 실행할 준비가 되었습니다.
이제 상대 Endpoints "/download" 를 방문하면 브라우저에서 파일을 "simple.txt"로 다운로드하려고 시도합니다.
4. 결론
서블릿에서 파일을 다운로드하는 것은 간단한 프로세스가 됩니다. 스트림을 사용하면 데이터를 바이트로 전달할 수 있으며 미디어 유형은 예상되는 데이터 유형을 클라이언트 브라우저에 알립니다.
응답을 처리하는 방법을 결정하는 것은 브라우저에 달려 있지만 Content-Disposition 헤더에 대한 몇 가지 지침을 제공할 수 있습니다.
이 기사의 모든 코드는 GitHub 에서 찾을 수 있습니다 .