我正在尝试使用RestTemplate使用以下代码上传文件。
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
bean,而Controller代码是
@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 :(得分:45)
使用RestTemplate
进行上传代码修改后,Multipart文件上传工作正常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>
答案 1 :(得分:13)
以下是我的工作示例
@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);
}
答案 2 :(得分:8)
在大多数情况下,在Web.xml中注册MultipartFilter是不正确的,因为Spring MVC已经完成了处理多部分请求的工作。它甚至写在过滤器的javadoc中。
在服务器端,在您的应用上下文中定义一个multipartResolver bean:
@Bean
public CommonsMultipartResolver multipartResolver(){
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
commonsMultipartResolver.setDefaultEncoding("utf-8");
commonsMultipartResolver.setMaxUploadSize(50000000);
return commonsMultipartResolver;
}
在客户端,这是准备与Spring RestTemplate API一起使用的请求的方法:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
LinkedMultiValueMap<String, String> pdfHeaderMap = new LinkedMultiValueMap<>();
pdfHeaderMap.add("Content-disposition", "form-data; name=filex; filename=" + file.getOriginalFilename());
pdfHeaderMap.add("Content-type", "application/pdf");
HttpEntity<byte[]> doc = new HttpEntity<byte[]>(file.getBytes(), pdfHeaderMap);
LinkedMultiValueMap<String, Object> multipartReqMap = new LinkedMultiValueMap<>();
multipartReqMap.add("filex", doc);
HttpEntity<LinkedMultiValueMap<String, Object>> reqEntity = new HttpEntity<>(multipartReqMap, headers);
ResponseEntity<MyResponse> resE = restTemplate.exchange(uri, HttpMethod.POST, reqEntity, MyResponse.class);
真正重要的是使用确切的大小写提供Content-disposition标头,并添加名称和文件名说明符,否则您的部分将被多部分解析器丢弃。
然后,您的控制器方法可以使用以下参数处理上传的文件:
@RequestParam("filex") MultipartFile file
希望这会有所帮助。
答案 3 :(得分:6)
对于那些收到错误的人:
TransactionsModel = getattr(import_module(__name__), 'TransactionsModel')
可以使用
解决models_root = os.path.join(os.path.dirname(__file__), '..', 'models')
fp, file_path, desc = imp.find_module(module_name, [models_root])
TransactionsModel = imp.load_module(module_name, fp, file_path,
desc).TransactionsModel
TransactionType = imp.load_module(module_name, fp, file_path,
desc).TransactionType
如果类路径中不存在该文件,则需要绝对路径。
答案 4 :(得分:1)
更多基于这种感觉,但如果你错过了在上下文配置中声明bean,那么这就是你会得到的错误,所以尝试添加
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10000000"/>
</bean>
答案 5 :(得分:0)
正确的文件上传是这样的:
HTTP标头:
Content-Type:multipart / form-data; boundary = ABCDEFGHIJKLMNOPQ
Http正文:
-ABCDEFGHIJKLMNOPQ
Content-Disposition:表单数据; name =“文件”; filename =“ my.txt”
Content-Type:应用程序/八位字节流
内容长度:...
<...以64为基数的文件数据...>
-ABCDEFGHIJKLMNOPQ-
和代码是这样的:
public void uploadFile(File file) {
try {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/file/user/upload";
HttpMethod requestMethod = HttpMethod.POST;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, String> fileMap = new LinkedMultiValueMap<>();
ContentDisposition contentDisposition = ContentDisposition
.builder("form-data")
.name("file")
.filename(file.getName())
.build();
fileMap.add(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString());
HttpEntity<byte[]> fileEntity = new HttpEntity<>(Files.readAllBytes(file.toPath()), fileMap);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", fileEntity);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
ResponseEntity<String> response = restTemplate.exchange(url, requestMethod, requestEntity, String.class);
System.out.println("file upload status code: " + response.getStatusCode());
} catch (IOException e) {
e.printStackTrace();
}
}