2014-11-17 2 views
20

Я пытаюсь загрузить файл с помощью RestTemplate с помощью следующего кода.Загрузка многостраничного файла с использованием шаблона Spring Rest + Spring Web MVC

MultiValueMap<String, Object> multipartMap = new LinkedMultiValueMap<>(); 
    multipartMap.add("file", new ClassPathResource(file)); 

    HttpHeaders headers = new HttpHeaders(); 
    headers.setContentType(new MediaType("multipart", "form-data")); 

    HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<MultiValueMap<String, Object>>(multipartMap, headers); 

    System.out.println("Request for File Upload : " + request); 

    ResponseEntity<byte[]> result = template.get().exchange(
        contextPath.get() + path, HttpMethod.POST, request, 
        byte[].class); 

У меня есть MultipartResolver боб и код Контроллер

@RequestMapping(value = "/{id}/image", method = RequestMethod.POST) 
@ResponseStatus(HttpStatus.NO_CONTENT) 
@Transactional(rollbackFor = Exception.class) 
public byte[] setImage(@PathVariable("id") Long userId, 
     @RequestParam("file") MultipartFile file) throws IOException { 
    // Upload logic 
} 

И я получаю следующее исключение

org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present 
     at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:255) ~[spring-web-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:95) ~[spring-web-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:79) ~[spring-web-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:157) [spring-web-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:124) [spring-web-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(ShallowEtagHeaderFilter.java:80) [spring-web-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) [spring-web-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:67) [log4j-web-2.0.2.jar:2.0.2] 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at m.m.m.AbstractPreAuthenticatedProcessingFilter.doFilter(UapAbstractPreAuthenticatedProcessingFilter.java:109) [classes/:?] 
     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) [spring-security-web-3.2.5.RELEASE.jar:3.2.5.RELEASE] 
     at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) [spring-web-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) [spring-web-4.0.6.RELEASE.jar:4.0.6.RELEASE] 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [?:1.7.0_67] 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [?:1.7.0_67] 
     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-7.0.54.jar:7.0.54] 
     at java.lang.Thread.run(Thread.java:745) [?:1.7.0_67] 
+0

Каков URL-адрес, к которому вы обращаетесь, генерирует ошибку? – benji

+0

Выполнение POST на http: // localhost: 8080/myweb/50/image. Он достигает метода контроллера, но файл отсутствует. Не знаю, почему. – shazin

+0

Пожалуйста, поделитесь конфигурацией 'multipartResolver'. – Mithun

ответ

33

Мультисекционный File Upload работал после выполнения модификации кода Загружать с помощью RestTemplate

LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>(); 
map.add("file", new ClassPathResource(file)); 
HttpHeaders headers = new HttpHeaders(); 
headers.setContentType(MediaType.MULTIPART_FORM_DATA); 

HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<LinkedMultiValueMap<String, Object>>(
        map, headers); 
ResponseEntity<String> result = template.get().exchange(
        contextPath.get() + path, HttpMethod.POST, requestEntity, 
        String.class); 

И добавление MultipartFilter в web.xml

<filter> 
     <filter-name>multipartFilter</filter-name> 
     <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class> 
    </filter> 
    <filter-mapping> 
     <filter-name>multipartFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 
+2

сохранен мой день :) –

+3

Если объект шаблона имеет тип RestTemplate, тот же ответ 400 Я получаю –

+0

Я использую приведенный выше код в клиенте отдыха для загрузки файла в сеть отдыха (на другом сервере, отличном от моего локального компьютера), но получая ошибку как: ошибка ввода-вывода в запросе POST для «http: // anothermachine: 31112/url/path»: ресурс пути к ключу [fileName.csv] не может быть разрешен для URL, потому что он не существует –

0

Больше основано на чувстве, но это ошибка, вы получите если вы пропустили объявление компонента в конфигурации контекста, попробуйте добавить

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

MultipartResolver уже есть. – shazin

+0

oki, вы можете вставить весну mvc conf –

6

Вот мой рабочий пример

@RequestMapping(value = "/api/v1/files/upload", method =RequestMethod.POST) 
public ResponseEntity<?> upload(@RequestParam("files") MultipartFile[] files) { 
    LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>(); 
    List<String> tempFileNames = new ArrayList<>(); 
    String tempFileName; 
    FileOutputStream fo; 

    try { 
     for (MultipartFile file : files) { 
      tempFileName = "/tmp/" + file.getOriginalFilename(); 
      tempFileNames.add(tempFileName); 
      fo = new FileOutputStream(tempFileName); 
      fo.write(file.getBytes()); 
      fo.close(); 
      map.add("files", new FileSystemResource(tempFileName)); 
     } 

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

     HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<>(map, headers); 
     String response = restTemplate.postForObject(uploadFilesUrl, requestEntity, String.class); 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    for (String fileName : tempFileNames) { 
     File f = new File(fileName); 
     f.delete(); 
    } 
    return new ResponseEntity<Object>(HttpStatus.OK); 
} 
3

Для те, кто получает ошибку, получают ошибку как:

I/O error on POST request for "anothermachine:31112/url/path";: class path 
resource [fileName.csv] cannot be resolved to URL because it does not exist. 

Она может быть решена с помощью

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

Если файл не присутствует в пути к классам, и требуется абсолютный путь.