SpringBoot 错误处理页

SpringBoot 错误处理有三种情况

  • 数据验证错误
  • 错误页指派
  • 全局异常处理

比如说在提交表单信息的时候,有些信息没填,有些信息有规范的格式,如果不符合要求就是数据校验错误。

我们需要对这些数据的格式进行校验,不符合要求不能接受且要提示错误信息。

验证注解

点击查看源码

springboot 错误处理,数据校验错误

SpringBoot 有数据校验的默认支持,该支持由 Hibernate 开发框架提供。

错误信息统一配置在ValidationMessages.properties文件中。

这种方式每个 VO 类在ValidationMessages.properties文件中配置对应的错误信息,并且在 VO 类的属性上添加上错误注解,过程繁琐。不推荐使用,更推荐使用反射和拦截器的方式处理错误信息。

但是我们还是要会使用这种方式处理数据验证错误,写了一个小 Demo,再接下来简单记录一下使用过程。

添加错误信息配置文件

src/main/resources目录中建立ValidationMessages.properties文件。文件中配置错误信息

1
2
3
4
5
6
7
8
member.mid.notnull.error=邮箱不允许为空
member.mid.email.error=邮箱格式错误
member.mid.length.error=邮箱长度错误
member.age.notnull.error=年龄不允许为空
member.age.digits.error=年龄格式错误
member.salary.notnull.error=工资不允许为空
member.salary.digits.error=工资格式错误
member.birthday.notnull.error=生日不允许为空

VO 类添加注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SuppressWarnings("serial")
public class Member implements Serializable {
    @NotNull(message="{member.mid.notnull.error}")
    @Email(message="{member.mid.email.error}")
    @Length(min=6,message="{member.mid.length.error}")
    private String mid ;
    @NotNull(message="{member.age.notnull.error}")
    @Digits(integer=3,fraction=0,message="{member.age.digits.error}")
    private Integer age ;
    @NotNull(message="{member.salary.notnull.error}")
    @Digits(integer=20,fraction=2,message="{member.salary.digits.error}")
    private Double salary ;
    @NotNull(message="{member.birthday.notnull.error}")
    private Date birthday ;

}

控制器配置校验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RequestMapping(value = "/add", method = RequestMethod.POST)
@ResponseBody
public Object add(@Valid Member vo, BindingResult result) {
    if (result.hasErrors()) {
        Iterator<ObjectError> iterator = result.getAllErrors().iterator();
        while (iterator.hasNext()) {
            ObjectError error = iterator.next();
            System.out.println("【错误信息】code = " + error.getCode() + ",message = " + error.getDefaultMessage());
        }
        return result.getAllErrors();
    } else {
        return vo;
    }
}

springboot 错误处理,配置错误页面

错误页面配置在src/main/view/static目录下,比如叫 error-404.html

SringBoot 1.x 这样处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.shuiyujie.config;

import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;

/**
 * @author shui
 * @create 2019-02-12
 **/
@Configuration
public class ErrorPageConfig {

    @Bean
    public EmbeddedServletContainerCustomizer containerCustomizer() {
        return new EmbeddedServletContainerCustomizer() {
            @Override
            public void customize(
                    ConfigurableEmbeddedServletContainer container) {
                ErrorPage errorPage400 = new ErrorPage(HttpStatus.BAD_REQUEST,
                        "/error-400.html");
                ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND,
                        "/error-404.html");
                ErrorPage errorPage500 = new ErrorPage(
                        HttpStatus.INTERNAL_SERVER_ERROR, "/error-500.html");
                container.addErrorPages(errorPage400, errorPage404,
                        errorPage500);
            }
        };
    }
}

SringBoot 2.x 这样处理

在SpringBoot2中没有EmbeddedServletContainerCustomizer这个类了,要这样处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ackage com.shuiyujie.config;

import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

/**
 * @author shui
 * @create 2019-02-12
 **/
@Component
public class ErrorPageConfig implements ErrorPageRegistrar {
    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        ErrorPage[] errorPages = new ErrorPage[3];
        errorPages[0] = new ErrorPage(HttpStatus.NOT_FOUND, "/error-400.html");
        errorPages[1] = new ErrorPage(HttpStatus.NOT_FOUND, "/error-404.html");
        errorPages[2] = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error-500.html");
        registry.addErrorPages(errorPages);
    }
}

SpringBoot 全局错误处理

之前设置了错误页面,发生错误将会跳转到错误页面。

1
2
3
4
5
6
7
8
9
10
11
/**
 * 演示 500 错误
 *
 * @return
 */
@RequestMapping(value="/get")
@ResponseBody
public String get() {
    System.out.println("除法计算:" + (10 / 0));
    return "hello world" ;
}

比如这样一个 10/0 的错误控制器跳转到 500 页面,这样就看不到详细的报错信息了。我们想看到类似控制台里面更加详细的报错信息。

定义一个错误信息处理的页面

新建一个错误界面src/main/view/templates/error.html

1
2
3
4
5
6
7
8
9
10
11
12
!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
   <title>SpringBoot模版渲染</title>
   <link rel="icon" type="image/x-icon" href="/images/mldn.ico"/>
   <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
</head>
<body>
   <p th:text="${url}"/>
   <p th:text="${exception.message}"/>
</body>
</html>

定义全局异常处理类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@RestControllerAdvice
public class GlobalExceptionHandler {
    // 定义错误显示页,error.html
    public static final String DEFAULT_ERROR_VIEW = "error";

    // 所有的异常都是Exception子类
    @ExceptionHandler(Exception.class)
    public Object defaultErrorHandler(HttpServletRequest request, Exception e) {
        class ErrorInfo {
            private Integer code;
            private String message;
            private String url;

            public Integer getCode() {
                return code;
            }

            public void setCode(Integer code) {
                this.code = code;
            }

            public String getMessage() {
                return message;
            }

            public void setMessage(String message) {
                this.message = message;
            }

            public String getUrl() {
                return url;
            }

            public void setUrl(String url) {
                this.url = url;
            }
        }
        ErrorInfo info = new ErrorInfo();
        // 标记一个错误信息类型
        info.setCode(100);
        info.setMessage(e.getMessage());
        info.setUrl(request.getRequestURL().toString());
        return info;
    }
}
posted @ 2019-02-19 10:26  深页  阅读(142)  评论(0编辑  收藏  举报