코드 그라데이션

서블릿과 파일 업로드 (2) 본문

Java, SpringBoot 추가 공부/파일 업로드

서블릿과 파일 업로드 (2)

완벽한 장면 2023. 11. 22. 16:05

서블릿과 파일 업로드2
서블릿이 제공하는 Part 에 대해 알아보고 실제 파일도 서버에 업로드 해보자.

 

1. 먼저 파일을 업로드를 하려면 실제 파일이 저장되는 경로가 필요하다.

- 해당 경로에 실제 폴더를 만들어두자.
- 그리고 다음에 만들어진 경로를 입력해두자.

 

나의 저장 경로

C:\Inflearn_Spring\file

 

application.properties 에 파일 업로드 경로 설정

예시

 

내 application.properties

file.dir=C:/Inflearn_Spring/file

 

주의

cf. 2번의 경우 요즘은 굳이 안 넣어도 되나봄. 

특히 windows는 \\ 로 구분을 했으나, 요즘에는 / 로 써도 스프링이 전부 호환해줌.

 

 


ServletUploadControllerV2

@Slf4j
@Controller 
@RequestMapping("/servlet/v2") // 이 컨트롤러의 모든 요청은 "/servlet/v2" 경로에서 처리
public class ServletUploadControllerV2 {

    @Value("${file.dir}") // 스프링 프로퍼티 값을 주입받기 위한 어노테이션
    private String fileDir; // "file.dir" 프로퍼티 값을 저장할 변수


    @GetMapping("/upload") // HTTP GET 요청을 처리하는 메서드
    public String newFile() {
        return "upload-form"; // "upload-form"이라는 뷰 이름을 반환하여 해당 뷰를 표시
    }



    @PostMapping("/upload") // HTTP POST 요청을 처리하는 메서드
    public String saveFileV1(HttpServletRequest request) throws ServletException, IOException {
        log.info("request={}", request); // 로그에 HTTP 요청 정보를 출력

        String itemName = request.getParameter("itemName"); // HTTP 요청에서 "itemName" 매개변수 값을 가져옴
        log.info("itemName={}", itemName); // "itemName" 값을 로그에 출력

        Collection<Part> parts = request.getParts(); // HTTP 요청의 모든 파트(파일 업로드 항목)을 가져옴
        log.info("parts={}", parts); // 파트 목록을 로그에 출력

        for (Part part : parts) { // 파트 목록을 반복
            log.info("==== PART ====");
            log.info("name={}", part.getName()); // 파트의 이름을 로그에 출력

            Collection<String> headerNames = part.getHeaderNames(); // 파트의 헤더 이름 목록을 가져옴

            for (String headerName : headerNames) { // 헤더 이름 목록을 반복
                log.info("header {}: {}", headerName, part.getHeader(headerName)); // 헤더 정보를 로그에 출력
            }

            // content-disposition; filename 헤더를 통해 업로드된 파일 이름을 가져옴
            // part.getSubmittedFileName() : 클라이언트가 전달한 파일명
            log.info("submittedFileName={}", part.getSubmittedFileName());

            // 파트의 바디(body) 크기를 출력
            log.info("size={}", part.getSize());

            // 파트의 입력 스트림을 가져와서 UTF-8 인코딩으로 문자열로 변환
            // part.getInputStream(); : Part의 전송 데이터를 읽음.
            InputStream inputStream = part.getInputStream();
            String body = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
            log.info("body={}", body);

            // 만약 업로드된 파일 이름이 있는 경우, 파일을 지정된 경로에 저장
            if (StringUtils.hasText(part.getSubmittedFileName())) {
                String fullPath = fileDir + part.getSubmittedFileName();
                log.info("파일 저장 fullPath={}", fullPath);
                part.write(fullPath); // Part를 통해 전송된 데이터를 저장할 수 있게 만듦
            }
        }
        return "upload-form";
    }
}

 

 

Part 주요 메서드

part.getSubmittedFileName() : 클라이언트가 전달한 파일명

part.getInputStream() : Part의 전송 데이터를 읽을 수 있다.

part.write(...) : Part를 통해 전송된 데이터를 저장할 수 있다.

 

실행

http://localhost:8080/servlet/v2/upload

 

찍힌 로그를 보면

2023-09-29 18:05:37.496  INFO 8268 --- [nio-8080-exec-2] i.u.c.ServletUploadControllerV2          : 파일 저장 fullPath=C:/Inflearn_Spring/file/btn_google.png

 

파일이 해당 폴더에 들어와 있음을 확인할 수 있음.

 

 

서블릿이 제공하는 Part 는 편하기는 하지만, HttpServletRequest 를 사용해야 하고, 

추가로 파일 부분만 구분하려면 여러가지 코드를 넣어야 한다. 

 

이제, 스프링이 이 부분을 얼마나 편리하게 제공하는지 확인할 차례다.

728x90
Comments