Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

javax.servelet.http.Part field cannot be resolved with StandardMultipartHttpServletRequest. #27819

Closed
binchoo opened this issue Dec 15, 2021 · 1 comment
Labels
status: superseded An issue that has been superseded by another

Comments

@binchoo
Copy link
Contributor

binchoo commented Dec 15, 2021

Affects: 5.3.2
Related issue: #15220

Hello, I'm trying to upload a file via multipart/form-data request. The handler method requires one object parameter, which contains a field of type javax.servelet.http.Part. As MultipartFile typed field can be resolved with parts, I've expected the same from Part.

  @Setter
  @Getter
  @AllArgsConstructor
  @NoArgsConstructor
  public class UserHavingPartVO {
      private String name;
      private int age; 
      private Part file;
  }

  @Controller
  public class FileUploadController {

      @PostMapping("/vopart")
      public ResponseEntity bindVOHavingPart(UserHavingPartVO userVo){
          if (userVo.getFile() == null)
              return ResponseEntity.noContent().build();
          return ResponseEntity.ok().build();
      }
  }

As described in senario 7 (from related issue #15220),
Part field could not be bind with values, as StandardMultipartHttpServletRequest wraps Part into private class StandardMultipartHttpServletRequest.StandardMultipartFile.
In turn, conversion from StandardMultipartFile to Part had occured but failed.

Test and generated logs are below. I hope available approaches are found for this scenario.

@SpringJUnitWebConfig(classes = {WebConfig.class})
public class FileUploadControllerTests {

    MockMvc mvc;

    FileUploadController controller = new FileUploadController();

    MockPart mockPart = new MockPart("file", "filename.png", "file".getBytes());

    @BeforeEach
    public void setup() {
        this.mvc = MockMvcBuilders.standaloneSetup(controller).build();
    }

    @DisplayName("params + Part -> VO Having Part : 400 Error")
    @Test
    void bindVOHavingPart() throws Exception {
        MultipartHttpServletRequest request = (MultipartHttpServletRequest)
                mvc.perform(multipart("/vopart")
                        .part(mockPart)
                        .param("name", "jaebin-joo")
                        .param("age", "11"))
                    .andExpect(status().is4xxClientError()) // StandardMultipartFile 타입을 Part로 변환할 수 없기 때문에
                    .andReturn().getRequest();

        assertThat(request.getParts().size()).isEqualTo(1);
        assertThat(request.getMultiFileMap().size()).isEqualTo(0);
    }
}
main] DEBUG org.springframework.web.method.HandlerMethod - Could not resolve parameter [0] in public org.springframework.http.ResponseEntity org.binchoo.study.spring.multipart.profileservice.controller.FileUploadControllerTests$FileUploadController.bindVOHavingPart(org.binchoo.study.spring.multipart.profileservice.controller.FileUploadControllerTests$UserHavingPartVO): org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'userHavingPartVO' on field 'file': rejected value [org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@4e974b9e]; codes [typeMismatch.userHavingPartVO.file,typeMismatch.file,typeMismatch.javax.servlet.http.Part,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userHavingPartVO.file,file]; arguments []; default message [file]]; default message [Failed to convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'javax.servlet.http.Part'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'javax.servlet.http.Part': no matching editors or conversion strategy found]
@binchoo
Copy link
Contributor Author

binchoo commented Dec 19, 2021

PR: #27830 replaces this issue.

@binchoo binchoo closed this as completed Dec 19, 2021
@snicoll snicoll added status: superseded An issue that has been superseded by another and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Dec 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: superseded An issue that has been superseded by another
Projects
None yet
Development

No branches or pull requests

3 participants