JSP -12

김정현·2024년 6월 21일
0

JSP

목록 보기
13/13

파일 업로드

웹페이지에서 전송 받음.

  • 의존성 추가

commons-fileupload2-jakarta

  • multipart

일반적인 양식 전송 형태 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());
        }
    }
}

0개의 댓글