我创建了一个springboot应用程序,它在... / api / myEndpoints中包含一些Rest API端点...以及用户可以与之交互的一些UI表单的百万美元模板。
因为我添加了一个errorController:
@Controller
@RequestMapping("/error")
public class ErrorController {
@RequestMapping(method = RequestMethod.GET)
public String index(Model model) {
return "error";
}
}
每当我的RestControllers中抛出异常时,我会收到一个空的白色网站,其中包含单词" error"。这可能对网络前端有意义,但不适合我的api。对于API,我希望spring输出标准的JSON结果,例如:
{
"timestamp": 1473148776095,
"status": 400,
"error": "Bad request",
"exception": "java.lang.IllegalArgumentException",
"message": "A required parameter is missing (IllegalArgumentException)",
"path": "/api/greet"
}
当我从ErrorController中删除索引方法时,我总是收到JSON输出。 我的问题是:是否有可能只为所有api urls(../api/*)排除自动重定向到/ error?
非常感谢。
答案 0 :(得分:8)
在那之前可能有更好的解决方案,直到那时......这里有你如何实现你的要求:
(1)禁用ErrorMvcAutoConfiguration
将此添加到您的application.properties
:
spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration
(2)定义两个ControllerAdvices
由于我们禁用了ErrorMvcAutoConfiguration
,我们需要自己捕获异常。创建一个建议来捕获特定包的错误,另一个建议来捕获所有其他包。它们每个都重定向到不同的URL。
//Catch exception for API.
@ControllerAdvice(basePackageClasses = YourApiController.class)
@Order(Ordered.HIGHEST_PRECEDENCE)
public static class ErrorApiAdvice {
@ExceptionHandler(Throwable.class)
public String catchApiExceptions(Throwable e) {
return "/error/api";
}
}
//Catch all other exceptions
@ControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE)
public static class ErrorAdvice {
@ExceptionHandler(Throwable.class)
public String catchOtherExceptions() {
return "/error";
}
}
(3)创建一个控制器来处理错误页面
您可以在错误处理中使用不同的逻辑:
@RestController
public class MyErrorController {
@RequestMapping("/error/api")
public String name(Throwable e) {
return "api error";
}
@RequestMapping("/error")
public String error() {
return "error";
}
}
使用 Spring-Boot 1.4.x ,您还可以实施ErrorViewResolver
(see this doc):
@Component
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request,
HttpStatus status, Map<String, Object> model) {
if("/one".equals(model.get("path"))){
return new ModelAndView("/errorpage/api");
}else{
return new ModelAndView("/errorpage");
}
}
}