【发布时间】:2017-02-09 15:52:09
【问题描述】:
我有一个文件要上传到我的 spring-boot 微服务。我正在使用 jQuery 使用 FormData javascript 对象发布文件。由于无法将我的 FormData 文件与 RequestParam 文件匹配,Spring-boot 没有在我的控制器中调用我的端点。
JavaScript:
var name = "TEST";
var kml = '<kml><Document><Placemark id="' + name + '"><Point><coordinates>-69.83701518,47.817278750000014</coordinates></Point></Placemark></Document></kml>';
// upload the kml file to the server
var data = new FormData();
data.append('file', kml);
$.ajax({
method: "POST",
url: "http://localhost:9096/upload/" + name,
data: data,
cache: false,
contentType: false,
processData: false,
success: function(data){
console.log("success", name, data);
}
});
这是我的控制器代码:
@RestController
public class MicroServiceController {
private Logger logger = LoggerFactory.getLogger(MicroServiceController.class);
@RequestMapping(value="/upload/{name}", method = { RequestMethod.POST })
public ResponseEntity<?> uploadKML(@PathVariable String name, @RequestParam("file") MultipartFile file ) throws IOException {
logger.debug("Upload: {}", name);
return new ResponseEntity<Boolean>(true, HttpStatus.OK);
}
}
这是一个例外:
2017-02-09 11:45:52.860 DEBUG 5521 --- [nio-9096-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'microServiceController'
2017-02-09 11:45:52.888 DEBUG 5521 --- [nio-9096-exec-1] .w.s.m.m.a.ServletInvocableHandlerMethod : Failed to resolve argument 1 of type 'org.springframework.web.multipart.MultipartFile'
org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:193) ~[spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:109) ~[spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.6.RELEASE.jar!/:4.3.6.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_121]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_121]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.11.jar!/:8.5.11]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_121]
2017-02-09 11:45:52.889 DEBUG 5521 --- [nio-9096-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolving exception from handler [public org.springframework.http.ResponseEntity<?> com.jasco.microservice.MicroServiceController.uploadKML(java.lang.String,org.springframework.web.multipart.MultipartFile) throws java.io.IOException]: org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
2017-02-09 11:45:52.891 DEBUG 5521 --- [nio-9096-exec-1] .w.s.m.a.ResponseStatusExceptionResolver : Resolving exception from handler [public org.springframework.http.ResponseEntity<?> com.jasco.microservice.MicroServiceController.uploadKML(java.lang.String,org.springframework.web.multipart.MultipartFile) throws java.io.IOException]: org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
2017-02-09 11:45:52.891 DEBUG 5521 --- [nio-9096-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolving exception from handler [public org.springframework.http.ResponseEntity<?> com.jasco.microservice.MicroServiceController.uploadKML(java.lang.String,org.springframework.web.multipart.MultipartFile) throws java.io.IOException]: org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
2017-02-09 11:45:52.891 DEBUG 5521 --- [nio-9096-exec-1] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-02-09 11:45:52.892 DEBUG 5521 --- [nio-9096-exec-1] o.s.web.servlet.DispatcherServlet : Successfully completed request
这是请求和标头:
Request URL:http://localhost:9096/upload/TEST
Request Method:POST
Status Code:400
Remote Address:127.0.0.1:9096
Request Headers:
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Cache-Control:no-cache
Connection:keep-alive
Content-Length:273
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryM401einBJzuTMVSj
Host:localhost:9096
Origin:http://localhost:8090
Pragma:no-cache
Referer:http://localhost:8090/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36
Request Payload
------WebKitFormBoundaryM401einBJzuTMVSj
Content-Disposition: form-data; name="file"
<kml><Document><Placemark id="TEST"><Point><coordinates>-69.83701518,47.817278750000014</coordinates></Point></Placemark></Document></kml>
------WebKitFormBoundaryM401einBJzuTMVSj--
以及响应 JSON:
{"timestamp":1486655346223,"status":400,"error":"Bad Request","exception":"org.springframework.web.multipart.support.MissingServletRequestPartException","message":"Required request part 'file' is not present","path":"/upload/TEST"}
对我来说,看起来我将文件名设置为“文件”,并且我也在微服务中寻找“文件”......但它似乎没有在 spring 上建立连接-引导端。我很困惑,因为这一切看起来都像我在互联网上找到的示例和问题,但我仍然得到例外。
任何关于下一步要尝试什么或我搞砸的地方的建议都会很有帮助!
【问题讨论】:
-
我对 spring-boot 社区取消他们的论坛,然后不回答 stackoverflow 问题感到非常失望。他们网站上几乎整个问题页面都有 0 个答案。
-
对于其他遇到此问题的人,我正在通过不使用表单数据而是将 kml 放入正文中来解决此问题,然后将参数从“@RequestParam MultipartFile 文件”更改为“@ RequestBody 字符串 kml”。如果我的公里数太大,我会被狗咬的。
-
我发现把MultipartFile改成MultipartFile[]会调用成功,但是数组是空的。
-
底层请求包含正确的上传文件数据,但spring-boot无法识别。不确定这是弹簧启动错误还是我做错了什么 - 我不会解决这个问题 - 只是通过使用 body raw 来避开它。
标签: jquery spring spring-boot file-upload netflix-zuul