SpringBoot使用Filter 过滤请求参数进行逻辑处理

    技术2022-07-11  98

    1. SpringBoot使用Filter, 过滤请求参数进行逻辑处理。 由于请求中的值 只能读取一次, 我们需要 

    继承HttpServletRequestWrapper,将请求体中的流copy一份,覆写getInputStream()和getReader()方法供外部使用。每次调用覆写后的getInputStream()方法都是从复制出来的二进制数组中进行获取,这个二进制数组在对象存在期间一直存在,这样就实现了流的重复读取。

     

    package com.test; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.Enumeration; import java.util.Map; import java.util.Vector; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import jodd.io.StreamUtil; /** * 重写 HttpServletRequestWrapper 处理json报文请求 * @author LZHH_2008 * @date 2019年8月9日 下午5:23:03 * */ public class RequestWrapper extends HttpServletRequestWrapper { private byte[] body; //用于保存读取body中数据 public RequestWrapper(HttpServletRequest request) throws IOException { super(request); //读取请求的数据保存到本类当中 body = StreamUtil.readBytes(request.getReader(), "UTF-8"); } //覆盖(重写)父类的方法 @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } //覆盖(重写)父类的方法 @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } @Override public boolean isFinished() { // TODO Auto-generated method stub return false; } @Override public boolean isReady() { // TODO Auto-generated method stub return false; } @Override public void setReadListener(ReadListener arg0) { // TODO Auto-generated method stub } }; } /** * 获取body中的数据 * @return */ public byte[] getBody() { return body; } /** * 把处理后的参数放到body里面 * @param body */ public void setBody(byte[] body) { this.body = body; } }

     

    2. doFilter方法是执行过滤的请求的核心,当客户端请求访问web资源时,这个时候我们可以拿到request里面的参数,对数据进行处理后,通过filterChain方法将请求将请求放行,放行后我们也可以通过response对响应进行处理,然后会传递到下一个过滤器

     

    package com.test; import java.io.BufferedReader; import java.io.IOException; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.kedacom.vise.vas.dto.KmediaPlayRecodLogDTO; import com.kedacom.vise.vas.dto.VideoPlayRecordDTO; import com.kedacom.vise.vas.service.KmediaPlayRecodLogService; import com.kedacom.vise.vas.service.VideoPlayRecordsService; import cn.hutool.Hutool; import cn.hutool.core.date.DateUtil; import lombok.extern.slf4j.Slf4j; /** * 过滤器,过滤的记录 * @author LZHH_2008LZHH_2008 * @time 2020年7月1日上午11:16:14 */ @Slf4j @WebFilter(urlPatterns = "/video-play/*", filterName = "videoPlayRecordFilter") // 配置过滤具体的URL public class VideoPlayRecordFilter implements Filter { private TestService testService; //获取 Spring 管理的对象, 不能使用依赖注入的方式 private TestService2 testService2; @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { System.out.println("####进入过滤器"); RequestWrapper requestWrapper = new RequestWrapper((HttpServletRequest) request); // 读取请求内容 BufferedReader br; br = requestWrapper.getReader(); String line = null; StringBuilder sb = new StringBuilder(); while ((line = br.readLine()) != null) { sb.append(line); } // 将json字符串转换为json对象 //因为我的请求是list 所以转成 JSONArray JSONArray jsonArray = JSONObject.parseArray(sb.toString()); log.info("######过滤器 插入/更新记录请求数据为:{}", jsonArray.toString()); for(int i =0 ; i < jsonArray.size(); i++){ //TODO //具体的业务逻辑 } } // 放行 filterChain.doFilter(requestWrapper, response); //TODO // 可以做请求返回的逻辑 例如,加密等 } @Override public void init(FilterConfig config) throws ServletException { ServletContext servletContext = config.getServletContext(); WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext); //获取 Spring 管理的对象 TestService = (TestService )context.getBean("testService"); TestService2 = (TestService2)context.getBean("testService2"); } }

    3. SpringBoot启动类中添加 注解: @ServletComponentScan("com.test")

     

    参考:https://blog.csdn.net/muscleheng/article/details/80067772

    Processed: 0.011, SQL: 9