• Filter拦截过滤参数


     来自连接SpringBoot过滤器(过滤请求参数) - 简书

    获取http参数有两种方式,一种通过request.getParameter获取Get方式传递的参数,另外一种是通过request.getInputStream或reques.getReader获取通过POST/PUT/DELETE/PATCH传递的参数;

    • @PathVariable注解是REST风格url获取参数的方式,只能用在GET请求类型,通过getParameter获取参数
    • @RequestParam注解支持GET和POST/PUT/DELETE/PATCH方式,Get方式通过getParameter获取参数和post方式通过getInputStream或getReader获取参数
    • @RequestBody注解支持POST/PUT/DELETE/PATCH,可以通过getInputStream和getReader获取参数
    • HttpServletRequest参数可以通过getParameter和getInputStream或getReader获取参数

    上述通过getInputStream或getReader在拦截器中获取会导致控制器拿到的参数为空,这是因为流读取一次之后流的标志位已经发生了变化,无法多次读取参数;

    通过HttpServletRequestWrapper包装类每次读取参数后再回写参数

    1. 创建ParamsFilter实现Filter接口

    1. package com.example.filter;
    2. import javax.servlet.*;
    3. import javax.servlet.http.HttpServletRequest;
    4. import java.io.IOException;
    5. /**
    6. *
    7. * @description: 请求参数过滤器
    8. *
    9. */
    10. public class ParamsFilter implements Filter {
    11. @Override
    12. public void init(FilterConfig filterConfig) throws ServletException {
    13. }
    14. @Override
    15. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    16. HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
    17. ParamsRequestWrapper requestWrapper = new ParamsRequestWrapper(httpRequest);
    18. filterChain.doFilter(requestWrapper, servletResponse);
    19. }
    20. @Override
    21. public void destroy() {
    22. }
    23. }
    1. 过滤请求参数

      1. package com.example.filter;
      2. import com.alibaba.fastjson.JSON;
      3. import org.apache.commons.io.IOUtils;
      4. import org.apache.commons.lang3.StringUtils;
      5. import org.springframework.http.HttpHeaders;
      6. import org.springframework.http.MediaType;
      7. import javax.servlet.ServletInputStream;
      8. import javax.servlet.http.HttpServletRequest;
      9. import javax.servlet.http.HttpServletRequestWrapper;
      10. import java.io.ByteArrayInputStream;
      11. import java.io.IOException;
      12. import java.util.HashMap;
      13. import java.util.Iterator;
      14. import java.util.Map;
      15. import java.util.Set;
      16. /**
      17. *
      18. * @description: 对请求参数进行过滤
      19. *
      20. */
      21. public class ParamsRequestWrapper extends HttpServletRequestWrapper {
      22. private Map params = new HashMap<>();
      23. private static final String ENCODING = "UTF-8";
      24. private static final String CLASSTYPE = "java.lang.String";
      25. public ParamsRequestWrapper(HttpServletRequest request) {
      26. super(request);
      27. // 将参数表,赋予给当前的Map以便于持有request中的参数
      28. Map requestMap = request.getParameterMap();
      29. System.out.println("转化前参数:" + JSON.toJSONString(requestMap));
      30. this.params.putAll(requestMap);
      31. this.modifyParameters();
      32. System.out.println("转化后参数:" + JSON.toJSONString(params));
      33. }
      34. /**
      35. * 重写getInputStream方法 post请求参数必须通过流才能获取到值
      36. */
      37. @Override
      38. public ServletInputStream getInputStream() throws IOException {
      39. ServletInputStream stream = super.getInputStream();
      40. //非json类型,直接返回
      41. if (!super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)) {
      42. return stream;
      43. }
      44. String json = IOUtils.toString(stream, ENCODING);
      45. if (StringUtils.isBlank(json)) {
      46. return stream;
      47. }
      48. System.out.println("转化前参数:" + json);
      49. Map map = modifyParams(json);
      50. System.out.println("转化后参数:" + JSON.toJSONString(map));
      51. ByteArrayInputStream bis = new ByteArrayInputStream(JSON.toJSONString(map).getBytes(ENCODING));
      52. return new ParamsServletInputStream(bis);
      53. }
      54. private static Map modifyParams(String json) {
      55. Map params = JSON.parseObject(json);
      56. Map maps = new HashMap<>(params.size());
      57. for (String key : params.keySet()) {
      58. Object value = getValue(params.get(key));
      59. maps.put(key, value);
      60. }
      61. return maps;
      62. }
      63. private static Object getValue(Object obj) {
      64. if (obj == null) {
      65. return null;
      66. }
      67. String type = obj.getClass().getName();
      68. // 对字符串的处理
      69. if (CLASSTYPE.equals(type)) {
      70. obj = obj.toString().trim();
      71. }
      72. return obj;
      73. }
      74. /**
      75. * 将parameter的值去除空格后重写回去
      76. */
      77. private void modifyParameters() {
      78. Set set = params.keySet();
      79. Iterator it = set.iterator();
      80. while (it.hasNext()) {
      81. String key = (String) it.next();
      82. String[] values = params.get(key);
      83. values[0] = values[0].trim();
      84. params.put(key, values);
      85. }
      86. }
      87. /**
      88. * 重写getParameter 参数从当前类中的map获取
      89. */
      90. @Override
      91. public String getParameter(String name) {
      92. String[] values = params.get(name);
      93. if (values == null || values.length == 0) {
      94. return null;
      95. }
      96. return values[0];
      97. }
      98. }

    2. 字节数据转换流(Map → ByteArrayInputStream → ServletInputStream )

    1. package com.example.filter;
    2. import javax.servlet.ReadListener;
    3. import javax.servlet.ServletInputStream;
    4. import java.io.ByteArrayInputStream;
    5. import java.io.IOException;
    6. /**
    7. *
    8. * @description: 请求参数输入流
    9. *
    10. */
    11. public class ParamsServletInputStream extends ServletInputStream {
    12. private ByteArrayInputStream bis;
    13. public ParamsServletInputStream(ByteArrayInputStream bis) {
    14. this.bis = bis;
    15. }
    16. @Override
    17. public boolean isFinished() {
    18. return true;
    19. }
    20. @Override
    21. public boolean isReady() {
    22. return true;
    23. }
    24. @Override
    25. public void setReadListener(ReadListener readListener) {
    26. }
    27. @Override
    28. public int read() throws IOException {
    29. return bis.read();
    30. }
    31. }
    1. 过滤器配置类
    1. package com.example.config;
    2. import com.example.filter.ParamsFilter;
    3. import org.springframework.boot.web.servlet.FilterRegistrationBean;
    4. import org.springframework.context.annotation.Bean;
    5. import org.springframework.context.annotation.Configuration;
    6. import javax.servlet.DispatcherType;
    7. /**
    8. * @description: 过滤器配置类
    9. */
    10. @Configuration
    11. public class FilterConfig {
    12. @Bean
    13. public FilterRegistrationBean parmsFilterRegistration() {
    14. FilterRegistrationBean registration = new FilterRegistrationBean();
    15. registration.setDispatcherTypes(DispatcherType.REQUEST);
    16. registration.setFilter(new ParamsFilter());
    17. registration.addUrlPatterns("/*");
    18. registration.setName("ParamsFilter");
    19. registration.setOrder(Integer.MAX_VALUE - 1);
    20. return registration;
    21. }
    22. }

    过滤器过滤的请求为所有请求(/*),排除部分请求

     

    1. 在配置类中添加不需要过滤的请求的url

     

    1. package com.example.config;
    2. import com.example.filter.ParamsFilter;
    3. import org.apache.commons.lang3.StringUtils;
    4. import org.springframework.boot.web.servlet.FilterRegistrationBean;
    5. import org.springframework.context.annotation.Bean;
    6. import org.springframework.context.annotation.Configuration;
    7. import javax.servlet.DispatcherType;
    8. import java.util.HashSet;
    9. import java.util.Set;
    10. /**
    11. * @description: 过滤器配置类
    12. */
    13. @Configuration
    14. public class FilterConfig {
    15. @Bean
    16. public FilterRegistrationBean parmsFilterRegistration() {
    17. FilterRegistrationBean registration = new FilterRegistrationBean();
    18. registration.setDispatcherTypes(DispatcherType.REQUEST);
    19. registration.setFilter(new ParamsFilter());
    20. registration.addUrlPatterns("/*");
    21. // 排除不需要过滤的请求
    22. Set set = new HashSet<>();
    23. set.add("/hello");
    24. set.add("/testFilter");
    25. String urls = StringUtils.join(set.toArray(), ",");
    26. registration.addInitParameter("exclusions", urls);
    27. registration.setName("ParamsFilter");
    28. registration.setOrder(Integer.MAX_VALUE - 1);
    29. return registration;
    30. }
    31. }
    1. package com.example.filter;
    2. import javax.servlet.*;
    3. import javax.servlet.http.HttpServletRequest;
    4. import java.io.IOException;
    5. import java.util.Arrays;
    6. import java.util.HashSet;
    7. import java.util.Set;
    8. /**
    9. * @description: 请求参数过滤器
    10. */
    11. public class ParamsFilter implements Filter {
    12. public static final String PARAM_NAME_EXCLUSIONS = "exclusions";
    13. public static final String SEPARATOR = ",";
    14. private Set excludesUrls;
    15. @Override
    16. public void init(FilterConfig filterConfig) throws ServletException {
    17. String param = filterConfig.getInitParameter(PARAM_NAME_EXCLUSIONS);
    18. if (param != null && param.trim().length() != 0) {
    19. this.excludesUrls = new HashSet(Arrays.asList(param.split(SEPARATOR)));
    20. }
    21. }
    22. @Override
    23. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    24. HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
    25. String requestURI = httpRequest.getRequestURI();
    26. if (this.isExclusion(requestURI)) {
    27. // 不过滤
    28. filterChain.doFilter(servletRequest, servletResponse);
    29. } else {
    30. // 过滤
    31. ParamsRequestWrapper requestWrapper = new ParamsRequestWrapper(httpRequest);
    32. filterChain.doFilter(requestWrapper, servletResponse);
    33. }
    34. }
    35. @Override
    36. public void destroy() {
    37. }
    38. public boolean isExclusion(String requestURI) {
    39. if (this.excludesUrls == null) {
    40. return false;
    41. }
    42. for (String url : this.excludesUrls) {
    43. if (url.equals(requestURI)) {
    44. return true;
    45. }
    46. }
    47. return false;
    48. }
    49. }

  • 相关阅读:
    蓝桥杯:子串分值
    stl_stack_queue的使用及OJ题
    基于Basic auth 的一个C# 示例
    产品与技术的平衡
    Vue知识系列(2)每天10个小知识点
    浅谈Kube-OVN
    目前比较好用的LabVIEW架构及其选择
    2022-08-08 学习日记(28th day)Stream流
    曾仕强老师视频+音频+电子书合集百度网盘资源
    [附源码]计算机毕业设计疫情防控平台Springboot程序
  • 原文地址:https://blog.csdn.net/yuzheh521/article/details/128019264