[스프링MVC] javax.servlet.http.Part가 파일을 받지 못할 때

웹 개발/스프링 프레임워크

2021. 12. 15.

Part 인자 바인딩이 안 먹는 경우

스프링 5.3.2 버전 이상을 권장합니다.

 

이 버전에서 Part 바인딩 관련 이슈가 해결되었음:

 

MockPart in request is not recieved in RequestPart in controller · Issue #26501 · spring-projects/spring-framework

Affects version: 5.3.3 Related to: #26261 I have a controller method that accepts multipart/form-data requests with 2 parameters: a file and a @RequestPart String label. Previously in my tests I wa...

github.com

이제 이런식의 바인딩이 잘 동작한다.

@PostMapping("/part/argbinding")
public ResponseEntity doBind(@RequestPart(value = "file") Part file){
    return ResponseEntity.ok().build();
}

Part 속성 바인딩이 안 먹는 경우

@Data
class PartForm {
    private Part file; // Nope...
    private String name;
    private String birthdate;
}

@PostMapping("/part/attrbinding")
public ResponseEntity doBind(PartForm form){
    return ResponseEntity.ok().build();
}

스프링 컨트리뷰터 Rossen Stoyanchev 님의 설명에 따르면, Part 타입 속성 바인딩은 멀티파트 리졸버가 없는 경우에 동작합니다. 그 분께서 주신 코멘트를 보고 저는 DispatcherServlet::checkMultipartServletRequestDataBinder::bind를 검토하여 이 내용이 사실임을 확인했습니다.

 

두 코드를 추적해 보는 과정은 Part 타입 속성에 Part를 바인딩 할 수 없는 이유에 정리했습니다.

 

[SpringMVC] `Part` 타입 속성에 `Part`를 바인딩 할 수 없는 이유 · Issue #12 · caffeine-library/random

용어 구분 인자 바인딩: HTTP 요청의 데이터를, 콘트롤러 메서드의 인자로 주입하는 것 (책임: 아규먼트 리졸버) 속성 바인딩: HTTP 요청의 데이터를, 콘트롤러 메서드의 포조 인자의 속성으로 주입

github.com

 

다만, 이런 스펙에 관해 스프링이 문서와 테스트 코드를 충분히 갖추지 못했으며, 똑같은 고생을 하실 분들이 추후 나오게 될 것이라 판단했습니다. 그래서 Rossen Stoyanchev님은 자바독을 강화하셨고, 저는 몇 가지 테스트 메서드를 추가하는 것으로 이슈가 마무리 되었습니다.

 

GitHub - spring-projects/spring-framework: Spring Framework

Spring Framework. Contribute to spring-projects/spring-framework development by creating an account on GitHub.

github.com

이슈 요약

여러분이 이 이슈로부터 가져가실 내용은 아래 두 가지입니다.

서블릿 요청이 MultipartResolver를 통해 MultipartRequest가 되었다면, 이 요청이 보유한 멀티파트 파일은 (애초에 Part 타입입니다)

  • Part 타입 인자에 바인딩 가능하다.
  • Part 타입 속성에 바인딩이 불가하다. 하지만 MultipartFile 타입 속성에 바인딩 가능하다.

spring.servlet.multipart.enabled=false 를 설정해 MultipartResolver를 사용하지 않음으로써 서블릿 리퀘스트가 보유한 멀티파트 파일은 (애초에 Part 타입입니다)

  • Part 타입 인자에 바인딩 가능하다.
  • Part 타입 속성에 바인딩이 가능하다. 하지만 MultipartFile 타입 속성에 바인딩 불가하다.

 

이를 검증하는 테스트 코드는 아래를 참고합니다.

MultipartResolver 존재여부에 따른 Part 바인딩 행동 검증

 

GitHub - caffeine-library/random: 스터디 진행 외에 공유하고 싶은 주제에 대해 얘기합니다

스터디 진행 외에 공유하고 싶은 주제에 대해 얘기합니다. Contribute to caffeine-library/random development by creating an account on GitHub.

github.com