栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Boot【定制化】~ AOP统一结果处理以及异常拦截

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Boot【定制化】~ AOP统一结果处理以及异常拦截

1、简介

用处:统一结果处理与异常拦截。

2、配置步骤 2.1、创建一个spring boot项目(idea)

完整项目结构!

2.2、导入依赖(需要使用到简化环境搭建)


    org.springframework.boot
    spring-boot-starter-aop




    com.alibaba
    fastjson
    1.2.76




    org.apache.commons
    commons-lang3



    org.springframework.boot
    spring-boot-starter-web



    org.springframework.boot
    spring-boot-devtools
    runtime
    true



    org.projectlombok
    lombok
    true


    org.springframework.boot
    spring-boot-starter-test
    test
    
        
            org.junit.vintage
            junit-vintage-engine
        
    
2.3、yml

注意:我们这个测试不需要yml(写上来防止你们疑惑!)

spring:
  application:
    name: springboot-day02-aop-exception    #服务名称(项目名)

2.4、需要使用的工具类

注意:直接复制使用,工具类方法太多所以直接抽取几个用到的方法(不是重点)。

1、StringUtils

public class StringUtils extends org.apache.commons.lang3.StringUtils
{
    
    public static boolean isEmpty(String str)
    {
        return isNull(str) || "".equals(str.trim());
    }
    
    public static boolean isNotEmpty(String str)
    {
        return !isEmpty(str);
    }

    public static boolean isNull(Object object)
    {
        return object == null;
    }

    public static boolean isNotNull(Object object)
    {
        return !isNull(object);
    }
    
}

2、ServletUtils

public class ServletUtils
{
    
    public static String parseString(HttpServletResponse response, String string)
    {
        try
        {
            response.setStatus(200);
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(string);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return null;
    }

}

2.5、需要使用的枚举以及状态

1、ErrorEnum

public enum ErrorEnum {

    
    P_ERROR_NULL("P0100", "参数%s不能为空"),
    P_NOT_EXIST("P0101", "%s不存在"),
    P_FORMAT_ERROR("P0102", "%s格式不正确"),

    
    S_CATCH_AUTH("S0104", "%s"),
    S_TOKEN_EXPIRED("S0104", "Token过期"),
    S_ERROR("S0105","系统异常 练习管理员!佳佳吖!"),
    ;

    private String code;
    private String message;

    ErrorEnum() {
    }

    ErrorEnum(String code, String message) {
        this.code = code;
        this.message = message;
    }

    public String getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    
    public String getMessage(String message) {
        if (StringUtils.isNotEmpty(message)) {
            return String.format(this.message, message);
        }
        return "";
    }

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

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

2、状态码常量类

public class HttpStatus 
{

    
    public static final int SUCCESS = 200;

    
    public static final int BAD_METHOD = 405;

    
    public static final int ERROR = 500;
    
}

2.6、统一结果返回格式对象
public class ResultReturn extends LinkedHashMap
{

    public static final Date newDateTime = new Date();
    public static final String CODE = "code";
    public static final String MSG = "message";
    public static final String DATE_TIME = "datetime";
    public static final String DATA = "data";

    public ResultReturn() {}

    public ResultReturn(Object code, String msg, Date datetime, Object data)
    {
        super.put(CODE, code);
        super.put(MSG, msg);
        super.put(DATE_TIME, datetime.getTime());
        if (StringUtils.isNotNull(data))
        {
            super.put(DATA, data);
        }
    }

    
    public static Object success(Object data)
    {
        return new ResultReturn(200, "success", newDateTime, data);
    }

    public static Object success()
    {
        return ResultReturn.success(null);
    }

    
    public static Object error(ErrorEnum errorEnum)
    {
        return new ResultReturn(errorEnum.getCode(), errorEnum.getMessage(), new Date(), null);
    }

    public static Object error(Object code, String errorMsg)
    {
        return new ResultReturn(code, errorMsg, newDateTime, null);
    }

    public static ResultReturn error(RuanjiaExceptionHandler e)
    {
        return new ResultReturn(e.getCode(), e.getMessage(), newDateTime, null);
    }
}

2.7、Controller统一返回结果(AOP)

1、自定义注解

作用:如果有不想被Aop拦截的controller方法,就是用该注解标识。

@Target({ ElementType.TYPE, ElementType.METHOD }) //用于方法上
@Retention(RetentionPolicy.RUNTIME) //保留政策:运行时
@Documented
public @interface OriginalReturn
{

}

2、统一结果拦截类(AOP切面类)

作用(重点):使用Aop实现统一结果拦截。

@Aspect
@Slf4j
@Component
public class ResultAspectj
{

    @Pointcut("execution(public * com.ruanjia.controller..*.*(..))")
    public void result() {};

    
    @Around("result()")
    public Object afterReturningMethod(ProceedingJoinPoint point) throws Throwable {
        Object proceed = point.proceed();
        
        if (proceed instanceof ModelAndView || proceed instanceof View) {
            return proceed;
        }
        Method method = ((MethodSignature) point.getSignature()).getMethod();
        
        if (method.isAnnotationPresent(OriginalReturn.class)) {
            return proceed;
        }
        return ResultReturn.success(proceed);
    }

}

2.8、全局异常拦截

1、自定义异常类

作用:处理系统业务异常(这里还可以细写,可以根据自己需要增加自定义异常!)

@Data
public class RuanjiaExceptionHandler extends RuntimeException
{

    private Object code;
    private String message;

    public RuanjiaExceptionHandler(ErrorEnum errorCodeEnum)
    {
        this.code = errorCodeEnum.getCode();
        this.message = errorCodeEnum.getMessage();
    }

    
    public RuanjiaExceptionHandler(ErrorEnum errorCodeEnum, String message)
    {
        super(errorCodeEnum.getMessage(message));
        if (StringUtils.isNotEmpty(message)) {
            this.message = errorCodeEnum.getMessage(message);
        } else {
            this.message = errorCodeEnum.getMessage();
        }
        this.code = errorCodeEnum.getCode();
    }

    
    public RuanjiaExceptionHandler(String message)
    {
        this.code = HttpStatus.ERROR;
        this.message = message;
    }

}

2、全局异常类

作用:拦截所有Controller异常

@Slf4j
@ControllerAdvice
public class SystemGlobalExceptionHandler
{

    
    @ExceptionHandler(RuanjiaExceptionHandler.class)
    public void ruanjiaExceptionHandler(RuanjiaExceptionHandler e, HttpServletResponse response)
    {
        log.error("===========RuanjiaExceptionHandler(自定义异常)==========");
        e.printStackTrace();
        ServletUtils.parseString(response, JSON.toJSONString(ResultReturn.error(e.getCode(), e.getMessage())));
    }

    
    @ExceptionHandler(ArithmeticException.class)
    public void handlerArithmeticException(ArithmeticException e, HttpServletResponse response)
    {
        log.error("===========ArithmeticException(算术异常)==========");
        e.printStackTrace();
        ServletUtils.parseString(response, JSON.toJSONString(ResultReturn.error(HttpStatus.ERROR, e.getMessage())));
    }

    
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public void handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request, HttpServletResponse response)
    {
        log.error("===========HttpRequestMethodNotSupportedException(GET/POST 不支持异常)==========");
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
        e.printStackTrace();
        ServletUtils.parseString(response, JSON.toJSONString(ResultReturn
                .error(HttpStatus.BAD_REQUEST,"请求地址【"+requestURI+"】,不支持【"+e.getMethod()+"】请求")));
    }

}

此致!配置完成,进入测试环节!

2.9、编写Controller测试类
@RestController
public class TestController
{

    
    @GetMapping("/result")
    public Object result()
    {
        return "同意结果返回测试!";
    }

    
    @GetMapping("/error1")
    public Object error()
    {
        int a = 10/0;
        return a;
    }

    
    @GetMapping("/error2")
    public Object error2(String username)
    {
        if (StringUtils.isEmpty(username))
        {
            throw new RuanjiaExceptionHandler(ErrorEnum.S_CATCH_AUTH, "用户名不能为空!");
        }
        return username;
    }


}

效果图:

1、统一结果返回测试

2、系统算术异常拦截

3、自定义异常拦截

结束语:不要半途而废!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/921340.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号