springBoot 过滤器去除请求参数前后空格实例详解

 更新时间:2022年11月28日 11:34:06   作者:雨点的名字  
这篇文章主要为大家介绍了springBoot 过滤器去除请求参数前后空格实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

背景

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

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

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

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

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

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

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

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

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

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

  • Get请求,请求参数放到url后面
  • Post请求 请求参数放到url后面
  • Post请求 请求参数放到body里面

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

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

一、实现代码

1、注册过滤器

/**
 *  通过FilterRegistrationBean注册自定义过滤器TrimFilter
 */
@Configuration
public class FilterConfig {
    /**
     * 注册去除参数头尾空格过滤器
     */
    @Bean
    public FilterRegistrationBean trimFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setDispatcherTypes(DispatcherType.REQUEST);
        //注册自定义过滤器
        registration.setFilter(new TrimFilter());
        //过滤所有路径
        registration.addUrlPatterns("/*");
        //过滤器名称
        registration.setName("trimFilter");
        //优先级越低越优先,这里说明最低优先级
        registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
        return registration;
    }
}

2、自定义过滤器TrimFilter

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

3、自定义TrimRequestWrapper类

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

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

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

/**
 * 自定义TrimRequestWrapper类
 */
@Slf4j
public class TrimRequestWrapper extends HttpServletRequestWrapper {
    /**
     * 保存处理后的参数
     */
    private Map<String, String[]> params = new HashMap<String, String[]>();
    public TrimRequestWrapper(HttpServletRequest request) {
        //将request交给父类,以便于调用对应方法的时候,将其输出
        super(request);
        //对于非json请求的参数进行处理
        if (super.getHeader(HttpHeaders.CONTENT_TYPE) == null ||
                (!super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE) &&
                        !super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_UTF8_VALUE))) {
            setParams(request);
        }
    }
    private void setParams(HttpServletRequest request) {
        //将请求的的参数转换为map集合
        Map<String, String[]> requestMap = request.getParameterMap();
        log.info("kv转化前参数:" + JSON.toJSONString(requestMap));
        this.params.putAll(requestMap);
        //去空操作
        this.modifyParameterValues();
        log.info("kv转化后参数:" + JSON.toJSONString(params));
    }
    /**
     * 将parameter的值去除空格后重写回去
     */
    public void modifyParameterValues() {
        Set<String> set = params.keySet();
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String key = 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
     */
    @Override
    public String[] getParameterValues(String name) {
        return params.get(name);
    }
    /**
     * 重写getInputStream方法  post类型的请求参数必须通过流才能获取到值
     * 这种获取的参数的方式针对于内容类型为文本类型,比如Content-Type:text/plain,application/json,text/html等
     * 在springmvc中可以使用@RequestBody 来获取 json数据类型
     * 其他文本类型不做处理,重点处理json数据格式
     * getInputStream() ,只有当方法为post请求,且参数为json格式是,会被默认调用
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {
        //
        if (!super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE) &&
                !super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_UTF8_VALUE)) {
            //如果参数不是json格式则直接返回
            return super.getInputStream();
        }
        //为空,直接返回
        String json = IOUtils.toString(super.getInputStream(), "utf-8");
        if (StringUtils.isEmpty(json)) {
            return super.getInputStream();
        }
        log.info("json转化前参数:" + json);
        //json字符串首尾去空格
        JSONObject jsonObject = StringJsonUtils.JsonStrTrim(json);
        log.info("json转化后参数:" + jsonObject.toJSONString());
        ByteArrayInputStream bis = new ByteArrayInputStream(jsonObject.toJSONString().getBytes("utf-8"));
        return new MyServletInputStream(bis);
    }
}

二、测试

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

/**
 * 测试接口
 *
 * @author xub
 * @date 2022/10/24 下午5:06
 */
@Slf4j
@RestController
public class ParamController {
    /**
     * 1、Get请求测试首尾去空格
     */
    @GetMapping(value = "/getTrim")
    public String getTrim(@RequestParam String username, @RequestParam String phone) {
        return username + "&" + phone;
    }
    /**
     * 2、Post方法测试首尾去空格
     */
    @PostMapping(value = "/postTrim")
    public String postTrim(@RequestParam String username, @RequestParam String phone) {
        return username + "&" + phone;
    }
    /**
     * 3、post方法 json入参 测试首尾去空格
     */
    @PostMapping(value = "/postJsonTrim")
    public String helloUser(@RequestBody UserDO userDO) {
        return JSONObject.toJSONString(userDO);
    }
}

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

请求url

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

后台输出日志

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

接口返回

张三&18812345678

说明首尾去空格成功!

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

请求url

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

后台输出日志

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

接口返回

张三&18812345678

说明首尾去空格成功!

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

请求url

http://127.0.0.1:8080/postJsonTrim

请求参数和返回参数

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

后台输出日志

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

说明首尾去空格成功!

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

以上就是springBoot 过滤器去除请求参数前后空格实例详解的详细内容,更多关于springBoot 过滤器去除空格的资料请关注脚本之家其它相关文章!

相关文章

  • 学习Java之自定义异常与NullPointerException的处理

    学习Java之自定义异常与NullPointerException的处理

    有时候Java自身提供的异常类并不能很好地表达我们的需求,所以这时候我们就可以自定义异常,也就是说,我们可以制造出一个自己的异常类,这样就可以抛出或捕获自己的异常了,本文就给大家详细讲讲Java自定义异常与NullPointerException的处理
    2023-08-08
  • 微信支付java版本之获取Access_token

    微信支付java版本之获取Access_token

    这篇文章主要介绍了微信支付java版本之获取Access_token,java如何获取Access_token,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • Java HttpClient用法的示例详解

    Java HttpClient用法的示例详解

    Java开发语言中实现HTTP请求的方法主要有两种:一种是JAVA的标准类HttpUrlConnection;另一种是第三方开源框架HTTPClient。本文就将详细讲讲Java中HttpClient的使用,需要的可以参考一下
    2022-07-07
  • java类实现日期的时间差的实例讲解

    java类实现日期的时间差的实例讲解

    在本篇文章里小编给大家整理的是一篇关于java类实现日期的时间差的实例讲解内容,有兴趣的朋友们可以学习下。
    2021-01-01
  • MyBatis学习教程(八)-Mybatis3.x与Spring4.x整合图文详解

    MyBatis学习教程(八)-Mybatis3.x与Spring4.x整合图文详解

    这篇文章主要介绍了MyBatis学习教程(八)-Mybatis3.x与Spring4.x整合图文详解的相关资料,需要的朋友可以参考下
    2016-05-05
  • 基于springmvc之常用注解,操作传入参数

    基于springmvc之常用注解,操作传入参数

    这篇文章主要介绍了springmvc之常用注解,操作传入参数方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • 关于spring data jpa一级缓存的问题

    关于spring data jpa一级缓存的问题

    这篇文章主要介绍了关于spring data jpa一级缓存的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Java 添加Word目录的2种方法示例代码详解

    Java 添加Word目录的2种方法示例代码详解

    目录是一种能够快速、有效地帮助读者了解文档或书籍主要内容的方式。这篇文章主要介绍了Java 添加Word目录的2种方法 ,需要的朋友可以参考下
    2019-06-06
  • SpringBoot框架整合Mybatis简单攻略

    SpringBoot框架整合Mybatis简单攻略

    这篇文章主要介绍了SpringBoot框架整合Mybatis的简单攻略,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2021-10-10
  • Java springboot项目jar发布过程解析

    Java springboot项目jar发布过程解析

    这篇文章主要介绍了Java springboot项目jar发布过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09

最新评论