禁用重定向到某些网址的/错误

时间:2016-09-06 11:20:43

标签: spring spring-boot exception-handling

我创建了一个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?

非常感谢。

1 个答案:

答案 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 ,您还可以实施ErrorViewResolversee 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");
        }   
    }
}