玖富娱乐平台全网唯一指定1956注册开户网站

SpringBoot 2.x(七):文雅的处置惩罚非常_玖富娱

日期:2019-01-04 浏览:
玖富娱乐是一家为代理招商,直属主管信息发布为主的资讯网站,同时也兼顾玖富娱乐代理注册登录地址。

媒介

非常的处置惩罚在我们的一样平常开辟中是一个绕不过去的坎,在Spring Boot 项目中怎样文雅的去处置惩罚非常,恰是我们这一节课须要研讨的偏向。

非常的分类

在一个Spring Boot项目中,我们能够把非常分为两种,第一种是要求抵达Controller层之前,第二种是抵达Controller层今后项目代码中发作的毛病。而第一种又能够分为两种毛病范例:1. 途径毛病 2. 相似于要求体式格局毛病,参数范例纰谬等相似毛病。

界说ReturnVO和ReturnCode

为了连结返回值的一致,我们这里界说了一致返回的类ReturnVO,和一个纪录毛病返回码和毛病信息的罗列类ReturnCode,而详细的毛病信息和毛病代码生存到了response.properties中,运用流举行读取。

ReturnVO

public class ReturnVO {

    private static Properties properties = ReadPropertiesUtil.getProperties(System.getProperty("user.dir")   CommonUrl.RESPONSE_PROP_URL);

    /**
     * 返回代码
     */
    private String code;

    /**
     * 返回信息
     */
    private String message;

    /**
     * 返回数据
     */
    private Object data;


    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getMessage() {
        return message;
    }

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

    public String getCode() {
        return code;
    }

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

    /**
     * 默许组织,返回操纵准确的返回代码和信息
     */
    public ReturnVO() {
        this.setCode(properties.getProperty(ReturnCode.SUCCESS.val()));
        this.setMessage(properties.getProperty(ReturnCode.SUCCESS.msg()));
    }

    /**
     * 返回代码,这里须要在罗列中去界说
     * @param code
     */
    public ReturnVO(ReturnCode code) {
        this.setCode(properties.getProperty(code.val()));
        this.setMessage(properties.getProperty(code.msg()));
    }

    /**
     * 返回数据,默许返回准确的code和message
     * @param data
     */
    public ReturnVO(Object data) {
        this.setCode(properties.getProperty(ReturnCode.SUCCESS.val()));
        this.setMessage(properties.getProperty(ReturnCode.SUCCESS.msg()));
        this.setData(data);
    }

    /**
     * 返回毛病的代码,和自界说的毛病信息
     * @param code
     * @param message
     */
    public ReturnVO(ReturnCode code, String message) {
        this.setCode(properties.getProperty(code.val()));
        this.setMessage(message);
    }

    /**
     * 返回自界说的code,message,和data
     * @param code
     * @param message
     * @param data
     */
    public ReturnVO(ReturnCode code, String message, Object data) {
        this.setCode(code.val());
        this.setMessage(message);
        this.setData(data);
    }

    @Override
    public String toString() {
        return "ReturnVO{"  
                "code='"   code   '''  
                ", message='"   message   '''  
                ", data="   data  
                '}';
    }
}

ReturnCode

其他的毛病处置惩罚只须要在罗列类中增加对应的非常便可,罗列的称号要界说为非常的称号,如许能够直接不消对其他的代码举行修正,增加一个新的非常时,仅仅增加罗列类中的字段和properties文件中的属性。

public enum ReturnCode {

    /** 操纵胜利 */
    SUCCESS("SUCCESS_CODE", "SUCCESS_MSG"),

    /** 操纵失利 */
    FAIL("FAIL_CODE", "FAIL_MSG"),

    /** 空指针非常 */
    NullPointerException("NPE_CODE", "NPE_MSG"),

    /** 自界说非常之返回值为空 */
    NullResponseException("NRE_CODE", "NRE_MSG"),

    /** 运行时非常 */
    RuntimeException("RTE_CODE","RTE_MSG"),

    /** 要求体式格局毛病非常 */
    HttpRequestMethodNotSupportedException("REQUEST_METHOD_UNSUPPORTED_CODE","REQUEST_METHOD_UNSUPPORTED_MSG"),

    /** INTERNAL_ERROR */
    BindException("BIND_EXCEPTION_CODE","BIND_EXCEPTION_MSG"),

    /** 页面途径纰谬 */
    UrlError("UE_CODE","UE_MSG");

    private ReturnCode(String value, String msg){
        this.val = value;
        this.msg = msg;
    }

    public String val() {
        return val;
    }

    public String msg() {
        return msg;
    }

    private String val;
    private String msg;
}

response.properties

这里我自界说了一些非常用于背面的测试,在我们现实的项目中须要界说许多的非常去完美。

SUCCESS_CODE=2000
SUCCESS_MSG=操纵胜利

FAIL_CODE=5000
FAIL_MSG=操纵失利

NPE_CODE=5001
NPE_MSG=空指针非常

NRE_CODE=5002
NRE_MSG=返回值为空

RTE_CODE=5001
RTE_MSG=运行时非常

UE_CODE=404
UE_MSG=页面途径有误

REQUEST_METHOD_UNSUPPORTED_CODE=4000
REQUEST_METHOD_UNSUPPORTED_MSG=要求体式格局非常

BIND_EXCEPTION_CODE=4001
BIND_EXCEPTION_MSG=要求参数绑定失利

途径毛病处置惩罚

这里的途径毛病处置惩罚体式格局是采用了完成ErrorController接口,然后完成了getErrorPath()要领:

/**
 * 要求途径有误
 * @author yangwei
 * @since 2019-01-02 18:13
 */
@RestController
public class RequestExceptionHandler implements ErrorController {

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @RequestMapping("/error")
    public ReturnVO errorPage(){
        return new ReturnVO(ReturnCode.UrlError);
    }
}

这里能够举行测试一下:

运用ControllerAdvice对其他范例的非常举行处置惩罚

相似于抵达Controller之前的要求参数毛病,要求体式格局毛病,数据格式纰谬等等毛病都归类为一种,这里仅仅展现要求体式格局毛病的处置惩罚体式格局。

-玖富娱乐是一家为代理招商,直属主管信息发布为主的资讯网站,同时也兼顾玖富娱乐代理注册登录地址。-
/**
 * 全局非常处置惩罚类
 * @author yangwei
 *
 * 用于全局返回json,如需返回ModelAndView请运用ControllerAdvice
 * 继续了ResponseEntityExceptionHandler,关于一些相似于要求体式格局非常的非常举行捕捉
 */
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    private static Properties properties = ReadPropertiesUtil.getProperties(System.getProperty("user.dir")   CommonUrl.RESPONSE_PROP_URL);

    /**
     * 重写handleExceptionInternal,自界说处置惩罚历程
     **/
    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
        //这里将非常直接传给handlerException()要领举行处置惩罚,返回值为OK包管友爱的返回,而不是涌现500毛病码。
        return new ResponseEntity<>(handlerException(ex), HttpStatus.OK);
    }

    /**
     * 非常捕捉
     * @param e 捕捉的非常
     * @return 封装的返回工具
     **/
    @ExceptionHandler(Exception.class)
    public ReturnVO handlerException(Throwable e) {
        ReturnVO returnVO = new ReturnVO();
        String errorName = e.getClass().getName();
        errorName = errorName.substring(errorName.lastIndexOf(".")   1);
        //若是没有界说非常,而是直接抛出一个运行时非常,须要进入以下分支
        if (e.getClass() == RuntimeException.class) {
            returnVO.setMessage(properties.getProperty(valueOf("RuntimeException").msg())  ": "  e.getMessage());
            returnVO.setCode(properties.getProperty(valueOf("RuntimeException").val()));
        } else {
            returnVO.setMessage(properties.getProperty(valueOf(errorName).msg()));
            returnVO.setCode(properties.getProperty(valueOf(errorName).val()));
        }
        return returnVO;
    }
}

这里我们能够举行测试:

@RestController
@RequestMapping(value = "/user")
public class UserController {

    @Autowired
    private IUserService userService;

    @PostMapping(value = "/findAll")
    public Object findAll() {
        throw new RuntimeException("ddd");
    }

    @RequestMapping(value = "/findAll1")
    public ReturnVO findAll1(UserDO userDO) {
        System.out.println(userDO);
        return new ReturnVO(userService.findAll1());
    }

   @RequestMapping(value = "/test")
    public ReturnVO test() {
        throw new RuntimeException("测试非自界说运行时非常");
    }
}

直接在浏览器接见findAll,默许为get要领,这里依照我们希冀会抛出要求体式格局非常的毛病:

接见findAll1?id=123ss,这里因为我们接收的UserDOid属性是Integer范例,以是这里报一个参数绑定非常:

接见test,测试非自界说运行时非常:

连系AOP运用,放入公用模块削减代码的反复

我们上节课运用AOP关于全局非常处置惩罚举行了一次简朴的操纵,这节课举行了完美,并将其放入到我们的公用模块,运用时只需导入jar包,然后在启动类设置装备摆设扫描包途径便可

/**
 * 一致封装返回值和非常处置惩罚
 *
 * @author vi
 * @since 2018/12/20 6:09 AM
 */
@Slf4j
@Aspect
@Order(5)
@Component
public class ResponseAop {

    @Autowired
    private GlobalExceptionHandler exceptionHandler;

    /**
     * 切点
     */
    @Pointcut("execution(public * indi.viyoung.viboot.*.controller..*(..))")
    public void httpResponse() {
    }

    /**
     * 环切
     */
    @Around("httpResponse()")
    public ReturnVO handlerController(ProceedingJoinPoint proceedingJoinPoint) {
        ReturnVO returnVO = new ReturnVO();
        try {
            Object proceed = proceedingJoinPoint.proceed();
            if (proceed instanceof ReturnVO) {
                returnVO = (ReturnVO) proceed;
            } else {
                returnVO.setData(proceed);
            }
        }  catch (Throwable throwable) {
            // 这里直接挪用方才我们在handler中编写的要领
            returnVO =  exceptionHandler.handlerException(throwable);
        }
        return returnVO;
    }
}

做完这些准备工作,今后我们在举行非常处置惩罚的时刻只须要举行以下几步操纵:

  • 引入公用模块jar包
  • 在启动类上设置装备摆设扫描包途径
  • 若是新增非常的话,在罗列类中新增后,再去properties中举行返回代码和返回信息的编纂便可(注重:罗列类的变量名肯定要和非常名连结一致

云撸猫

民众号

-玖富娱乐是一家为代理招商,直属主管信息发布为主的资讯网站,同时也兼顾玖富娱乐代理注册登录地址。


平台知识

联系方式丨CONTACT

  • 全国热线:7711177
  • 传真热线:010-88888888
  • Q Q咨询:7711177
  • 企业邮箱:
首页
电话
短信