SSM(十四) 基于 annotation 的 http 防重插件(下)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 针对于我们现在常用的RESTful API通常我们需要对请求进行唯一标识,也就是每次都要带上一个请求号,如reqNO。

使用@Aspect来定义了一个切面。


其中prefixReq,day域可以自定义缓存请求号时的key前缀以及缓存的时间。


最关键的一点是用

@Pointcut("@annotation(com.crossoverJie.request.anotation.CheckReqNo)")


定义了一个切入点,这样所有使用@CheckReqNo的注解都会被拦截。


接下来的逻辑就比较简单了,在每次请求之前进行拦截。


先去Redis中查看这个请求号(ps:反射获取)是否存在,如果不存在则通过并将本次的请求号缓存起来。如果存在则抛出异常。


使用注解


可以在jdbc.properties配置文件中自定义前缀和缓存时间


#redis前缀
redis.prefixReq=reqNo
#redis缓存时间 默认单位为天
redis.day=1


不定义也可以,会使用默认值。


由于该注解是需要加到controller层,因此我们得使用CGLIB代理。


这里有一个坑,需要将开启CGLIB的配置配置到我们web.xml中的


<!-- Spring MVC servlet -->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>


这里所定义的spring-mvc.xml文件中,不然springMVC所在的子容器是无法被父容器所加载的。


使用实例:


@CheckReqNo
    @RequestMapping(value = "/createRedisContent",method = RequestMethod.POST)
    @ResponseBody
    public BaseResponse<NULLBody> createRedisContent(@RequestBody RedisContentReq redisContentReq){
        BaseResponse<NULLBody> response = new BaseResponse<NULLBody>() ;
        Rediscontent rediscontent = new Rediscontent() ;
        try {
            CommonUtil.setLogValueModelToModel(redisContentReq,rediscontent);
            rediscontentMapper.insertSelective(rediscontent) ;
            response.setReqNo(redisContentReq.getReqNo());
            response.setCode(StatusEnum.SUCCESS.getCode());
            response.setMessage(StatusEnum.SUCCESS.getMessage());
        }catch (Exception e){
            logger.error("system error",e);
            response.setReqNo(response.getReqNo());
            response.setCode(StatusEnum.FAIL.getCode());
            response.setMessage(StatusEnum.FAIL.getMessage());
        }
        return response ;
    }


统一异常controller


/**
 *
 * ClassName: ErrorController <br/>
 * Function: 错误异常统一处理. <br/>
 * @author crossoverJie
 * @version
 * @since JDK 1.7
 */
@ControllerAdvice
public class ErrorController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Object processUnauthenticatedException(NativeWebRequest request, Exception e) {
        logger.error("请求出现异常:", e);
        BaseResponse<NULLBody> response = new BaseResponse<NULLBody>();
        response.setCode(StatusEnum.FAIL.getCode());
        if (e instanceof RuntimeException){
            response.setMessage(e.getMessage());
        } else {
            response.setMessage(StatusEnum.FAIL.getMessage());
        }
        return response ;
    }
}


这样当controller层出现异常之后都会进入这里进行统一的返回。


总结


至此整个插件的流程已经全部OK,从中可以看出Spring AOP在实际开发中的各种好处。


之前的几篇文章也有应用到:




不知不觉这个小白入门的SSM系列已经更新了14篇了,在GitHub也有了500多颗星了,期间也和不少朋友有过交流、探讨,感谢大家的支持。


接下来可能不太会更新这个系列了,由于博主现在所在的项目组采用的是目前比较流行的SpringBoot+SpringCloudDocker的方式来进行架构的,所以之后的重心肯定会移到这方面,用过SpringBoot之后相信大家肯定也回不去了。


所以之后我会继续更新SpringBoot+SpringCloud相关的文章,欢迎持续关注,持续拍砖(ps:这个插件也会用springBoot重写一遍)


插件地址:github.com/crossoverJi…

项目地址:github.com/crossoverJi…

个人博客地址:crossoverjie.top



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
Shell Python
`pytest-httpserver`是一个pytest插件,它允许你在测试期间启动一个轻量级的HTTP服务器,并模拟HTTP请求和响应。
`pytest-httpserver`是一个pytest插件,它允许你在测试期间启动一个轻量级的HTTP服务器,并模拟HTTP请求和响应。
UE Http Server 插件说明
UE Http Server 插件说明
372 0
|
XML JSON JavaScript
UE4 HTTP 请求插件说明(DTHttpRequest)
UE4 HTTP 请求插件说明(DTHttpRequest)
419 0
|
测试技术
JMeter http(s)请求插件jmeter-plugin-httpBinaryFileUpload.jar
JMeter http(s)请求插件jmeter-plugin-httpBinaryFileUpload.jar
126 0
|
SQL Web App开发 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
在运行一个group by的sql时,抛出以下错误信息: Task with the most failures(4):  -----Task ID:  task_201411191723_723592_m_000004URL:  http://DDS0204.
968 0

热门文章

最新文章