springboot实现全局异常解析器

一、使用场景

在单体微服务项目中,平时我们在编码时,出现的异常不能直接返回给客户端,问题直接暴露给前台,前台使用体验很差,而且网站还可能遭到恶意攻击。因此使用全局异常捕获,自定义返回结果很有必要。

二、实现全局异常解析器

2.1 引入依赖

基于本文实现的解析器引入相关依赖

<!--    参数校验依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.3.6.Final</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

2.2 代码实现

1.工具类(返回给前端的结果封装)

@Data
@NoArgsConstructor
@AllArgsConstructor
public class R {
    /**
     * 通用成功状态码
     */
    public static final String SUCCESS_CODE = "001";
    /**
     * 失败状态码
     */
    public static final String FAIL_CODE = "004";
    /**
     * 未登录
     */
    public static final String USER_NO_LOGIN = "401";
    private String code;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String msg;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Object data;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Long   total;
    /**
     * 成功
     * @param msg
     * @param data
     * @return
     */
    public static R ok(String msg,Object data,Long total){

        return new R(SUCCESS_CODE,msg,data,total);
    }
    /**
     * 成功
     * @param data
     * @return
     */
    public static R ok(String msg,Object data){

        return ok(msg,data,null);
    }
    /**
     * 成功
     * @return
     */
    public static R ok(String msg){

        return ok(msg,null);
    }
    /**
     * 成功
     * @return
     */
    public static R ok(Object data){

        return ok(null,data);
    }
    /**
     * 失败
     * @param msg
     * @param data
     * @return
     */
    public static R fail(String msg,Object data,Long total){

        return new R(FAIL_CODE,msg,data,total);
    }
    /**
     * 失败
     * @param data
     * @return
     */
    public static R fail(String msg,Object data){

        return fail(msg,data,null);
    }
    /**
     * 失败
     * @return
     */
    public static R fail(String msg){

        return fail(msg,null);
    }
    /**
     * 失败
     * @return
     */
    public static R fail(Object data){

        return fail(null,data);
    }
    /**
     * 未登录
     * @return
     */
    public static R NO_LOGIN(){

        return fail(USER_NO_LOGIN,"用户未登录!");
    }
}

2.全局异常解析器

@Slf4j
@SuppressWarnings("ALL")
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(BindException.class)
    @ResponseStatus(HttpStatus.OK)
    public R bindException(HttpServletRequest request,
                           HttpServletResponse response,
                           BindException exception) {
        BindingResult bindingResult = exception.getBindingResult();
        //获取所有校验异常信息进行拼接返回
        //获取所有校验异常信息进行拼接返回
        String message = exception.getBindingResult().getFieldError().getDefaultMessage();
        return R.fail(message);
//        return R.fail(exception.getBindingResult().getFieldError().getDefaultMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.OK)
    public R methodArgumentNotValidException(HttpServletRequest request,
                                                     HttpServletResponse response,
                                                     MethodArgumentNotValidException exception) {
        BindingResult bindingResult = exception.getBindingResult();
        log.info("GlobalExceptionHandler类中methodArgumentNotValidException方法异常,异常参数:"+exception.getBindingResult().getFieldError().getDefaultMessage());
        //获取所有校验异常信息进行拼接返回
        String message = exception.getBindingResult().getFieldError().getDefaultMessage();
        return R.fail(message);
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.OK)
    public R methodArgumentNotValidException(HttpServletRequest request,
                                                     HttpServletResponse response,
                                                     MissingServletRequestParameterException exception) {
//        return R.fail(exception.getMessage());
        log.info("GlobalExceptionHandler类中methodArgumentNotValidException方法异常,异常信息:"+exception.getMessage());
        return R.fail("请正确填入参数!");
    }

    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.OK)
    public R methodArgumentNotValidException(HttpServletRequest request,
                                                     HttpServletResponse response,
                                                     ConstraintViolationException exception) {
        System.out.println(exception.getLocalizedMessage());
        Iterator<ConstraintViolation<?>> iterator = exception.getConstraintViolations().iterator();
        if (iterator.hasNext()) {
            ConstraintViolationImpl next = (ConstraintViolationImpl)iterator.next();
            return R.fail(next.getMessage());
        }
        return R.fail(exception.getMessage());
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    public R exception(HttpServletRequest request,
                               HttpServletResponse response,
                               Exception exception) {
        log.info("GlobalExceptionHandler类中exception异常,异常信息:"+exception.getMessage());
        return R.fail("预期之外的异常!");
    }

}

3.添加异常解析器

若上述异常解析器不够用。现在我们业务中出现新的需求,需要使用shiro实现登录,那么shiro在登录失败时会返回一个AuthenticationException异常,此时我们在解析器中添加shiro验证异常解析。

/**
     * shiro登录验证失败异常解析器
     * @param request
     * @param response
     * @param exception
     * @return
     */
    @ExceptionHandler(AuthenticationException.class)
    @ResponseStatus(HttpStatus.OK)
    public R methodAuthenticationException(HttpServletRequest request,
                                             HttpServletResponse response,
                                             AuthenticationException exception) {
        log.info("GlobalExceptionHandler类中methodAuthenticationException方法异常,异常信息:"+exception.getMessage());
        return R.fail("登陆失败,请检查账号密码是否正确!");
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值