我们有一个带有嵌入式jetty的spring boot服务器,它暴露了一个rest接口。
我们的RestController服务使用" multipart / form-data" (上传文件),我们使用javax.validation
(hibernate)验证请求的参数返回 BAD_REQUEST 。
这里的问题是,当没有给出参数时,jetty和spring的过滤器会抛出异常,并且 500 INTERNAL ERROR 将返回给客户端。
我们想在这种情况下返回 400 BAD REQUEST ,但我们找不到合适的方法,因为在尝试控制器或参数验证之前请求被拒绝(我们制作@NotNull @RequestParam ("文件&#34))。所以不会调用controllerAdvice
当类型为" multipart / form-data"时,Jetty和Spring过滤器拒绝HTTP请求。并且没有属性(没有任何部分的多部分)
你对这个案子有什么建议?
这是堆栈跟踪
WARN 2017/07/17 18:15:52.849 CEST <Thread[qtp1020520290-18]> EXCEPTION
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.io.IOException: Missing content for multipart request
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982) ~[spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) ~[spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) ~[javax.servlet-api-3.1.0.jar!/:3.1.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) ~[javax.servlet-api-3.1.0.jar!/:3.1.0]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845) ~[jetty-servlet-9.3.11.v20160721.jar!/:9.3.11.v20160721]
.........................
Caused by: org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.io.IOException: Missing content for multipart request
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:111) ~[spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:85) ~[spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:76) ~[spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1099) ~[spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:932) ~[spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
... 42 common frames omitted
答案 0 :(得分:0)
此问题发生在IOException
包裹的org.springframework.web.multipart.MultipartException
。
只需为该error-page
异常类型创建一个标准的Servlet规范MultipartException
错误处理程序,并让您的调度(作为ERROR)页面报告您想要的状态代码400。
请注意,如果您这样做,您还希望在类似的org.eclipse.jetty.http.BadMessageException
错误处理程序中捕获error-page
,以解决在您的Spring代码被调用之前发生的类似问题。
另请注意,有许多类型的错误请求,其中许多通常不属于servlet上下文(或之前),并且无法通过spring错误处理来处理,因此这种错误设置对于您的特定需求非常常见
答案 1 :(得分:0)
你可以编写自己的ControllerAdvice,就像这样。
@ResponseBody
@ExceptionHandler(MultipartException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorObject handleMultiPartException(
MultipartException e) {
//process error message
return new ErrorObject(e);
}
答案 2 :(得分:0)
我没有通过HandleException(MultipartException)捕获错误,而是通过将 MultipartFile设置为可选(必需= false),然后检查MultipartFile变量是否为null
。 / p>
...
@RequestMapping(value = "/csv", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<?> downloadFile(@RequestParam(value = "file", required = false) MultipartFile file) {
// Manage the error if no files are uploaded | Not possible to use ExceptionHandler for MultipartFile
if (file == null) {
return new ResponseHTTP().WithError("No CSV file selected", HttpStatus.BAD_REQUEST);
}
...