使用@Aspect和@Before注解以及全局异常拦截

记录:390

场景:使用aspectjweaver包的@Aspect和@Before注解拦截自定义注解@VerifyCity。自定义注解@VerifyCity作用在Controller的方法上。实现在执行Controller的方法前,先拦截注解校验必要参数。使用@RestControllerAdvice和@ExceptionHandler注解拦截异常,实现优雅返回异常信息。

版本:JDK 1.8,SpringBoot 2.6.3

AOP:Aspect Oriented Programming,面向切面编程。

AOP:将业务逻辑的各个部分进行隔离,使开发人员在编写业务逻辑时可以专心于核心业务,从而提高了开发效率。

AOP:取横向抽取机制,取代了传统纵向继承体系的重复性代码,主要应用在事务处理、日志管理、权限控制、异常处理等方面。

1.自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface VerifyCity {
    String value() default "";
}

2.使用@Aspect和@Before实现拦截自定义注解

2.1代码

@Aspect
@Order(0)
@Component
@Slf4j
public class VerifyCityAspect {
  @Before("@annotation(verifyCity)")
  public void beforeVerify(VerifyCity verifyCity) {
    RequestAttributes reqAttributes = RequestContextHolder.currentRequestAttributes();
    HttpServletRequest httpReq = ((ServletRequestAttributes) reqAttributes).getRequest();
    String httpCityName = httpReq.getHeader("cityName");
    String annotationCityName = verifyCity.value();
    log.info("从http请求头中获取的城市名称,cityName=" + httpCityName);
    log.info("从Controller的方法上的@VerifyCity注解获取的城市名称,cityName=" + annotationCityName);
    if (!StringUtils.equals(httpCityName, annotationCityName)) {
      log.info("校验失败,不执行Controller.");
      throw new VerifyException("校验城市编码失败.");
    }
    log.info("校验成功,执行Controller.");
  }
}

2.2解析

@Aspect,标记实现AOP。

@Before("@annotation(verifyCity)"),标记拦截注解@VerifyCity。

StringUtils.equals(httpCityName, annotationCityName),比对从请求头中获取的cityName的值与从注解@VerifyCity中获取的值,相等则验证通过,否则抛出一个异常,结束程序。

throw new VerifyException("校验城市编码失败."),抛出定义异常,结束本次请求,也就是不会执行@VerifyCity标记的Controller的方法了。

3.自定义异常

自定义VerifyException继承RuntimeException。

public class VerifyException extends RuntimeException {
  private String errorCode = "";
  public VerifyException(String message) {
      super(message);
      this.errorCode = "500";
  }
  public String getErrorCode() {
      return errorCode;
  }
}

4.自定义全局拦截器

4.1代码

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
  @ExceptionHandler(value = VerifyException.class)
  public String bizExceptionHandler(HttpServletRequest req, VerifyException e) {
    String errMsg = "异常编码: " + e.getErrorCode() + ";异常信息: " + e.getMessage();
    log.error(errMsg);
    return errMsg;
  }
}

4.2解析

@RestControllerAdvice,标记全局异常。

@ExceptionHandler(value = VerifyException.class),指定拦截的异常类型。

返回值类型String,抛出异常后,会组装成字符串信息返回,而不是一连串报错异常。

5.使用自定义注解

在Controller类使用注解@VerifyCity("Hangzhou")。

@Slf4j
@RestController
@RequestMapping("/hub/example/city")
public class CityController {
  @VerifyCity("Hangzhou")
  @PostMapping("/queryCityByCityCode")
  public Object queryCityByCityCode(String cityCode) {
      log.info("入参cityCode = "+cityCode);
      return "执行成功";
  }
}

6.使用Postman测试

6.1请求地址与入参

地址:http://127.0.0.1:18200/hub-200-base/hub/example/city/queryCityByCityCode

入参:cityCode=310001

请求头:cityName=Hangzhou

返回值:执行成功

6.2优雅拦截异常返回

返回值:异常编码: 500;异常信息: 校验城市编码失败.

6.3不使用全局拦截异常返回

把VerifyCityAspect中抛出异常改为:

throw new RuntimeException("校验城市编码失败.");

不优雅返回值:

{
  "timestamp": "2023-03-23T23:03:4127+08:00",
  "status": 500,
  "error": "Internal Server Error",
  "path": "/hub-200-base/hub/example/city/queryCityByCityCode"
}

或者

java.lang.RuntimeException: 校验城市编码失败.
  at com.hub.example.aspect.VerifyCityAspect.beforeVerify(VerifyCityAspect.java:37) ~[classes/:na]
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
  at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]

7.核心依赖包

<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.9.19</version>
</dependency>

以上,感谢。

2023年3月23日

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值