2017-01-31 19 views
2

MultipartFileを使用してSpringを使用してファイルをアップロードする、Java設定のWebサービスを実装しようとしています。私は春のブートを使用していないと私のクラスパスにcommons-fileuploadライブラリがあります。春休みSpring起動のないJava設定のMultiPartファイルアップロード

私が言うの春のドキュメント読み:

あなたはweb.xmlの「マルチパート-config設定」セクションで、またはプログラムサーブレット登録でjavax.servlet.MultipartConfigElementでのDispatcherServletをマークする必要があるのか​​、サーブレットクラスのjavax.servlet.annotation.MultipartConfigアノテーションを持つカスタムサーブレットクラスの場合...前述のいずれかの方法でサーブレット3.0のマルチパート解析が有効になったら、SpringコンフィグレーションにStandardServletMultipartResolverを追加できます

したがって、私はadde D私のAppConfigクラスにこのBean:

@Bean 
public StandardServletMultipartResolver multipartResolver() { 
    return new StandardServletMultipartResolver(); 
} 

MultipartConfigを持つクラスを注釈付き:

@EnableWebMvc 
@MultipartConfig(maxFileSize = 5120) 
public class AppConfig extends WebMvcConfigurerAdapter{ 
... 
} 

しかし、私がサービスを呼び出すとき、私はこの例外を取得:私が使用している場合

Caused by: org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.lang.UnsupportedOperationException: SRVE8020E: Servlet does not accept multipart request 
    at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:111) 
    at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:85) 
    at org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:76) 
    at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:112) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207) 
    at [internal classes] 
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207) 
    ... 1 more 
Caused by: java.lang.UnsupportedOperationException: SRVE8020E: Servlet does not accept multipart request 
    at com.ibm.ws.webcontainer.srt.SRTServletRequest.prepareMultipart(SRTServletRequest.java:3657) 
    at [internal classes] 
    at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:92) 

StandardServletMultipartResolverの代わりにCommonsMultipartResolverと同じエラーが発生します。

これは私が自分のアプリケーションを初期化する方法である:

public class AppInitializer implements WebApplicationInitializer { 

    @Override 
    public void onStartup(ServletContext servletContext) throws ServletException { 
     AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); 
     context.register(AppConfig.class); 
     context.setServletContext(servletContext); 

     servletContext.addListener(new ContextLoaderListener(context)); 

     ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcherServlet", new DispatcherServlet(context)); 
     dispatcher.setLoadOnStartup(1); 
     dispatcher.addMapping("/"); 


     CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); 
     characterEncodingFilter.setEncoding("UTF-8"); 
     characterEncodingFilter.setForceEncoding(true); 

     EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD); 
     FilterRegistration.Dynamic characterEncoding = servletContext.addFilter("CharacterEncodingFilter", characterEncodingFilter); 
     characterEncoding.addMappingForUrlPatterns(dispatcherTypes, true, "/*"); 

    } 
} 

私もMultipartFilterが、運とを追加してみました。

MultipartFilter multipartFilter = new MultipartFilter(); 
FilterRegistration.Dynamic multipart = servletContext.addFilter("multipartFilter", multipartFilter); 
    multipart.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); 

これは必要ですか?何が間違っているのですか?私は解決策を探してインターネット全体を読むと思うが、彼らはすべてMultipartConfigElementMultipartConfigFactoryで春のブートを使用しています。たぶん、問題は私がサービスを消費する方法ですか?

これは私のコントローラのメソッドです:

@RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = "multipart/form-data") 
public Long uploadAttachment(@RequestParam("cn") String callerName, @RequestParam("cs") String callerService, @RequestParam("file") MultipartFile file) 

、これは私がそれを消費する方法である:

File file = new File("C:\\Users\\cte0289\\Documents\\Email\\document.docx"); 
RestTemplate rest = new RestTemplate(); 
LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>(); 

map.add("cn", callerName); 
map.add("cs", callerService); 
map.add("file", file);    
Long response = rest.postForObject(url + "/upload", map, Long.class); 

私はやって他に何か分からない助けてください。

+0

'@ MultipartConfig'を追加することは、サーブレット上にあるはずなので、かなり無駄です。ディスパッチャーサーブレットを使用するときは、サーブレットの登録時に取得する登録オブジェクトに 'MultipartConfigElement'を設定する必要があります。代わりに、コモンズファイルアップロードを使用するように切り替えてください。したがって、サーブレットを正しく構成していない限り、サーブレット3.0のアップロードは機能しません(いくつのフィルタを前に置いてください)。 –

+0

この行をAppInitializerクラスの 'dispatcher.setMultipartConfig(新しいMultipartConfigElement(" C:/ tmp "、1024 * 1024 * 5、1024 * 1024 * 5 * 5、1024 * 1024));で' 'MultipartConfigElement 'しかし、私はまだエラーが発生します。これは間違っていますか?あなたに質問すると、私は 'CharacterEncodingFilter'が必要です – amicoderozer

+0

@ M.Deinum私はサービスを消費するために使用している方法が正しいかどうか知っていますか?私はコモンズファイルのアップロードとサーブレット3.0で両方のアプローチを試みましたが、私はそれを動作させることができません。 – amicoderozer

答えて

1

Java構成でファイルのアップロードを処理するために、春のプロジェクトを構成する正しい方法はこれです:あなたはコモンズのFileUploadライブラリでそれを設定したい場合は あなたは、あなたのConfigurationクラスでこのBeanを含めると、あなたはサーブレット3でプロジェクトを設定したい場合は、あなたのクラスパスに

@Bean 
public CommonsMultipartResolver multipartResolver(){ 
    CommonsMultipartResolver resolver = new CommonsMultipartResolver(); 
    resolver.setMaxUploadSize(5242880); // set the size limit 
    return resolver; 
} 

jarを追加する必要があります。

dispatcher.setMultipartConfig(new MultipartConfigElement("C:/tmp", 1024*1024*5, 1024*1024*5*5, 1024*1024)); 

と(私の場合のAppConfig)を設定クラスでこのBeanを含める:

@Bean 
public StandardServletMultipartResolver multipartResolver() { 
    return new StandardServletMultipartResolver(); 
} 

は私が間違っていた@AlieneilAはあなたがディスパッチャサーブレットでMultipartConfig要素を設定する必要が言ったように0、私はLinkedMultiValueMapにファイルを挿入しました。私はFileSystemResourceを使用する必要がありました:

File file = new File("C:\\document.doc"); 
RestTemplate rest = new RestTemplate(); 
LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>(); 

map.add("param1", param1); 
map.add("param2", param2); 
map.add("file", new FileSystemResource(file));    
Long response = rest.postForObject(url, map, Long.class); 

またはMockMultipartFileこの回答により示唆されるように:この場合https://stackoverflow.com/a/38270420/6503002

依存関係として春のモックを含める:

<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-mock</artifactId> 
    <version>2.0.8</version> 
</dependency> 
1

私はあなたがこのような何かをしようとする場合がありますと思う:

 public class AppInitializer implements WebApplicationInitializer { 

     @Override 
     public void onStartup(ServletContext servletContext) throws ServletException { 
      AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); 
      context.register(AppConfig.class); 
      context.setServletContext(servletContext); 

      servletContext.addListener(new ContextLoaderListener(context)); 

      ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcherServlet", new DispatcherServlet(context)); 
      dispatcher.setLoadOnStartup(1); 
      dispatcher.addMapping("/"); 
dispatcher.setMultipartConfig(getMultipartConfigElement()); 


      CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); 
      characterEncodingFilter.setEncoding("UTF-8"); 
      characterEncodingFilter.setForceEncoding(true); 

      EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD); 
      FilterRegistration.Dynamic characterEncoding = servletContext.addFilter("CharacterEncodingFilter", characterEncodingFilter); 
      characterEncoding.addMappingForUrlPatterns(dispatcherTypes, true, "/*"); 

     } 

    private MultipartConfigElement getMultipartConfigElement(){ 
      MultipartConfigElement multipartConfigElement = new MultipartConfigElement("C:/tmp", 1024*1024*5, 1024*1024*5*5, 1024*1024); 
      return multipartConfigElement; 
     } 
    } 
+0

私はこのソリューションを試みたが、私はまだ同じエラーが発生します。とにかくありがとう! – amicoderozer

+0

私はファイルをアップロードする方法を見てみることをお勧めします。 File file = new File(..) ファイル(filebucket)用のクラスを作るのがいいかもしれないし、MultipartFileをアップロードしようとしないといいでしょうか? – AlieneilA

+1

あなたは正しいです、私は間違った方法でファイルをアップロードしました。提案していただきありがとうございます。 +1 – amicoderozer

0

誰でもAbstractAnnotationConfigDispatcherServletInitializerを拡張した場合にはWebアプリケーションの初期化設定のためのクラス、簡単な設定の下で有効になりますMultiPart特集 -

import javax.servlet.MultipartConfigElement; 
import javax.servlet.ServletRegistration.Dynamic; 

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; 

public class WebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 

    @Override 
    protected Class<?>[] getRootConfigClasses() { 
     return null; 
    } 

    @Override 
    protected Class<?>[] getServletConfigClasses() { 
     return new Class[] { AppConfig.class }; 
    } 

    @Override 
    protected String[] getServletMappings() { 
     return new String[] { "/" }; 
    } 

    @Override 
    protected void customizeRegistration(Dynamic registration) { 

     MultipartConfigElement multiPart = new MultipartConfigElement("C:/temp/", 
       1024 * 1024 * 5, 1024 * 1024 * 10, 1024 * 1024 * 3); 

     registration.setMultipartConfig(multiPart); 
    } 

} 
関連する問題