springboot拦截器配置、消息头校验、重复请求过滤
时间:2019-12-26
本文章向大家介绍springboot拦截器配置、消息头校验、重复请求过滤,主要包括springboot拦截器配置、消息头校验、重复请求过滤使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一个一个来,按spring boot的风格,我们不喜欢xml文件,所以使用java类来启用拦截器配置:
import com.wlf.order.prize.aop.RequestInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class InterceptorConfig implements WebMvcConfigurer { public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/**"). excludePathPatterns("/jpservice/getSign", "/jpservice/getTimeStamp"); } }
上面我们拦截了所有的web请求,除了这两个接口:"/jpservice/getSign", "/jpservice/getTimeStamp"
接着我们进入拦截器里,做消息头校验、重复请求校验:
import com.wlf.order.prize.javabean.Result; import com.wlf.order.prize.util.BeanConvert; import com.wlf.order.prize.util.IPUtil; import com.wlf.order.prize.util.ThreadLocalUtil; import com.wlf.order.prize.util.TimeStampList; import lombok.extern.slf4j.Slf4j; import org.springframework.lang.Nullable; import org.springframework.stereotype.Component; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * 拦截器:增加重复请求的过滤、话单记录处理 * * @author wulinfeng * @since 2019/12/25 */ @Slf4j @Component public class RequestInterceptor extends HandlerInterceptorAdapter { private final static SimpleDateFormat SF = new SimpleDateFormat("yyyyMMddHHmmss"); // 话单格式:记录时间|接口名称|接口时延|调用方IP|本地IP|业务参数|结果码|序列号 private final static String CDR_FORMAT = "{}|{}|{}|{}|{}|{}|{}|{}"; // 时间戳缓存 private final static TimeStampList cache = new TimeStampList(10000); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 请求头校验 String timestamp = request.getHeader("timestamp"); String sign = request.getHeader("sign"); if (timestamp == null || timestamp.trim().equals("") || sign == null || sign.trim().equals("")) { Result result = new Result(1025, "请求头缺失."); getResponse(result, response); return false; } // 时间戳校验 if (timestamp.length() != 13) { Result result = new Result(1026, "时间戳格式错误."); getResponse(result, response); return false; } Long requestTime = null; try { requestTime = Long.parseLong(timestamp); } catch (NumberFormatException e) { Result result = new Result(1026, "时间戳格式错误."); getResponse(result, response); return false; } // 重复请求校验 if (cache.contains(requestTime)) { Result result = new Result(1027, "重复请求."); getResponse(result, response); return false; } cache.add(requestTime); // 获取请求和本地IP,记录话单 String beginTime = String.valueOf(System.currentTimeMillis()); String remoteIp = IPUtil.getRemoteIp(request); String localIp = IPUtil.getLocalIp(); Map<String, String> strMap = new HashMap<>(); strMap.put("beginTime", beginTime); strMap.put("remoteIp", remoteIp); strMap.put("localIp", localIp); strMap.put("sequence", timestamp); ThreadLocalUtil.setMap(strMap); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { // 计算接口时延 Map<String, String> strMap = ThreadLocalUtil.getMap(); long beginTime = Long.parseLong(strMap.get("beginTime")); long currentTime = System.currentTimeMillis(); // 获取当前时间 String currentDate = SF.format(new Date(currentTime)); // 记录话单 log.error(CDR_FORMAT, currentDate, strMap.get("apiType"), currentTime - beginTime, strMap.get("remoteIp"), strMap.get("localIp"), strMap.get("sequence"), strMap.get("biz"), strMap.get("resultCode")); } /** * 构造响应消息体 * * @param result * @param response * @throws IOException */ private void getResponse(Result result, HttpServletResponse response) throws IOException { response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); PrintWriter out = null; out = response.getWriter(); out.write(BeanConvert.getResultJson(result)); out.flush(); out.close(); } }
原文地址:https://www.cnblogs.com/wuxun1997/p/12102299.html
- spring-data-mongodb之查询操作
- spring mvc开发的mongodb网页版客户端
- nginx转发后后端怎么获取用户真实IP
- MongoDB aggregation $unwind
- spring data mongodb 代码连接数据库方式
- spring data mongodb dbref 关联查询
- spring-data-mongodb mapreduce使用
- 项目中如何设计通用的评论模块
- java8 stream
- spring boot中自定义错误提示页面
- spring boot中删除Data MongoDB的_class
- 用aop加redis实现通用接口缓存
- spring boot 实现mysql读写分离
- spring boot集成druid连接池
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 【STM32F407开发板用户手册】第33章 STM32F407的SPI总线应用之驱动DAC8563
- Salesforce LWC学习(二十) CLI篇:新版本不支持Audience解决方案
- 【STM32F429开发板用户手册】第33章 STM32F429的SPI总线应用之驱动DAC8563
- ELK学习笔记之filbeat pod无法将容器日志发送
- 小学生看了都会的Apache配置虚拟主机教程
- 【STM32F407开发板用户手册】第34章 STM32F407的SPI总线应用之驱动DAC8501
- 学长冷月带你怒刷LeetCode之反转链表
- php面试笔记-php基础知识-变量和引用变量
- 【STM32F429开发板用户手册】第34章 STM32F429的SPI总线应用之驱动DAC8501
- docker 安装mysql5.7
- php面试笔记(5)-php基础知识-自定义函数及内部函数考点
- AJAX的一个简单实例,跨域的解决,使用JQuery来进行ajax的调用
- ASP.NET Core 将文件夹内容输出为压缩包文件方法
- 如何阻止指定类型的SAP CRM附件被上传到服务器
- Docker 之NameSpace与Cgroup