java web 之springboot教程(六)----统一异常处理

在日常开发中发生了异常,往往是需要通过一个统一的异常处理处理所有异常,来保证客户端能够收到友好的提示。SpringBoot在页面 发生异常的时候会自动把请求转到/error,SpringBoot内置了一个BasicErrorController对异常进行统一的处理,当然也可以自定义这个路径。

自定义的错误页面

我们会发现无论是发生什么错误,SpringBoot都会返回一个状态码以及一个错误页面,这个错误页面是怎么来的呢? 
我们来看看SpringBoot错误处理模块的源码就会非常清楚,默认的发生错误,它会将请求转发到BasicErrorController控制器来处理请求,下面是该controller类的源码:

@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {

    private final ErrorProperties errorProperties;

    /**
     * Create a new {@link BasicErrorController} instance.
     * @param errorAttributes the error attributes
     * @param errorProperties configuration properties
     */
    public BasicErrorController(ErrorAttributes errorAttributes,
            ErrorProperties errorProperties) {
        this(errorAttributes, errorProperties,
                Collections.<ErrorViewResolver>emptyList());
    }

    /**
     * Create a new {@link BasicErrorController} instance.
     * @param errorAttributes the error attributes
     * @param errorProperties configuration properties
     * @param errorViewResolvers error view resolvers
     */
    public BasicErrorController(ErrorAttributes errorAttributes,
            ErrorProperties errorProperties, List<ErrorViewResolver> errorViewResolvers) {
        super(errorAttributes, errorViewResolvers);
        Assert.notNull(errorProperties, "ErrorProperties must not be null");
        this.errorProperties = errorProperties;
    }

    @Override
    public String getErrorPath() {
        return this.errorProperties.getPath();
    }

    @RequestMapping(produces = "text/html")
    public ModelAndView errorHtml(HttpServletRequest request,
            HttpServletResponse response) {
        HttpStatus status = getStatus(request);
        Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
                request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
        response.setStatus(status.value());
        ModelAndView modelAndView = resolveErrorView(request, response, status, model);
        return (modelAndView == null ? new ModelAndView("error", model) : modelAndView);
    }

    @RequestMapping
    @ResponseBody
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        Map<String, Object> body = getErrorAttributes(request,
                isIncludeStackTrace(request, MediaType.ALL));
        HttpStatus status = getStatus(request);
        return new ResponseEntity<Map<String, Object>>(body, status);
    }

从上面的源码我们可以看到,它有两个RequestMapping方法来映射错误请求,为什么会是两个呢?其实errorHtml方法映射的是浏览器发送来的请求,而error方法映射的是不是浏览器而是其他软件app客户端发送的错误请求。

在resources/public/error/ 下定义404.html,500.html或者在templates/error/下定义404.html,500.html;

注意:templates/error/ 这个的优先级比较 resources/public/error/高

400.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>404</title>
</head>
<body>
    亲,您所访问的页面不存在
</body>
</html>

 500.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>500</title>
</head>
<body>
    服务器内部错误
</body>
</html>

不过注意的是上面的这种自定义页面的方式只在浏览器端有效,而不是浏览器发送的请求不会生效。因此下面我们就讲一下如何自定义异常处理来解决这个问题。

自定义异常处理

1,定义个exception类,yonglai

package com.cx.springbootdemo.exception;

public class UserNotExistException extends RuntimeException{

    private static final long serialVersionUID = 1L;
    private String id;
    public UserNotExistException(String id) {
        super("user not exist");
        this.id=id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getId() {
        return id;
    }
}

加上@ControllerAdvice注解将会处理controller层抛出的对应的异常,这里我们处理controller抛出的UserNotExistException自定义异常,并且将错误信息以及用户id以json串的格式返回给客户。 
接着,我们在controller的请求方法中抛出这个异常,会看到在浏览器中的异常是我们自定义的异常返回的json数据。

Controller层代码:

//    @GetMapping("/user/{id:\\d+}")
    @RequestMapping(value="/user/{id:\\d+}",method=RequestMethod.GET)
    public User get(@PathVariable String id) {
        throw new UserNotExistException(id);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值