您在控制器建议中的方法上缺少 @ResponseBody 注释。它会导致错误,因为 Spring 正在尝试从该方法中查找名称返回为 String 的模板,因此在 REST 调用期间您会得到如下内容:
{
"error": "Not Found",
"exception": "javax.validation.ConstraintViolationException",
"message": "No message available",
"path": "/history",
"status": 404,
"timestamp": 1502293311543
}
给handleValidationFailure(ConstraintViolationException ex)方法添加@ResponseBody注解意味着当你返回一个String时,它不是模板名而是响应对象本身。
或者,您可以在您的通知方法中使用ResponseEntity<String> 作为返回类型,例如
@ExceptionHandler(value = {ConstraintViolationException.class})
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public ResponseEntity<String> handleValidationFailure(ConstraintViolationException ex) {
StringBuilder messages = new StringBuilder();
for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
messages.append(violation.getMessage());
}
return ResponseEntity.badRequest().body(messages.toString());
}
因此您不必使用@ResponseBody 来注释方法,Spring 现在将您的响应不是视图名称而是响应主体本身。希望对你有帮助。
更新
我假设您调用的端点不正确。我创建了一个小型 Spring Boot 应用程序,它使用提供的信息复制您的问题:
https://github.com/wololock/rest-validation-demo
随意克隆它并运行它。运行后你可以尝试调用/history端点:
curl "localhost:8080/history?emp=AZ000001A"
它会作为回报显示:
{"id":"AZ000001A","name":"Joe Doe"}%
如果您使用违反验证规则的emp 调用此端点:
curl "localhost:8080/history?emp=sd"
您将收到以下回复:
{"message":"Your request contains errors","errors":[{"getHistory.arg0":"Invalid emp"}]}
我的假设是,在您的情况下,您错误地调用了端点。使用@RestController 注解存在普遍的误解。我看到人们像@RestController("/someRootPath") 这样使用它,然后他们希望有像
这样的端点
localhost:8080/someRootPath/...
这是不正确的。传递给@RestController注解的值只不过是:
该值可能表示对逻辑组件名称的建议,在自动检测到组件的情况下将其转换为 Spring bean。
您可以随时查看控制台日志以查看您的控制器的最终映射是什么,例如
2017-08-09 20:40:45.663 INFO 1340 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6385cb26: startup date [Wed Aug 09 20:40:44 CEST 2017]; root of context hierarchy
2017-08-09 20:40:45.696 INFO 1340 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/history],methods=[GET]}" onto public org.springframework.http.ResponseEntity<com.github.wololock.restvalidationdemo.Employee> com.github.wololock.restvalidationdemo.EmployeeController.getHistory(java.lang.String)
2017-08-09 20:40:45.698 INFO 1340 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2017-08-09 20:40:45.698 INFO 1340 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-08-09 20:40:45.708 INFO 1340 --- [ main] o.s.w.s.h.BeanNameUrlHandlerMapping : Mapped URL path [/employee] onto handler '/employee'
2017-08-09 20:40:45.714 INFO 1340 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-08-09 20:40:45.714 INFO 1340 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
希望对你有帮助。