web-dev-qa-db-ja.com

JSONを使用したSpring MVCマルチパートリクエスト

Spring MVCを使用して、JSONデータを含むファイルを投稿したい。だから私は休憩サービスを開発しました

@RequestMapping(value = "/servicegenerator/wsdl", method = RequestMethod.POST,consumes = { "multipart/mixed", "multipart/form-data" })
@ResponseBody
public String generateWSDLService(@RequestPart("meta-data") WSDLInfo wsdlInfo,@RequestPart("file") MultipartFile file) throws WSDLException, IOException,
        JAXBException, ParserConfigurationException, SAXException, TransformerException {
    return handleWSDL(wsdlInfo,file);
}

content-Type = multipart/form-data or multipart/mixedを使用して残りのクライアントからリクエストを送信すると、次の例外が発生します:org.springframework.web.multipart.support.MissingServletRequestPartException

誰でもこの問題を解決するのに役立ちますか?

@RequestPartを使用して、MultipartとJSONの両方をサーバーに送信できますか?

62
Sunil Kumar

これが、Spring MVC Multipart RequestをJSONデータで実装した方法です。

JSONデータを使用したマルチパートリクエスト(混合マルチパートとも呼ばれます):

Spring 4.0.2リリースのRESTfulサービスに基づいて、最初の部分がXMLまたはJSON形式のデータであり、2番目の部分がファイルであるHTTPリクエストを@RequestPartで実現できます。以下にサンプル実装を示します。

Javaスニペット:

ControllerのRestサービスには、@ RequestPartとMultipartFileが混在して、このようなMultipart + JSONリクエストを処理します。

@RequestMapping(value = "/executesampleservice", method = RequestMethod.POST,
    consumes = {"multipart/form-data"})
@ResponseBody
public boolean executeSampleService(
        @RequestPart("properties") @Valid ConnectionProperties properties,
        @RequestPart("file") @Valid @NotNull @NotBlank MultipartFile file) {
    return projectService.executeSampleService(properties, file);
}

フロントエンド(JavaScript)スニペット:

  1. FormDataオブジェクトを作成します。

  2. 以下の手順のいずれかを使用して、FormDataオブジェクトにファイルを追加します。

    1. タイプが「file」の入力要素を使用してファイルがアップロードされている場合は、FormDataオブジェクトに追加します。 formData.append("file", document.forms[formName].file.files[0]);
    2. ファイルをFormDataオブジェクトに直接追加します。 formData.append("file", myFile, "myfile.txt"); OR formData.append("file", myBob, "myfile.txt");
  3. 文字列化されたJSONデータでblobを作成し、FormDataオブジェクトに追加します。これにより、マルチパートリクエストの2番目のパートのコンテンツタイプは、ファイルタイプではなく「application/json」になります。

  4. サーバーにリクエストを送信します。

  5. リクエストの詳細:
    Content-Type: undefined。これにより、ブラウザーはContent-Typeをmultipart/form-dataに設定し、境界を正しく埋めます。 Content-Typeをmultipart/form-dataに手動で設定すると、リクエストの境界パラメーターの入力に失敗します。

JavaScriptコード:

formData = new FormData();

formData.append("file", document.forms[formName].file.files[0]);
formData.append('properties', new Blob([JSON.stringify({
                "name": "root",
                "password": "root"                    
            })], {
                type: "application/json"
            }));

リクエストの詳細:

method: "POST",
headers: {
         "Content-Type": undefined
  },
data: formData

ペイロードのリクエスト:

Accept:application/json, text/plain, */*
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryEBoJzS3HQ4PgE1QB

------WebKitFormBoundaryvijcWI2ZrZQ8xEBN
Content-Disposition: form-data; name="file"; filename="myfile.txt"
Content-Type: application/txt


------WebKitFormBoundaryvijcWI2ZrZQ8xEBN
Content-Disposition: form-data; name="properties"; filename="blob"
Content-Type: application/json


------WebKitFormBoundaryvijcWI2ZrZQ8xEBN--
152
Sunil Kumar

これは動作するはずです!

クライアント(角度):

$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 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
9
mohi

ドキュメントが言うように:

名前で識別される「multipart/form-data」リクエストの一部が見つからないときに発生します。

これは、パーツがリクエストに存在しないため、またはWebアプリケーションがマルチパートリクエストを処理するために正しく構成されていないため、リクエストがマルチパート/フォームデータではないためです。 MultipartResolverはありません。

2
Vaelyr