web-dev-qa-db-fra.com

Spring MVC Multipart Request avec JSON

Je souhaite publier un fichier contenant des données JSON avec Spring MVC. J'ai donc développé un service de repos comme

@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);
}

Lorsque j'envoie une demande du reste du client avec content-Type = multipart/form-data or multipart/mixed, Je reçois la prochaine exception: org.springframework.web.multipart.support.MissingServletRequestPartException

Quelqu'un peut-il m'aider à résoudre ce problème?

Puis-je utiliser @RequestPart pour envoyer à la fois Multipart et JSON à un serveur?

62
Sunil Kumar

Voici comment j'ai implémenté Spring MVC Multipart Request avec des données JSON.

Demande multipartie avec données JSON (également appelée multipartie mixte):

Sur la base du service RESTful dans la version Spring 4.0.2, les requêtes HTTP avec la première partie sous forme de données au format XML ou JSON et la deuxième partie sous forme de fichier peuvent être réalisées avec @RequestPart. Vous trouverez ci-dessous un exemple de mise en œuvre.

Extrait de Java:

Le service de repos dans Controller aura mélangé @RequestPart et MultipartFile pour répondre à cette demande 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);
}

Front End (JavaScript) Extrait:

  1. Créez un objet FormData.

  2. Ajoutez le fichier à l'objet FormData en utilisant l'une des étapes ci-dessous.

    1. Si le fichier a été chargé à l'aide d'un élément d'entrée de type "fichier", ajoutez-le à l'objet FormData. formData.append("file", document.forms[formName].file.files[0]);
    2. Ajoutez directement le fichier à l'objet FormData. formData.append("file", myFile, "myfile.txt"); OR formData.append("file", myBob, "myfile.txt");
  3. Créez un blob avec les données JSON sous forme de chaîne et ajoutez-le à l'objet FormData. Ainsi, le type de contenu de la deuxième partie de la demande multipart est "application/json" au lieu du type de fichier.

  4. Envoyez la demande au serveur.

  5. Détails de la demande:
    Content-Type: undefined. Ainsi, le navigateur définit le type de contenu sur multipart/form-data et remplit correctement les limites. Définir manuellement Content-Type sur multipart/form-data ne remplira pas le paramètre de limite de la demande.

Code 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"
            }));

Détails de la demande:

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

Charge utile de la demande:

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

Cela doit marcher!

client (angulaire):

$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;
        }
      };

Backend-Spring Boot:

@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

Comme le dit la documentation:

Relevé lorsque la partie d'une requête "multipart/form-data" identifiée par son nom est introuvable.

Cela peut être dû au fait que la demande n'est pas une donnée multipart/form, soit parce que la pièce n'est pas présente dans la demande, soit parce que l'application Web n'est pas configurée correctement pour traiter les demandes multipart - par ex. pas de MultipartResolver.

2
Vaelyr