복붙노트

[SPRING] 혼합 된 다중 요청을 사용하는 @RequestPart, Spring MVC 3.2

SPRING

혼합 된 다중 요청을 사용하는 @RequestPart, Spring MVC 3.2

나는 Spring 3.2에 기반한 RESTful 서비스를 개발 중이다. 두 번째 부분에 XMLor JSON 형식의 데이터가 있고 두 번째 부분에 이미지 파일이있는 다중 부분 HTTP 요청을 처리하는 컨트롤러에 문제가 있습니다.

요청을 수신하기 위해 @RequestPart 주석을 사용하고 있습니다.

@RequestMapping(value = "/User/Image", method = RequestMethod.POST,  consumes = {"multipart/mixed"},produces="applcation/json")

public
ResponseEntity<List<Map<String, String>>> createUser(
        @RequestPart("file") MultipartFile file, @RequestPart(required=false) User user) {

    System.out.println("file" + file);

    System.out.println("user " + user);

    System.out.println("received file with original filename: "
            + file.getOriginalFilename());

    // List<MultipartFile> files = uploadForm.getFiles();
    List<Map<String, String>> response = new ArrayList<Map<String, String>>();
    Map<String, String> responseMap = new HashMap<String, String>();

    List<String> fileNames = new ArrayList<String>();

    if (null != file) {
        // for (MultipartFile multipartFile : files) {

        String fileName = file.getOriginalFilename();
        fileNames.add(fileName);

        try {
            file.transferTo(new File("C:/" + file.getOriginalFilename()));
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    responseMap.put("displayText", file.getOriginalFilename());
    responseMap.put("fileSize", "" + file.getSize());
    response.add(responseMap);

    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.add("Accept", "application/json");
    return new ResponseEntity<List<Map<String, String>>>(response,
            httpHeaders, HttpStatus.OK);

}

User.java는 다음과 같이 될 것입니다.

@XmlRootElement(name = "User")


public class User implements Serializable { 
    private static final long serialVersionUID = 1L;

    private int userId;
    private String name;
    private String email;

    private String company;
    private String gender;

    //getter setter of the data members
}

내 이해하기 위해 @RequestPart 주석을 사용하여 XML multipart 섹션이 Content-Type에 따라 평가되고 마침내 내 User 클래스에 마샬링되지 않을 것으로 기대합니다. (Jaxb2를 사용하고 있습니다. marshaller / unmarhaller가 제대로 구성되어 있습니다. 응용 프로그램 컨텍스트와 절차는 XML 데이터를 본문으로 전달하고 @RequestBody 주석을 사용할 때 다른 모든 컨트롤러 메서드에 대해 잘 작동합니다.

그러나 실제로 일어나고있는 것은 파일이 올바르게 발견되어 MultipartFile로 구문 분석되지만 "사용자"부분은 절대로 보이지 않고 요청이 항상 실패하고 컨트롤러 메소드 서명과 일치하지 않는다는 것입니다.

여러 클라이언트 유형으로 문제를 재현했고 멀티 파트 요청의 형식이 양호하다는 확신이 들었습니다.

이 문제를 해결하는 데 도움을주십시오. 어쩌면 혼합 / 다중 요청을받을 수있는 몇 가지 해결 방법이있을 것입니다.

감사합니다.

Raghavendra

해결법

  1. ==============================

    1.문제를 해결했는지 확신 할 수 없지만 @RequestPart와 MultipartFile을 함께 섞을 때 내 JSON 객체가 컨트롤러에서 선택되지 않는 비슷한 문제가있었습니다.

    문제를 해결했는지 확신 할 수 없지만 @RequestPart와 MultipartFile을 함께 섞을 때 내 JSON 객체가 컨트롤러에서 선택되지 않는 비슷한 문제가있었습니다.

    통화에 대한 메소드 서명이 올바른 것 같습니다.

    public ResponseEntity<List<Map<String, String>>> createUser(
            @RequestPart("file") MultipartFile file, @RequestPart(required=false) User user) {
    
    // ... CODE ... 
    }
    

    그러나 요청이 다음과 같이 표시되는지 확인하십시오.

    POST /createUser
    Content-Type: multipart/mixed; boundary=B0EC8D07-EBF1-4EA7-966C-E492A9F2C36E
    
    --B0EC8D07-EBF1-4EA7-966C-E492A9F2C36E
    Content-Disposition: form-data; name="user";
    Content-Type: application/xml; charset=UTF-8
    
    <user><!-- your user xml --></user>
    --B0EC8D07-EBF1-4EA7-966C-E492A9F2C36E
    Content-Disposition: form-data; name="file"; filename="A551A700-46D4-470A-86E7-52AD2B445847.dat"
    Content-Type: application/octet-stream
    
    /// FILE DATA
    --B0EC8D07-EBF1-4EA7-966C-E492A9F2C36E--
    
  2. ==============================

    2.나는 문제를 해결할 수 있었다.

    나는 문제를 해결할 수 있었다.

    엔드 포인트 예 :

    @PostMapping("/")
    public Document create(@RequestPart Document document,
                           @RequestPart(required = false) MultipartFile file) {
        log.debug("#create: document({}), file({})", delegation, file);
        //custom logic
        return document;
    }
    

    예외:

    "error_message": "Content type 'application/octet-stream' not supported"
    

    예외는 다음 메소드에서 발생합니다.

    org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(HttpInputMessage,MethodParameter,Type)
    

    해결책:

    HttpMessageConverter 또는 HttpMessageConverter를 구현하고 MediaType.APPLICATION_OCTET_STREAM에 대해 알고있는 사용자 지정 변환기 @Component를 만들어야합니다. 간단한 해결 방법으로 AbstractJackson2HttpMessageConverter를 확장하면 충분합니다.

    @Component
    public class MultipartJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {
    
    /**
     * Converter for support http request with header Content-Type: multipart/form-data
     */
    public MultipartJackson2HttpMessageConverter(ObjectMapper objectMapper) {
        super(objectMapper, MediaType.APPLICATION_OCTET_STREAM);
    }
    }
    
  3. ==============================

    3.너 해봤 어?

    너 해봤 어?

    ResponseEntity<List<Map<String, String>>> createUser(
            @RequestPart("file") MultipartFile file, @RequestBody(required=false) User user) {
    

    또는

    ResponseEntity<List<Map<String, String>>> createUser(
            @RequestPart("file") MultipartFile file, @RequestParam(required=false) User user) {
    

    이것이 작동하지 않으면 우리에게 mapping.xml을 보여줄 수 있습니까?

  4. from https://stackoverflow.com/questions/16230291/requestpart-with-mixed-multipart-request-spring-mvc-3-2 by cc-by-sa and MIT license