赞
踩
本文分为两种方法,第一种适合于对于小程序这种简单的应用,只需要得到错误消息即可,第二章针对大型规范化的网页项目。
1、继承RuntimeException。
2、实现get和set方法(lombok工具类实现)
3、创建两个变量,一个用于保存状态码另一个保存错误消息。
4、创建可能使用到的构造方法
super(msg)表示将错误信息以我们平时看见的红色字样打印在控制台
- import lombok.Data;
- @Data//异常类
- public class EmosException extends RuntimeException{
- private int code=500;
- private String msg;
-
- //对该异常类的构造方法进行补充,不写的化会默认只有一个无参构造
- public EmosException(String msg) {
- super(msg);
- this.msg = msg;
- }
-
- public EmosException(String msg, int code) {
- super(msg);
- this.msg = msg;
- this.code = code;
- }
-
- public EmosException(String msg, Throwable e) {
- super(msg, e);
- this.msg = msg;
- }
-
- public EmosException(String msg, int code, Throwable e) {
- super(msg, e);
- this.msg = msg;
- this.code = code;
- }
-
- }
1、给这个类+@RestControllerAdvice注解表示是异常处理的配置类。
2、给该类的方法上+@ResponseBody注解表示返回的是JSON类型,@ExceptionHandler表示处理的异常是什么类型的异常。
3、书写异常处理方法,参数就是总异常类Exception。
4、用if else if等进行分支,用instanceof判断是什么类型的。
返回的类型都是字符串类型,保存在requset.data中,前台获取只需要request.data即可得到异常消息。
- package com.example.emos.config;
- import com.example.emos.exception.EmosException;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.shiro.authz.UnauthorizedException;
- import org.springframework.http.HttpStatus;
- import org.springframework.web.bind.MethodArgumentNotValidException;
- import org.springframework.web.bind.annotation.ExceptionHandler;
- import org.springframework.web.bind.annotation.ResponseBody;
- import org.springframework.web.bind.annotation.ResponseStatus;
- import org.springframework.web.bind.annotation.RestControllerAdvice;
-
- @Slf4j//打印日志信息用
- @RestControllerAdvice//让系统知道这是处理异常的类
- //步骤:1、将异常转化为对应的类型 2、调用里面的获取消息模块
- public class ExceptionAdvice {
- @ResponseBody//将异常的返回格式为json格式
- @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
- @ExceptionHandler(Exception.class)//处理哪种异常
- public String exceptionHandler(Exception e){
- log.error("执行异常",e);//将异常打印在控制台
- //处理后端验证失败
- if(e instanceof MethodArgumentNotValidException){
- //将异常强转为验证异常
- MethodArgumentNotValidException exception= (MethodArgumentNotValidException) e;
- //获取异常消息
- return exception.getBindingResult().getFieldError().getDefaultMessage();
- }
- //自定义异常
- else if(e instanceof EmosException){
- EmosException exception= (EmosException) e;
- return exception.getMsg();
- }
- //未授权类型
- else if(e instanceof UnauthorizedException){
- return "你不具备相关权限";
- }
- else{
- return "后端执行异常";
- }
- }
- }
该封装方法将每一种异常对应的状态码,以及异常返回消息的统一封装
1、新建一个properties文件,用于保存所有的异常消息文本:
- lin.codes[0] = ok
- lin.codes[999] = 服务器未知异常
-
- lin.codes[10000] = 通用错误
- lin.codes[10001] = 通用参数错误
- lin.codes[10002] = 资源未找到
- lin.codes[10003] = 没有找到合适的登陆处理方法
- lin.codes[10004] = 令牌不合法或者过期
- lin.codes[10005] = 用户未被授权
- lin.codes[10006] = 登陆失败
-
- lin.codes[20000] = 用户类通用错误
- lin.codes[20001] = 用户已存在
- lin.codes[20002] = 用户不存在
- lin.codes[20003] = 用户密码错误
- lin.codes[20004] = 获取用户wx openid失败
2、写一个配置文件,将上面写好的各种异常消息在SpringBoot开启时就读取进去。
- package com.lin.missyou.core.CodeConfiguration;
-
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.context.annotation.PropertySource;
- import org.springframework.stereotype.Component;
- import java.util.HashMap;
- import java.util.Map;
-
- //指明共有的前缀
- @ConfigurationProperties(prefix = "lin")
- //指明异常文件的地址
- @PropertySource(value = "classpath:config/exception-code.properties",encoding = "UTF-8")
- //加入到SpringBoot容器
- @Component
- //将那个文件的所有内容都读到这个map中
- public class ExceptionCodeConfiguration {
-
- private Map<Integer, String> codes = new HashMap<>();
-
- public Map<Integer, String> getCodes() {
- return codes;
- }
-
- public void setCodes(Map<Integer, String> codes) {
- this.codes = codes;
- }
-
-
- public String getMessage(int code){
- String message = codes.get(code);
- return message;
- }
- }
配置文件的位置如下:
3、此时我们新建一个父类继承RuntimeException,用于让所有的关于http的异常都继承它:
- package com.lin.missyou.exception.http;
-
- /**
- * 这是下面所有小错误类的父类。
- * 1、同包的所有类都继承这个类,不同异常的code和状态码不同。code码指的是前面写的异常信息的数组索引
- * 2、根据状态码对异常进行分类。
- * 3、例如商品没找到,或用户没找到,都抛出NotFoundException,状态码来表示是什么没找到
- * */
- public class HttpException extends RuntimeException{
- protected Integer code;
- protected Integer httpStatusCode = 500;
-
- public Integer getCode() {
- return code;
- }
-
- public Integer getHttpStatusCode() {
- return httpStatusCode;
- }
-
-
- }
下面我们以一个NotFoundException为例:
- package com.lin.missyou.exception.http;
-
- public class NotFoundException extends HttpException{
- public NotFoundException(int code){
- this.httpStatusCode = 404;
- this.code = code;
- }
- }
我还创建了一个和它写法一致的异常类,只是httpStatusCode不同:
4、此时我们来到最核心的部分,全局异常管理类:
在这里将处理我们前面所写的全部异常,每当新增一个异常类就要在这里写好对应的处理方法。
1、打上@ControllerAdvice注解表示是处理异常类的
2、打上@ResponseBody 防止返回JSON对象出现问题
3、将刚刚写好的处理异常消息的封装类注入今来
4、@ExceptionHandler表示处理什么异常
5、@ResponseStatus表示该异常的http状态码是多少。该部分有两种处理方式:
完整代码:
- //当有异常时会进入这个类
- @ControllerAdvice //内部包含了Component注解,所以会被SpringBoot发现
- @ResponseBody //因为异常返回的也是对象,所以要加这个注解
- public class GlobalExceptionAdvice {
- @Autowired //将异常配置文件与这个类相对应
- private ExceptionCodeConfiguration codeConfiguration;
-
- //一、处理一个已知hpptStatus的异常
- @ExceptionHandler(value=Exception.class)
- /**
- * 设置Http的状态码,不设置的话都是200正常。设置方式有两种:
- * 1、 @ResponseStatus来设置状态码。不灵活,不能动态设置
- * 2、通过ResponseEntity来设置返回的属性
- * */
- @ResponseStatus(code= HttpStatus.INTERNAL_SERVER_ERROR)
- public UnifyResponse handleException(HttpServletRequest req, Exception e) {
- String requestUrl = req.getRequestURI(); //获取出现异常的地址
- String method = req.getMethod(); //获取是GET还是POST方法
- System.err.println(e);
- return new UnifyResponse(9999, "服务器异常", method + " "+ requestUrl);
- }
-
- //二、处理自己写的那些httpStatus动态变化HttpException<-自己写的那个父类
- @ExceptionHandler(HttpException.class)
- /**2、通过ResponseEntity来设置返回的属性(状态码等)*/
- public ResponseEntity<UnifyResponse> handleHttpException(HttpServletRequest req, HttpException e){
- //1、获取URL和请求方法
- String requestUrl = req.getRequestURI();
- String method = req.getMethod();
- //2、封装返回对象
- UnifyResponse message =
- new UnifyResponse(
- e.getCode() //获取自定义的异常状态码
- ,codeConfiguration.getMessage(e.getCode()) //通过这个自定义状态码来查询对应的消息
- , method + " " + requestUrl); //封装方法和URL
-
- //3、因为没用指定状态码,所以需要用ResponseEntity对象。
- //3.1与ResponseBody注解用处相同,不加无法返回对象以及对中文等都无法解析
- HttpHeaders headers = new HttpHeaders();
- headers.setContentType(MediaType.APPLICATION_JSON);
- //3.2通过异常来获取http状态码信息
- HttpStatus httpStatus = HttpStatus.resolve(e.getHttpStatusCode());
-
- //4、返回对象
- return new ResponseEntity<>(message, headers, httpStatus);
- }
- }
调用处:
- @Override
- public BannerByNameVo findByName(String name) {
- BannerByNameVo bannerItems = bannerDao.selectByNames(name);
- if (bannerItems==null)
- throw new NotFoundException(10005);
- return bannerItems;
- }
返回形式如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。