web-dev-qa-db-fra.com

Téléchargement de fichier en plusieurs parties Spring Boot

J'utilise Spring Boot et souhaite utiliser un contrôleur pour recevoir un téléchargement de fichier en plusieurs parties. Lors de l'envoi du fichier, la réponse erreur 415 du type de contenu non pris en charge et le contrôleur ne sont jamais atteints

There was an unexpected error (type=Unsupported Media Type, status=415).
Content type 'multipart/form-data;boundary=----WebKitFormBoundary1KvzQ1rt2V1BBbb8' not supported

J'ai essayé d'envoyer en utilisant form: action dans la page html/jsp et également dans une application client autonome qui utilise RestTemplate. Toutes les tentatives donnent le même résultat

multipart/form-data;boundary=XXXXX not supported.

D'après la documentation en plusieurs parties, il semble que le paramètre de frontière doit être ajouté au téléchargement en plusieurs parties, mais cela ne semble pas correspondre au contrôleur recevant "multipart/form-data"

Ma méthode de contrôleur est configurée comme suit

@RequestMapping(value = "/things", method = RequestMethod.POST, consumes = "multipart/form-data" ,
                                     produces = { "application/json", "application/xml" })
     public ResponseEntity<ThingRepresentation> submitThing(HttpServletRequest request,
                                     @PathVariable("domain") String domainParam,
                                     @RequestParam(value = "type") String thingTypeParam,
                                     @RequestBody MultipartFile[] submissions) throws Exception

Avec Bean Setup

 @Bean
 public MultipartConfigElement multipartConfigElement() {
     return new MultipartConfigElement("");
 }

 @Bean
 public MultipartResolver multipartResolver() {
     org.springframework.web.multipart.commons.CommonsMultipartResolver multipartResolver = new org.springframework.web.multipart.commons.CommonsMultipartResolver();
     multipartResolver.setMaxUploadSize(1000000);
     return multipartResolver;
 }

Comme vous pouvez le constater, le type de consommation a été défini sur "multipart/form-data", mais lorsque le multipart est envoyé, il doit avoir un paramètre de limite et placer une chaîne de limite aléatoire.

Quelqu'un peut-il me dire comment je peux définir le type de contenu dans le contrôleur afin qu'il corresponde ou modifier ma demande afin qu'elle corresponde à la configuration de mon contrôleur?

Mes tentatives d'envoyer ... Essai 1 ...

<html lang="en">
<body>

    <br>
    <h2>Upload New File to this Bucket</h2>
    <form action="http://localhost:8280/appname/domains/abc/things?type=abcdef00-1111-4b38-8026-315b13dc8706" method="post" enctype="multipart/form-data">
        <table width="60%" border="1" cellspacing="0">
            <tr>
                <td width="35%"><strong>File to upload</strong></td>
                <td width="65%"><input type="file" name="file" /></td>
            </tr>
            <tr>
                <td>&nbsp;</td>
                <td><input type="submit" name="submit" value="Add" /></td>
            </tr>
        </table>
    </form>
</body>
</html>

Tentative 2 ....

RestTemplate template = new RestTemplate();
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>();
parts.add("file", new FileSystemResource(pathToFile));

try{

    URI response = template.postForLocation(url, parts);
}catch(HttpClientErrorException e){
    System.out.println(e.getResponseBodyAsString());
}

Tentative 3 ...

FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
        formHttpMessageConverter.setCharset(Charset.forName("UTF8"));


        RestTemplate restTemplate = new RestTemplate();

        restTemplate.getMessageConverters().add( formHttpMessageConverter );
        restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
        restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());

        MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
        map.add("file", new FileSystemResource(path));

        HttpHeaders imageHeaders = new HttpHeaders();
        imageHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);

        HttpEntity<MultiValueMap<String, Object>> imageEntity = new HttpEntity<MultiValueMap<String, Object>>(map, imageHeaders);
        ResponseEntity e=  restTemplate.exchange(uri, HttpMethod.POST, imageEntity, Boolean.class);
        System.out.println(e.toString());
27
Rob McFeely
@RequestBody MultipartFile[] submissions

devrait être

@RequestParam("file") MultipartFile[] submissions

Les fichiers ne sont pas le corps de la requête, ils en font partie et il n'y a pas de HttpMessageConverter intégré qui puisse convertir la requête en un tableau de MultiPartFile.

Vous pouvez également remplacer HttpServletRequest par MultipartHttpServletRequest, ce qui vous donnera accès aux en-têtes des différentes pièces.

22
a better oliver

Vous pouvez simplement utiliser une méthode controller comme ceci:

@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<?> uploadFile(
    @RequestParam("file") MultipartFile file) {

  try {
    // Handle the received file here
    // ...
  }
  catch (Exception e) {
    return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
  }

  return new ResponseEntity<>(HttpStatus.OK);
} // method uploadFile

Sans aucune configuration supplémentaire pour Spring Boot.

En utilisant le côté suivant HTML côté client:

<html>
<body>
  <form action="/uploadFile" method="POST" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" value="Upload"> 
  </form>
</body>
</html>

Si vous voulez définir des limites sur la taille des fichiers , vous pouvez le faire dans le application.properties:

# File size limit
multipart.maxFileSize = 3Mb

# Total request size for a multipart/form-data
multipart.maxRequestSize = 20Mb

De plus, pour envoyer le fichier avec Ajax , regardez ici: http://blog.netgloo.com/2015/02/08/ printemps-boot-fichier-upload-with-ajax /

23
Andrea

La dernière version de SpringBoot rend le téléchargement de plusieurs fichiers très simple également. Du côté du navigateur, vous avez simplement besoin du formulaire de téléchargement HTML standard, mais avec plusieurs éléments d’entrée (un par fichier à télécharger, ce qui est très important), tous ayant le même nom d’élément (name = "files" pour l'exemple ci-dessous)

Ensuite, dans votre classe Spring @Controller sur le serveur tout ce dont vous avez besoin, cela ressemble à ceci:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
    public @ResponseBody ResponseEntity<?> upload(
        @RequestParam("files") MultipartFile[] uploadFiles) throws Exception     
{
    ...now loop over all uploadFiles in the array and do what you want
  return new ResponseEntity<>(HttpStatus.OK);
}

Ce sont les parties difficiles. Autrement dit, savoir créer plusieurs éléments d’entrée nommés "fichiers" et savoir utiliser un MultipartFile [] (tableau) comme paramètre de requête sont des choses délicates à connaître, mais c’est aussi simple que cela. Je ne parlerai pas de la façon de traiter une entrée MultipartFile, car il existe déjà de nombreux documents à ce sujet.

6
user2080225
   @Bean
    MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        factory.setMaxFileSize("5120MB");
        factory.setMaxRequestSize("5120MB");
        return factory.createMultipartConfig();
    }

mettez-le en classe où vous définissez les haricots

4
Ashutosh Jha

Dans Controller, votre méthode devrait être:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
    public ResponseEntity<SaveResponse> uploadAttachment(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
....

En outre, vous devez mettre à jour application.yml (ou application.properties) pour prendre en charge la taille de fichier maximale et la taille de la demande.

spring:
    http:
        multipart:
            max-file-size: 5MB
            max-request-size: 20MB
1
THIMIRA
@RequestMapping(value="/add/image", method=RequestMethod.POST)
public ResponseEntity upload(@RequestParam("id") Long id, HttpServletResponse response, HttpServletRequest request)
{   
    try {
        MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest)request;
        Iterator<String> it=multipartRequest.getFileNames();
        MultipartFile multipart=multipartRequest.getFile(it.next());
        String fileName=id+".png";
        String imageName = fileName;

        byte[] bytes=multipart.getBytes();
        BufferedOutputStream stream= new BufferedOutputStream(new FileOutputStream("src/main/resources/static/image/book/"+fileName));;

        stream.write(bytes);
        stream.close();
        return new ResponseEntity("upload success", HttpStatus.OK);

    } catch (Exception e) {
        e.printStackTrace();
        return new ResponseEntity("Upload fialed", HttpStatus.BAD_REQUEST);
    }   
}
1
Vikki Kamboj