web-dev-qa-db-ja.com

Spring MVCファイルのアップロード-マルチパート構成が提供されていないため、パーツを処理できません

だから私はSpringの初心者であり、私のプロジェクトでファイルのアップロードを動作させようとしています(Spring Tool Suite btwを使用しています)。

HTTPステータス500-マルチパートサーブレットリクエストを解析できませんでした。ネストされた例外はJava.lang.IllegalStateExceptionです:マルチパート構成が提供されていないため、パーツを処理できません

ブラウザからのスタックトレース:

 type Exception report 
 
 messageマルチパートサーブレットリクエストを解析できませんでした。ネストされた例外はJava.lang.IllegalStateExceptionです。マルチパート構成が提供されていないため、パーツを処理できません。
 
 descriptionサーバーは、このリクエストの実行を妨げる内部エラーを検出しました。
 
 exception 
 
 org.springframework.web.multipart.MultipartException:マルチパートサーブレットリクエストを解析できませんでした。ネストされた例外はJava.lang.IllegalStateException:マルチパート構成が提供されていないため、パーツを処理できません
 org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.Java:100)
 org.springframework.web.multipart.support.StandardMultipartHttpServletRequest。(StandardMultipartHttpServletRequest.Java:78)
 org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.Java:75)
 org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.Java:108)
 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:106)
 root cause 
 
 Java.lang.IllegalStateException:マルチパート構成が提供されていないため、パーツを処理できません
 org.Apache.catalina.connector.Request.parseParts(Request.Java :2676)
または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。(StandardMultipartHttpServletRequest.Java:78)
 org.springframework.web .multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.Java:75)
 org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.Java:108)
 org.springframework.web .filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:106)
 
 note根本原因の完全なスタックトレースは、Apache Tomcat/8.0.27ログで利用可能です。

これはjspのformタグです。

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

入力部:

<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>

写真は、アーティストオブジェクトのこのフィールドに保存されます。

@Lob
private byte[] photo;

コントローラーのマッピング方法:

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

Servlet-context.xmlのマルチパートリゾルバー設定:

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

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>

依存関係:

<!-- 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>

Tomcatの設定ファイルcontext.xmlをMETA-INF/context.xmlにインポートし、次のようにContextタグを編集しました。

<Context allowCasualMultipartParsing="true">

何も機能していないようです。どんな助けも大歓迎です。

10
kbijoch

実際、Spring MVCでマルチパートファイルをアップロードするためにweb.xmlにフィルターは必要ありません。私は私のプロジェクトで同じ設定をしていて、それが機能しました($ {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>

春のコンテキスト

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

スプリングコントローラー

@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

マルチパート構成が見つからないという例外から簡単です。 multipartResolverBeanを提供しましたが。

問題は、Spring Securityフィルターの前にMultipartFilterを指定しているときに、multipartResolverBeanを取得しようとしますが、見つからないことです。 Beanの名前/ IDはfilterMultipartResolverではなくmultipartResolver

自分に好意を行います。次のようにBean構成を変更してください-

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

答えはどれも問題を適切に解決しません。 Tomcat documentation によると、allowCasualMultipartParsingの設定:

ターゲットサーブレットが@MultipartConfigアノテーションでマークされていない場合でも、TomcatがHttpServletRequest.getPart *またはHttpServletRequest.getParameter *が呼び出されたときにmultipart/form-dataリクエストボディを自動的に解析する場合はtrueに設定します(サーブレット仕様3.0、セクション3.2を参照)詳細については)。 false以外の設定は、技術的に仕様に準拠していない方法でTomcatを動作させることに注意してください。デフォルトはfalseです。

それで、準拠する方法は何ですか?公式の JEE 6チュートリアル を読むとヒントが得られます。 Servlet 3以降で仕様に準拠した方法を使用する場合、サーブレットにはMultipartConfigが必要です。サーブレットの構成方法に応じて、3つの選択肢があります。

  • プログラム構成の場合:context.addServlet(name, servlet).setMultipartConfig(new MultipartConfigElement("your_path")
  • アノテーションを使用して、サーブレットのクラスに@javax.servlet.annotation.MultipartConfigアノテーションを付けます。
  • XML構成で、これをサーブレットのセクションのWEB-INF/web.xml記述子に追加します。

    <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

私は似たようなものを持っていますが、私がやったのは、モデルの属性とマッピングせずにファイルを送信するだけです、あなたの場合はこれを変更します:

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

コントローラーで

@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

構成ファイルに次のように追加します。

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

}
1
susan097

PUTメソッドハンドラーで同じ例外が発生する場合:代わりにPOSTを使用します。 PUTはマルチパートと互換性がありません。

詳細は それぞれの答え にあります。

0
izogfif

Spring Bootアプリケーションで同じ問題が発生した場合、この例外は数回発生します。

  • org.springframework.web.multipart.MultipartException:マルチパートサーブレットリクエストを解析できませんでした。ネストされた例外は
  • Java.lang.IllegalStateException:org.Apache.Tomcat.util.http.fileupload.FileUploadBase $ FileSizeLimitExceededException:フィールドmultipartFileは最大許容サイズである1048576バイトを超えています

org.Apache.Tomcat.util.http.fileupload.FileUploadBase $ FileSizeLimitExceededException:フィールドmultipartFileが最大許容サイズである1048576バイトを超えています。

http://www.mkyong.com/spring-boot/spring-boot-file-upload-example/ からコピーして、これでTomcatの例外を取り除きます

Tomcatの大きなファイルのアップロード接続のリセット。 {@link #containerCustomizer()}を適切に動作させる必要があります。そうしないと、他の賢明な例外が数回発生し、uploadErrorのRequestMappingが失敗します。

@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