需求:去除用户表单参数中由于用户不小心输入的前后空格,防止因为前后空格原因引起业务异常
实现方式一:前端参数传入的时候去除首尾空格
实现方式二:后端接收参数对参数处理,去除参数首尾空格后再做其他业务
实现方式三:利用Filter处理所有的请求,去除请求参数首尾空格重新写回
很明显实现方式一和实现方式二代码维护严重,需要对每个参数进行手动的去除首尾空格,这边主要讲实现方式三,这边实现方式用的是spring boot框架,需要对这个框架或者spring有一个简单的了解,文章后边有项目demo下载地址
1,注册过滤器
/** * 去除参数头尾空格过滤器 * @return */ @Bean public FilterRegistrationBean parmsFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setDispatcherTypes(DispatcherType.REQUEST); registration.setFilter(new ParamsFilter()); registration.addUrlPatterns("/*"); registration.setName("paramsFilter"); registration.setOrder(Integer.MAX_VALUE-1); return registration; }
2,ParamsFilter实现Filter类
public class ParamsFilter implements Filter{ @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { ParameterRequestWrapper parmsRequest = new ParameterRequestWrapper( (HttpServletRequest) arg0); arg2.doFilter(parmsRequest, arg1); } @Override public void init(FilterConfig arg0) throws ServletException { } @Override public void destroy() { } }
3,ParameterRequestWrapper类,也是本节实现最最重要的一个类,继承HttpServletRequestWrapper重写它的getParameter,getParameterValues方法,还有一个比较重要的就是必须重写getInputStream方法,因为如果请求以enctype=”application/x-www-form-urlencoded”方式提交的时候getParameterMap可以获取到表单提交的数据,而请求以enctype="multipart/form-data"方式提交的话是获取不到数据的,这个时候就必须从getInputStream流中获取,后面一种也是post常用的类型,也就是为什么用post提交请求没有参数大小的限制的原因了,具体代码如下:
public class ParameterRequestWrapper extends HttpServletRequestWrapper { private Map<String , String[]> params = new HashMap<String, String[]>(); public ParameterRequestWrapper(HttpServletRequest request) { // 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似 super(request); //将参数表,赋予给当前的Map以便于持有request中的参数 Map<String, String[]> requestMap=request.getParameterMap(); System.out.println("转化前参数:"+JSON.toJSONString(requestMap)); this.params.putAll(requestMap); this.modifyParameterValues(); System.out.println("转化后参数:"+JSON.toJSONString(params)); } /** * 重写getInputStream方法 post类型的请求参数必须通过流才能获取到值 */ @Override public ServletInputStream getInputStream() throws IOException { //非json类型,直接返回 if(!super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)){ return super.getInputStream(); } //为空,直接返回 String json = IOUtils.toString(super.getInputStream(), "utf-8"); if (StringUtils.isEmpty(json)) { return super.getInputStream(); } System.out.println("转化前参数:"+json); Map<String,Object> map=StringJsonUtils.jsonStringToMap(json); System.out.println("转化后参数:"+JSON.toJSONString(map)); ByteArrayInputStream bis = new ByteArrayInputStream(JSON.toJSONString(map).getBytes("utf-8")); return new MyServletInputStream(bis); } /** * 将parameter的值去除空格后重写回去 */ public void modifyParameterValues(){ Set<String> set =params.keySet(); Iterator<String> it=set.iterator(); while(it.hasNext()){ String key= (String) it.next(); String[] values = params.get(key); values[0] = values[0].trim(); params.put(key, values); } } /** * 重写getParameter 参数从当前类中的map获取 */ @Override public String getParameter(String name) { String[]values = params.get(name); if(values == null || values.length == 0) { return null; } return values[0]; } /** * 重写getParameterValues */ public String[] getParameterValues(String name) {//同上 return params.get(name); } class MyServletInputStream extends ServletInputStream{ private ByteArrayInputStream bis; public MyServletInputStream(ByteArrayInputStream bis){ this.bis=bis; } @Override public boolean isFinished() { return true; } @Override public boolean isReady() { return true; } @Override public void setReadListener(ReadListener listener) { } @Override public int read() throws IOException { return bis.read(); } } }
4,启动项目访问:http://localhost/test/get?userName=%20%20%20dd%20%20
结果如下图:
预留一个问题:怎么通过过滤器实现XSS攻击?
PS:本demo项目完整项目路径下载:https://github.com/zqh1989/spring/tree/master/spring-boot-filter-01
相关推荐
总结,Spring Boot的过滤器机制提供了强大的请求处理能力,开发者可以根据需求创建并配置过滤器,实现各种定制化的操作。通过合理利用过滤器,可以提升应用的安全性、性能和用户体验。在实际开发中,应根据具体场景...
Spring Boot 和 Vue.js 的前后端分离技术体系讲解.zip Spring Boot 和 Vue.js 的前后端分离技术体系讲解.zip Spring Boot 和 Vue.js 的前后端分离技术体系讲解.zip Spring Boot 和 Vue.js 的前后端分离技术体系讲解....
这本《Vue Spring Boot前后端分离开发实战》的源码提供了深入学习和实践这一技术栈的机会。以下是对其中涉及知识点的详细说明: 1. **Vue.js**:Vue.js是一个轻量级的前端JavaScript框架,以其易学易用、组件化和...
在Spring Boot框架中,过滤器(Filter)和监听器(Listener)是两个非常重要的概念,它们可以帮助我们实现一些自定义的处理逻辑,如数据校验、日志记录、请求拦截等。下面将详细讲解这两个概念及其在实际开发中的...
本demo为Spring boot整合shiro,以mybatis plus做dao层交互数据,实现了读取数据库用户数据实现用户登录,权限认证,读取数据库中用户对应的url请求,实现请求的过滤。自定义了relam和过滤器来实现这些功能
综上所述,文档《Spring Boot Vue前后端分离开发实战.pdf》涵盖了前后端分离的开发模式、Spring Boot和Vue.js的基础知识和使用、开发环境的搭建、前后端交互的实现、项目配置与启动、数据库操作、前端开发的实践等多...
Spring Boot 2.x基础教程:JSR-303实现请求参数校验 Spring Boot 2.x基础教程:Swagger接口分类与各元素排序问题详解 Spring Boot 2.x基础教程:Swagger静态文档的生成 Spring Boot 2.x基础教程:找回启动
在Spring框架中,拦截器(Interceptor)是一种强大的工具,它允许开发者在请求处理前后执行自定义逻辑,例如日志记录、权限检查等。Spring MVC中的拦截器是基于AOP(面向切面编程)原理实现的,可以理解为对...
Spring Boot和Vue.js前后端分离的技术架构.zip Spring Boot和Vue.js前后端分离的技术架构.zip Spring Boot和Vue.js前后端分离的技术架构.zip Spring Boot和Vue.js前后端分离的技术架构.zip Spring Boot和Vue.js前后...
Spring Boot是Java开发领域中的一款热门框架,它简化了基于Spring的应用程序的初始设置和配置。这个压缩包包含了丰富的Spring Boot学习资料以及实际项目案例,是深入理解和掌握Spring Boot技术的宝贵资源。 首先,...
一套基于时下最新 Java 技术栈 Spring Boot 3 + Vue 3 开发的前后端分离学习型新闻项目,配备保姆级项目开发教程手把手教你从零开始开发上线一个生产级别的 Java 系统。由新闻门户系统、作者后台管理系统、平台后台...
根据给定的文件标题“Spring Boot技术栈博客企业前后端2018”以及描述“Spring Boot技术栈博客企业前后端2018”,我们可以推断出这份资料主要围绕Spring Boot框架及其在企业级应用中的前后端开发进行讲解。...
在本文中,我们将深入探讨如何在Spring Boot应用中使用拦截器(Interceptor)和过滤器(Filter)来处理用户的登录session。这两个组件都是Spring框架的重要部分,它们在处理HTTP请求和响应时发挥着关键作用。 首先...
根据提供的文件信息,我们可以推断出这篇文档主要讨论的是与Spring Boot技术栈相关的博客内容,尤其是聚焦于企业级应用中的前后端开发。接下来,我们将基于这些有限的信息来展开相关知识点的详细阐述。 ### Spring ...
spring-boot-helloWorld:spring-boot的helloWorld版本 spring-boot-mybaits-annotation:注解版本 spring-boot-mybaits-xml:xml配置版本 spring-boot-mybatis-mulidatasource:springboot+mybatis多数据源最简解决...
在Spring Boot中,我们可以通过实现`HandlerInterceptor`接口并重写其三个方法——`preHandle()`, `postHandle()`, 和 `afterCompletion()` 来创建自定义的拦截器。 `preHandle()` 方法在目标处理方法调用之前执行...
本课程内容包括Spring简介、Spring Boot简介、安装JDK、安装Maven、第一个Spring Boot程序(使用Spring Initializr构建、Spring Boot代码讲解、安装Notepad++)、构建系统、代码、配置、三种方式运行程序、安装...
要运行第一个“Hello World”程序,你可以创建一个 `@RestController` 注解的控制器类,如 `HelloWorldController`,使用 `@RequestMapping` 映射请求。启动应用后,通过访问 `http://127.0.0.1:8080/hello` 即可...
1.24 Spring Boot过滤器、监听器 1.25 Spring Boot 拦截器HandlerInterceptor 1.26 Spring Boot启动加载数据CommandLineRunner 1.27 Spring Boot环境变量读取和属性对象的绑定 1.28 Spring Boot使用自定义的...
Spring Boot中文文档提供了详细的中文翻译和说明,包括了基本概念、使用方法、配置参数、代码示例等,可以帮助用户快速上手和深入理解Spring Boot的使用。该文档还提供了丰富的链接和参考资料,方便用户深入学习和...