经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring Boot » 查看文章
springBoot 过滤器去除请求参数前后空格(附源码)
来源:cnblogs  作者:雨点的名字  时间:2022/11/28 8:57:09  对本文有异议

背景 : 用户在前端页面中不小心输入的前后空格,为了防止因为前后空格原因引起业务异常,所以我们需要去除参数的前后空格!

如果我们手动去除参数前后空格,我们可以这样做

  1. @GetMapping(value = "/manualTrim")
  2. public void helloGet(String userName) {
  3. //手动去空格
  4. userName = userName == null ? null : userName.trim();
  5. //或者通过谷歌工具类手动去空格
  6. String trim = StringUtils.trim(userName);
  7. }

这种方式需要每个接口参数都进行手动的去除首尾空格,显然会让代码冗余,并不友好!所以我们应该从项目整体思考,这里通过过滤器的方式去除请求参数前后空格。

我们来看下大致实现的流程

在SpringBoot中有两种方式实现自定义Filter:

第一种是使用 @WebFilter@ServletComponentScan 组合注解。

第二种是通过配置类注入 FilterRegistrationBean对象。

通过FilterRegistrationBean对象可以通过Order属性改变顺序,使用@WebFilter注解的方式只能根据过滤器名的类名顺序执行,添加@Order注解是无效的。

既然是通过过滤器获取请求参数去除参数的首尾空格,那我们应该考虑几种情况的请求参数

  1. Get请求,请求参数放到url后面
  2. Post请求 请求参数放到url后面
  3. Post请求 请求参数放到body里面

第一种和第二种其实可以通过一种方式实现就是request.getParameter()方法。

Post中body请求参数我们可以通过使用流的方式,调用request.getInputStream()获取流,然后从流中读取参数。


一、实现代码

1、注册过滤器

  1. /**
  2. * 通过FilterRegistrationBean注册自定义过滤器TrimFilter
  3. */
  4. @Configuration
  5. public class FilterConfig {
  6. /**
  7. * 注册去除参数头尾空格过滤器
  8. */
  9. @Bean
  10. public FilterRegistrationBean trimFilterRegistration() {
  11. FilterRegistrationBean registration = new FilterRegistrationBean();
  12. registration.setDispatcherTypes(DispatcherType.REQUEST);
  13. //注册自定义过滤器
  14. registration.setFilter(new TrimFilter());
  15. //过滤所有路径
  16. registration.addUrlPatterns("/*");
  17. //过滤器名称
  18. registration.setName("trimFilter");
  19. //优先级越低越优先,这里说明最低优先级
  20. registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
  21. return registration;
  22. }
  23. }

2、自定义过滤器TrimFilter

  1. /**
  2. * 自定义过滤器 通过继承OncePerRequestFilter实现每次请求该过滤器只被执行一次
  3. */
  4. public class TrimFilter extends OncePerRequestFilter {
  5. @Override
  6. protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain)
  7. throws ServletException, IOException {
  8. //自定义TrimRequestWrapper,在这里实现参数去空
  9. TrimRequestWrapper requestWrapper = new TrimRequestWrapper(httpServletRequest);
  10. filterChain.doFilter(requestWrapper, httpServletResponse);
  11. }
  12. }

3、自定义TrimRequestWrapper类

TrimRequestWrapper类,其实也是最重要的一个类,继承HttpServletRequestWrapper重写getParameter,getParameterValues方法,getInputStream方法,前面的重写

可以解决非json的参数首尾去空格,但如果是json请求的参数那就必须重写getInputStream方法,从流中获取参数进行处理。

注意: request的输入流只能读取一次

  1. /**
  2. * 自定义TrimRequestWrapper类
  3. */
  4. @Slf4j
  5. public class TrimRequestWrapper extends HttpServletRequestWrapper {
  6. /**
  7. * 保存处理后的参数
  8. */
  9. private Map<String, String[]> params = new HashMap<String, String[]>();
  10. public TrimRequestWrapper(HttpServletRequest request) {
  11. //将request交给父类,以便于调用对应方法的时候,将其输出
  12. super(request);
  13. //对于非json请求的参数进行处理
  14. if (super.getHeader(HttpHeaders.CONTENT_TYPE) == null ||
  15. (!super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE) &&
  16. !super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_UTF8_VALUE))) {
  17. setParams(request);
  18. }
  19. }
  20. private void setParams(HttpServletRequest request) {
  21. //将请求的的参数转换为map集合
  22. Map<String, String[]> requestMap = request.getParameterMap();
  23. log.info("kv转化前参数:" + JSON.toJSONString(requestMap));
  24. this.params.putAll(requestMap);
  25. //去空操作
  26. this.modifyParameterValues();
  27. log.info("kv转化后参数:" + JSON.toJSONString(params));
  28. }
  29. /**
  30. * 将parameter的值去除空格后重写回去
  31. */
  32. public void modifyParameterValues() {
  33. Set<String> set = params.keySet();
  34. Iterator<String> it = set.iterator();
  35. while (it.hasNext()) {
  36. String key = it.next();
  37. String[] values = params.get(key);
  38. values[0] = values[0].trim();
  39. params.put(key, values);
  40. }
  41. }
  42. /**
  43. * 重写getParameter 参数从当前类中的map获取
  44. */
  45. @Override
  46. public String getParameter(String name) {
  47. String[] values = params.get(name);
  48. if (values == null || values.length == 0) {
  49. return null;
  50. }
  51. return values[0];
  52. }
  53. /**
  54. * 重写getParameterValues
  55. */
  56. @Override
  57. public String[] getParameterValues(String name) {
  58. return params.get(name);
  59. }
  60. /**
  61. * 重写getInputStream方法 post类型的请求参数必须通过流才能获取到值
  62. * 这种获取的参数的方式针对于内容类型为文本类型,比如Content-Type:text/plain,application/json,text/html等
  63. * 在springmvc中可以使用@RequestBody 来获取 json数据类型
  64. * 其他文本类型不做处理,重点处理json数据格式
  65. * getInputStream() ,只有当方法为post请求,且参数为json格式是,会被默认调用
  66. */
  67. @Override
  68. public ServletInputStream getInputStream() throws IOException {
  69. //
  70. if (!super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE) &&
  71. !super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_UTF8_VALUE)) {
  72. //如果参数不是json格式则直接返回
  73. return super.getInputStream();
  74. }
  75. //为空,直接返回
  76. String json = IOUtils.toString(super.getInputStream(), "utf-8");
  77. if (StringUtils.isEmpty(json)) {
  78. return super.getInputStream();
  79. }
  80. log.info("json转化前参数:" + json);
  81. //json字符串首尾去空格
  82. JSONObject jsonObject = StringJsonUtils.JsonStrTrim(json);
  83. log.info("json转化后参数:" + jsonObject.toJSONString());
  84. ByteArrayInputStream bis = new ByteArrayInputStream(jsonObject.toJSONString().getBytes("utf-8"));
  85. return new MyServletInputStream(bis);
  86. }
  87. }

二、测试

因为上面说了三种情况,所以这里提供了3个接口来进行测试

  1. /**
  2. * 测试接口
  3. *
  4. * @author xub
  5. * @date 2022/10/24 下午5:06
  6. */
  7. @Slf4j
  8. @RestController
  9. public class ParamController {
  10. /**
  11. * 1、Get请求测试首尾去空格
  12. */
  13. @GetMapping(value = "/getTrim")
  14. public String getTrim(@RequestParam String username, @RequestParam String phone) {
  15. return username + "&" + phone;
  16. }
  17. /**
  18. * 2、Post方法测试首尾去空格
  19. */
  20. @PostMapping(value = "/postTrim")
  21. public String postTrim(@RequestParam String username, @RequestParam String phone) {
  22. return username + "&" + phone;
  23. }
  24. /**
  25. * 3、post方法 json入参 测试首尾去空格
  26. */
  27. @PostMapping(value = "/postJsonTrim")
  28. public String helloUser(@RequestBody UserDO userDO) {
  29. return JSONObject.toJSONString(userDO);
  30. }
  31. }

1、Get请求测试首尾去空格

请求url

  1. http://localhost:8080/getTrim?username=张三 &phone= 18812345678

后台输出日志

  1. : kv转化前参数:{"username":["张三 "],"phone":[" 18812345678"]}
  2. : kv转化后参数:{"phone":["18812345678"],"username":["张三"]}

接口返回

  1. 张三&18812345678

说明首尾去空格成功!

2、Post方法测试首尾去空格

请求url

  1. http://127.0.0.1:8080/postTrim?username=张三 &phone= 18812345678

后台输出日志

  1. : kv转化前参数:{"username":["张三 "],"phone":[" 18812345678"]}
  2. : kv转化后参数:{"phone":["18812345678"],"username":["张三"]}

接口返回

  1. 张三&18812345678

说明首尾去空格成功!

3、post方法 json参数测试首尾去空格

请求url

  1. http://127.0.0.1:8080/postJsonTrim

请求参数和返回参数

注意 这个请求头为Content-Type:application/json

后台输出日志

  1. json转化前参数:{"phone":"18812345678 " ,"username":" 张三 "}
  2. json转化后参数:{"phone":"18812345678","username":"张三"}

说明首尾去空格成功!

项目示例源码: https://github.com/yudiandemingzi/spring-boot-study



声明: 公众号如需转载该篇文章,发表文章的头部一定要 告知是转至公众号: 后端元宇宙。同时也可以问本人要markdown原稿和原图片。其它情况一律禁止转载!

原文链接:https://www.cnblogs.com/qdhxhz/p/16826233.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号