web-dev-qa-db-fra.com

Téléchargement de fichier Spring MVC - Impossible de traiter les pièces car aucune configuration en plusieurs parties n'a été fournie

Je suis donc un débutant à Spring et j'essaie de faire en sorte que le téléchargement de fichiers fonctionne pour mon projet (j'utilise Spring Tool Suite btw.) Et lorsque je soumets un formulaire, tout ce que je reçois est:

État HTTP 500 - Impossible d'analyser la demande de servlet en plusieurs parties; l'exception imbriquée est Java.lang.IllegalStateException: impossible de traiter les pièces car aucune configuration en plusieurs parties n'a été fournie

Trace de pile à partir du navigateur:

 type Rapport d'exception 
 
 message Impossible d'analyser la demande de servlet en plusieurs parties; L'exception imbriquée est Java.lang.IllegalStateException: impossible de traiter les pièces car aucune configuration en plusieurs parties n'a été fournie. 
 
 description Le serveur a rencontré une erreur interne qui l'a empêché de répondre à cette demande. 
 
 exception 
 
 org.springframework.web.multipart.MultipartException: impossible d'analyser la demande de servlet en plusieurs parties; l'exception imbriquée est Java.lang.IllegalStateException: impossible de traiter les pièces car aucune configuration en plusieurs parties n'a été fournie 
 org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest (StandardMultipartHttpServletRequest.Java:100) .] org.springframework.web.multipart.support.StandardMultipartHttpServletRequest. (StandardMultipartHttpServletRequest.Java:78) [.________. ] org.springframework.web.multipart.support.MultipartFilter.doFilterInternal (MultipartFilter.Java:108). cause 
 
 Java.lang.IllegalStateException: impossible de traiter les pièces car aucune configuration en plusieurs parties n'a été fournie 
 org.Apache.catalina.connector.Request.parseParts (Request.Java : 2676) 
 Ou g.Apache.catalina.connector.Request.getParts (Request.Java:2643) 
 org.Apache.catalina.connector.RequestFacade.getParts (RequestFacade.Java:1083) 
 org.springframework. web.multipart.support.StandardMultipartHttpServletRequest.parseRequest (StandardMultipartHttpServletRequest.Java:85) 
 org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.sh). .multipart.support.StandardServletMultipartResolver.resolveMultipart (StandardServletMultipartResolver.Java:75) 
 org.springframework.web.multipart.support.MultipartFilter.doFilterInternal (MultipartFilter.jpg). .filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.Java:106) 
 
 note La trace complète de la pile de la cause racine est disponible dans les journaux Apache Tomcat/8.0.27. 

Voici la balise de formulaire dans jsp:

<form:form class="form-horizontal" role="form" method="post"
            action="newArtist.html" modelAttribute="artist" enctype="multipart/form-data">

Partie d'entrée:

<div class="form-group">
    <div class="col-lg-3">
        <label for="photo">Artist photo:</label>
        <form:input type="file" id="photo" path="photo"></form:input>
    </div>
</div>

La photo est stockée dans ce champ dans Objet d'artiste:

@Lob
private byte[] photo;

Méthodes de mappage du contrôleur:

@RequestMapping(value = "/newArtist", method = RequestMethod.GET)
public String showAddArtistForm(Model model)
{
    model.addAttribute("artist", new Artist());
    return "newArtist";
}

@RequestMapping(value = "/newArtist", method = RequestMethod.POST)
public String addArtist(@ModelAttribute("artist") @Valid Artist artist, BindingResult result,
        @RequestParam("photo") MultipartFile photo) throws IOException
{   
    if (result.hasErrors())
        return "newArtist";

    if(photo.getBytes() != null)
        artist.setPhoto(photo.getBytes());

    artistService.addArtist(artist);

    return "redirect:artists.html";
}

Configuration du résolveur en plusieurs parties dans servlet-context.xml:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="10000000"/>
</bean>

Filtres dans web.xml:

<filter>
    <filter-name>MultipartFilter</filter-name>
    <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>MultipartFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Dépendances:

<!-- Apache Commons FileUpload -->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.1</version>
    </dependency>

    <!-- Apache Commons IO -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>

J'ai également importé le fichier de configuration de Tomcat context.xml dans META-INF/context.xml et édité la balise Context comme ceci:

<Context allowCasualMultipartParsing="true">

Rien ne semble fonctionner, toute aide sera grandement appréciée.

10
kbijoch

En fait, vous n'avez besoin d'aucun filtre sur le web.xml pour télécharger votre fichier en plusieurs parties avec Spring MVC. J'ai la même configuration dans mon projet et cela a fonctionné ($ {spring.version} = 4.3.4.RELEASE):

POM

     <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <!-- Apache Commons FileUpload -->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.2</version>
    </dependency>

    <!-- Apache Commons IO -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.5</version>
    </dependency>

HTML

    <form method="POST" enctype="multipart/form-data" action="uploadAction">
        <table>
            <tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
            <tr><td></td><td><input type="submit" value="Upload" /></td></tr>
        </table>
    </form>

Contexte printanier

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="10000000"/>
</bean>

Contrôleur à ressort

@PostMapping("/uploadAction")
    public String handleFileUpload(@RequestParam("file") MultipartFile file,
            RedirectAttributes redirectAttributes) {

        File out = new File("outputfile.pdf");
        FileOutputStream fos = null;

        try {
            fos = new FileOutputStream(out);

            // Writes bytes from the specified byte array to this file output stream 
            fos.write(file.getBytes());
            System.out.println("Upload and writing output file ok");
        } catch (FileNotFoundException e) {
            System.out.println("File not found" + e);
        } catch (IOException ioe) {
            System.out.println("Exception while writing file " + ioe);
        } finally {
            // close the streams using close method
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException ioe) {
                System.out.println("Error while closing stream: " + ioe);
            }

            //storageService.store(file);
            redirectAttributes.addFlashAttribute("message",
                    "You successfully uploaded " + file.getOriginalFilename() + "!");

            return "redirect:/";
        }
    }
5
luis-br

Il est simple de l'exception qu'aucune configuration en plusieurs parties n'est trouvée. Bien que vous ayez fourni multipartResolver bean.

Le problème est que lors de la spécification du MultipartFilter avant le filtre Spring Security, il essaie d'obtenir le bean multipartResolver mais ne peut pas trouve le. Parce qu'il attend le nom/id du bean comme filterMultipartResolver au lieu de ( multipartResolver .

Fais toi plaisir. Veuillez modifier la configuration du bean comme suit -

<bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="10000000"/>
</bean>
4
Ramjan Ali Ashik

Aucune des réponses ne résout correctement le problème. Selon documentation Tomcat , sur la configuration de allowCasualMultipartParsing:

Affectez la valeur true si Tomcat doit automatiquement analyser les corps de requête multipart/form-data lorsque HttpServletRequest.getPart * ou HttpServletRequest.getParameter * est appelé, même lorsque le servlet cible n'est pas marqué avec l'annotation @MultipartConfig (voir Spécification de servlet 3.0, section 3.2 pour plus de détails). Notez que tout paramètre autre que false provoque le comportement de Tomcat d'une manière qui n'est pas conforme aux spécifications techniques . Le défaut est faux.

Alors, quelle est la manière conforme? Lire l'officiel tutoriel JEE 6 donne un indice. Si vous souhaitez utiliser une méthode conforme aux spécifications avec Servlet 3 ou une version plus récente, votre servlet doit avoir un MultipartConfig. Vous avez trois choix, selon la façon dont vous configurez votre servlet:

  • Avec la configuration programmatique: context.addServlet(name, servlet).setMultipartConfig(new MultipartConfigElement("your_path").
  • Avec les annotations, annotez la classe du servlet avec @javax.servlet.annotation.MultipartConfig.
  • Avec la configuration XML, ajoutez ceci au WEB-INF/web.xml descripteur, dans la section de votre servlet:

    <multipart-config>
         <location>/tmp</location>
         <max-file-size>20848820</max-file-size>
         <max-request-size>418018841</max-request-size>
         <file-size-threshold>1048576</file-size-threshold>
    </multipart-config>
    
2
Martín Straus

J'ai quelque chose de similaire, mais ce que j'ai fait, c'est simplement d'envoyer un fichier sans le mapper avec un attribut dans mon modèle, dans votre cas, je modifierais ceci:

<div class="form-group">
    <div class="col-lg-3">
        <label for="photo">Artist photo:</label>
        <input type="file" id="photo" name="file"/>
    </div>
</div>

Dans votre contrôleur

@RequestMapping(value = "/newArtist", method = RequestMethod.POST)
public String addArtist(@ModelAttribute("artist") @Valid Artist artist, BindingResult result,
    @RequestParam("file") MultipartFile file) throws IOException
//Here read the file and store the bytes into your photo attribute
...
1
cralfaro

Ajoutez dans votre fichier de configuration comme:

@Bean(name = "multipartResolver")
public CommonsMultipartResolver CanBeAnyName() { 
//configuration

}
1
susan097

Pour ceux qui obtiennent la même exception pour les gestionnaires de méthodes PUT: utilisez plutôt POST. PUT est incompatible avec le multi-part.

Plus de détails peuvent être trouvés dans le réponse respective

0
izogfif

Eu le même problème dans une application Spring Boot, ces exceptions se produisent plusieurs fois:

  • org.springframework.web.multipart.MultipartException: impossible d'analyser la demande de servlet en plusieurs parties; l'exception imbriquée est
  • Java.lang.IllegalStateException: org.Apache.Tomcat.util.http.fileupload.FileUploadBase $ FileSizeLimitExceededException: le champ multipartFile dépasse sa taille maximale autorisée de 1048576 octets

org.Apache.Tomcat.util.http.fileupload.FileUploadBase $ FileSizeLimitExceededException: le champ multipartFile dépasse sa taille maximale autorisée de 1048576 octets.

Débarrassez-vous de l'exception Tomcat avec cela, avec une copie de catting de http://www.mkyong.com/spring-boot/spring-boot-file-upload-example/

Réinitialisation de la connexion de téléchargement de fichiers volumineux de Tomcat. Vous devez laisser {@link #containerCustomizer ()} fonctionner correctement, une autre exception sage se produira plusieurs fois, RequestMapping pour uploadError échouera.

@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbedded() {

    TomcatEmbeddedServletContainerFactory Tomcat = new TomcatEmbeddedServletContainerFactory();

    Tomcat.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
        if ((connector.getProtocolHandler() instanceof AbstractHttp11Protocol<?>)) {
            //-1 means unlimited
            ((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
        }
    });

    return Tomcat;

}
0
ElMurxOr