복붙노트

[SPRING] Spring restful service에서 파일과 JSON 객체로 구성된 다중 요청을 처리하는 방법은 무엇입니까?

SPRING

Spring restful service에서 파일과 JSON 객체로 구성된 다중 요청을 처리하는 방법은 무엇입니까?

파일과 JSON 객체를 받아들이는 다음 리소스 (Spring 4.05.RELEASE를 사용하여 구현 됨)가 있습니다.

(P.S. activityTemplate은 직렬화 가능한 엔티티 클래스이다)

...
@RequestMapping(value="/create", method=RequestMethod.POST)
public @ResponseBody ActivityTemplate createActivityTemplate(
        @RequestPart ActivityTemplate activityTemplate, @RequestPart MultipartFile jarFile)
{
   //process the file and JSON
}
...

이것이 내가 시험 할 양식입니다.

<form method="POST" enctype="multipart/form-data"
    action="http://localhost:8080/activityTemplates/create">
    JSON: <input type="text" name="activityTemplate" value='/* the JSON object*/'><br />

    File to upload: <input type="file" name="file">
    <input type="submit" value="Upload">
</form>

이것은 내가 얻는 오류입니다.

 There was an unexpected error (type=Unsupported Media Type, status=415).
 Content type 'application/octet-stream' not supported

그렇다면 리소스가 다중 요청의 일부로 JSON 객체를 받아 들일 수 있도록해야합니까? 아니면 양식을 다른 방식으로 보내야합니까?

해결법

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

    1.이것은 나를 위해 일하기 위해 2 일이 걸렸다!

    이것은 나를 위해 일하기 위해 2 일이 걸렸다!

    클라이언트 (각) :

    $scope.saveForm = function () {
          var formData = new FormData();
          var file = $scope.myFile;
          var json = $scope.myJson;
          formData.append("file", file);
          formData.append("ad",JSON.stringify(json));//important: convert to string JSON!
          var req = {
            url: '/upload',
            method: 'POST',
            headers: {'Content-Type': undefined},
            data: formData,
            transformRequest: function (data, headersGetterFunction) {
              return data;
            }
          };
    

    봄 (시동) :

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
        public @ResponseBody
        Advertisement storeAd(@RequestPart("ad") String adString, @RequestPart("file") MultipartFile file) throws IOException {
    
            Advertisement jsonAd = new ObjectMapper().readValue(adString, Advertisement.class);
    //do whatever you want with your file and jsonAd
    
  2. ==============================

    2.희망이 당신을 도울 것입니다. HTTP 요청을 알리기 위해 요청에서 경계를 설정해야합니다.  간단하다; 멀티 파트 형식에 대한 간략한 소개는 아래 링크에서 찾을 수 있습니다.

    희망이 당신을 도울 것입니다. HTTP 요청을 알리기 위해 요청에서 경계를 설정해야합니다.  간단하다; 멀티 파트 형식에 대한 간략한 소개는 아래 링크에서 찾을 수 있습니다.

    멀티 파트에 대한 HTML 4.01 사양

    다음 예제에서는 "multipart / form-data"인코딩을 보여줍니다. Json 객체가 "MyJsonObj"이고 보낼 필요가있는 파일이 "myfile.txt"이면 사용 도구는 다음 데이터를 다시 전송할 수 있습니다.

    Content-Type: multipart/form-data; boundary=MyBoundary
    
    --MyBoundary
    Content-Disposition: form-data; name="myJsonString"
    Content-Type: application/json
    
    MyJsonObj //Your Json Object goes here
    --MyBoundary
    Content-Disposition: form-data; name="files"; filename="myfile.txt"
    Content-Type: text/plain
    
    ... contents of myfile.txt ...
    --MyBoundary--
    

    또는 파일 이름이 "image.gif"인 이미지 유형 인 경우,

    --MyBoundary
    Content-Disposition: file; filename="image.gif"
    Content-Type: image/gif
    Content-Transfer-Encoding: binary
    
    ...contents of image.gif...
    --MyBoundary--
    

    Content-Type 헤더에 boundary를 지정하여 서버가 전송 된 데이터를 분할하는 방법을 알고 있도록합니다.

    따라서 기본적으로 경계 값을 선택해야합니다.

  3. ==============================

    3.@RequestParts에 매개 변수 이름을 지정하지 않으셨습니까?

    @RequestParts에 매개 변수 이름을 지정하지 않으셨습니까?

    public @ResponseBody ActivityTemplate createActivityTemplate(
        @RequestPart("activityTemplate") ActivityTemplate activityTemplate, @RequestPart("file") MultipartFile jarFile)
    {
       //process the file and JSON
    }
    

    참고 : 클래스 경로에 jackson mapper .jar (Json을 ActivityTemplate에 매핑) 파일을 포함시키는 것을 잊지 마십시오.

  4. ==============================

    4.너를 바꿀 수는 없어.

    너를 바꿀 수는 없어.

    @RequestMapping(value="/create", method=RequestMethod.POST)
    

    @RequestMapping(value="/create",
                    method=RequestMethod.POST, consumes ={"multipart/form-data"})
    
  5. ==============================

    5.기본 콘텐츠 유형은 'application / octet-stream'입니다. jar 파일과 JSON을 업로드하기 때문에 다음과 같이 컨텐츠 유형을 @RequestMapping 주석에 설정해야합니다.

    기본 콘텐츠 유형은 'application / octet-stream'입니다. jar 파일과 JSON을 업로드하기 때문에 다음과 같이 컨텐츠 유형을 @RequestMapping 주석에 설정해야합니다.

    @RequestMapping(value="/create", method=RequestMethod.POST, headers="content-type=application/json,application/java-archive")
    
  6. ==============================

    6.오류 메시지는 콘텐츠 형식의 다중 부분 / MIME 부분에 대해 등록 된 HttpMessageConverter가 없음을 나타냅니다 (application / octet-stream). 그래도 jarFile 매개 변수는 application / octet-stream으로 올바르게 식별 될 수 있으므로 매개 변수 매핑이 일치하지 않는다고 가정합니다.

    오류 메시지는 콘텐츠 형식의 다중 부분 / MIME 부분에 대해 등록 된 HttpMessageConverter가 없음을 나타냅니다 (application / octet-stream). 그래도 jarFile 매개 변수는 application / octet-stream으로 올바르게 식별 될 수 있으므로 매개 변수 매핑이 일치하지 않는다고 가정합니다.

    먼저 매개 변수와 양식의 입력 요소에 동일한 이름을 설정하십시오.

    또 다른 문제점은 JSON이 다중 부분 / MIME에서 별도의 부분이 아닌 양식의 텍스트 입력 값 (일반)으로 업로드된다는 것입니다. Spring이 JSON 디시리얼라이저를 사용해야한다는 것을 알아 내기 위해 컨텐트 유형 헤더가 없습니다. 대신 @RequestParam을 사용하여이 답변과 같은 특정 변환기를 등록 할 수 있습니다. JSON 매개 변수 (봄 MVC 컨트롤러)

  7. ==============================

    7.이것은 MultipartFile을받는 동안 당신을 "multipart / form-data"로 요청 헤더 content-type을 설정하고, 컨트롤러에서 use = "multipart / form-data"를 사용하고 우리의 요청을 우리의 메소드로 매핑하는데 사용합니다 컨트롤러.

    이것은 MultipartFile을받는 동안 당신을 "multipart / form-data"로 요청 헤더 content-type을 설정하고, 컨트롤러에서 use = "multipart / form-data"를 사용하고 우리의 요청을 우리의 메소드로 매핑하는데 사용합니다 컨트롤러.

    JSON 데이터를 받기를 원한다면 JSONString 형태로 요청을 보내고 jsonstring을 수신 한 다음 나중에 json 객체 형식으로 변환 한 다음 해당 객체를 자신의 작업에 사용하십시오.

    아래 코드를 확인하십시오 :

    @RequestMapping(value="/savingImg", method=RequestMethod.POST, 
            consumes="multipart/form-data", produces="application/json")
    public ResponseEntity<?> savingAppIMgDtlss(
            @RequestParam(value="f1", required = false) MultipartFile f1 , 
            @RequestParam(value="f2", required = false) MultipartFile f2 ,
            @RequestParam(value="f3", required = false) MultipartFile f3 ,
            @RequestParam(value="f4", required = false) MultipartFile f4 ,
            @RequestParam(value="f5", required = false) MultipartFile f5 ,
            @RequestParam(value="f6", required = false) MultipartFile f6 ,
            @RequestParam(value="f7", required = false) MultipartFile f7 ,
            @RequestParam(value="f8", required = false) MultipartFile f8 ,@RequestParam("data") String jsonString) 
                    throws Exception , ParseException {
        try{
            JSONObject gstcTranObj = new JSONObject();
                    //converting JSONString to JSON
            net.sf.json.JSONObject jsonDtls = net.sf.json.JSONObject.fromObject(jsonString);
            System.out.println("f1::"+f1.getOriginalFilename());
            System.out.println("f2::"+f2.getOriginalFilename());
            System.out.println("f3::"+f3.getOriginalFilename());
            System.out.println("f4::"+f4.getOriginalFilename());
            System.out.println("f5::"+f5.getOriginalFilename());
            System.out.println("f6::"+f6.getOriginalFilename());
            System.out.println("f7::"+f7.getOriginalFilename());
            System.out.println("f8::"+f8.getOriginalFilename());
    } catch (Exception e) {
            e.printStackTrace();
    
            return new ResponseEntity<>("Failed",HttpStatus.NOT_FOUND);
        }finally{
    
        }
    return new ResponseEntity<>("Success", HttpStatus.OK);
    
      }
    }
    
  8. from https://stackoverflow.com/questions/27294838/how-to-process-a-multipart-request-consisting-of-a-file-and-a-json-object-in-spr by cc-by-sa and MIT license