springBoot过滤器去除请求参数前后空格

21 篇文章 1 订阅
11 篇文章 0 订阅

springBoot过滤器去除请求参数前后空格

在一个阳光明媚的早晨,客服小姐姐甜美的声音照常的响起:”昨天客户平台数千条用户充值失败,钱打到客户手中了,但是订单生成失败“

啊这…这……阳光逐渐暗淡,温馨的画面变成了黑白,甜美的声音也逐渐变的刺耳。脑子中出现了四个字【重大事故】

细细思索一番,昨天?? 近一周都没有了新版本上线,怎么昨天出现问题???? 带着满脑子问号冲向工位

在这里插入图片描述

迅速走过以下操作
  1. 不信任原则 迅速验证消息的真实性(消息属实)
  2. 查错误数据,查看数据范围,评定事故等级(还好:51条失败订单)
  3. 回复客服以及上级,说明事情已经开始处理
  4. 根据上面出错数据查询日志,定位问题
    1. 经过比对用户更改了微信参数【前面多打一个空格】
    2. 微信回调参数与数据库中保存进行比对【多一个空格必定比对不成功】
    3. 结局就是,回调失败,订单生成失败
  5. 立刻联系客户修复错误参数(保证不再扩大事故范围)
  6. 立即着手修复错误数据,保证平台运行
  7. 随后进行程序优化【即增加过滤器去除请求参数前后空格】
是时候站起来喝杯茶,客户很好说话,没有问责,没有争吵。看看窗外的天,乌云散去,阳光逐渐洒满大地,依旧是温馨和谐的日常~

在这里插入图片描述

随后,附上代码

每个SpringBoot项目增加过滤器(对外提供API的模块,web网站模块,微信小程序模块。。。)

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    /**
     * 去除参数头尾空格过滤器
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean trimFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setDispatcherTypes(DispatcherType.REQUEST);
        registration.setFilter(new TrimFilter());
        registration.addUrlPatterns("/*");
        registration.setName("TrimFilter");
        registration.setOrder(Integer.MAX_VALUE - 1);
        return registration;
    }
}

common(公共组件)中增加过滤器

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class TrimFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        filterChain.doFilter(new TrimHttpServletRequestWrapper((HttpServletRequest) servletRequest), servletResponse);
    }

    @Override
    public void destroy() {

    }
}
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class TrimHttpServletRequestWrapper extends javax.servlet.http.HttpServletRequestWrapper {

    private Map<String , String[]> params = new HashMap<>();

    public TrimHttpServletRequestWrapper(HttpServletRequest request) {
        // 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似
        super(request);
        //将参数表,赋予给当前的Map以便于持有request中的参数
        this.params.putAll(request.getParameterMap());
        this.modifyParameterValues();
    }
    /**
     * 重写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.hasLength(json)) {
            return super.getInputStream();
        }
        ByteArrayInputStream bis = new ByteArrayInputStream(JsonTrimUtils.jsonTrim(json).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= it.next();
            String[] values = params.get(key);
            for (int i = 0; i < values.length; i++) {
                values[i] = values[i].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);
    }

    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() {
            return bis.read();
        }
    }

}

工具类,去除JSON中值前后空格

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONValidator;

import java.util.Iterator;
import java.util.Map;

/**
 * json工具类
 * @Version 1.0
 */
public final class JsonTrimUtils {
    /**
     * 构造器
     */
    private JsonTrimUtils() {
    }
 
    /**
     * 去除json值前后空格
     * @param jsonStr jsonStr
     * @return
     */
    public static JSON jsonTrim(String jsonStr) throws Exception {
        if (JSONValidator.from(jsonStr).getType() == JSONValidator.Type.Object) {
            return  jsonTrim(JSONObject.parseObject(jsonStr));
        } else if (JSONValidator.from(jsonStr).getType() == JSONValidator.Type.Array) {
            JSONArray array = JSONArray.parseArray(jsonStr);
            jsonTrimArray(array);
            return array;
        }
        //前后端联调传值类型不同,及早的暴露问题,避免隐藏问题。
        throw new Exception("非JSON参数");
    }
 
    /**
     * 去除json值前后空格
     * @param json jsonStr
     * @return
     */
    public static JSON jsonTrim(JSON json) throws Exception {
        if (json instanceof JSONObject) {
            return  jsonTrim(json);
        } else if (json instanceof JSONArray) {
            jsonTrimArray((JSONArray) json);
            return json;
        }
        throw new Exception("非JSON参数");
    }
 
    /**
     * 去除value的空格
     *
     * @param jsonObject jsonObject
     * @return
     */
    public static JSONObject jsonTrim(JSONObject jsonObject) {
        Iterator<Map.Entry<String, Object>> iterator = jsonObject.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> next = iterator.next();
            Object value = next.getValue();
            if (value != null) {
                if (value instanceof String) {
                    //清空值前后空格
                    jsonObject.put(next.getKey(), ((String) value).trim());
                } else if (value instanceof JSONObject) {
                    jsonTrim((JSONObject) value);
                } else if (value instanceof JSONArray) {
                    jsonTrimArray((JSONArray) value);
                }
            }
        }
 
        return jsonObject;
    }
 
    /**
     * 清空JSONArray 值前后空格
     * @param array
     */
    private static void jsonTrimArray(JSONArray array) {
        if (array.size() > 0) {
            for (int i = 0; i < array.size(); i++) {
                Object object = array.get(i);
                if (object != null) {
                    if (object instanceof String) {
                        array.set(i, ((String) object).trim());
                    } else if (object instanceof JSONObject) {
                        jsonTrim((JSONObject) object);
                    } else if (object instanceof JSONArray) {
                        jsonTrimArray((JSONArray) object);
                    }
                }
            }
        }
    }
}

JSON 的支持使用的JAR

<!-- Json解析 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.69_sec11</version>
</dependency>

在这里插入图片描述

在此就全部搞定了,有需要的复制即可使用,有用就关注一下吧
  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
可以通过自定义一个过滤器实现对所有请求参数清除前后空格的操作。以下是实现方式: 1. 创建一个类,继承 `OncePerRequestFilter` 类,重写 `doFilterInternal` 方法,该方法用于拦截请求并处理请求参数。 ```java import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class TrimRequestParamsFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 获取所有请求参数名 Enumeration<String> paramNames = request.getParameterNames(); // 遍历请求参数并清除前后空格 while (paramNames.hasMoreElements()) { String paramName = paramNames.nextElement(); String[] paramValues = request.getParameterValues(paramName); for (int i = 0; i < paramValues.length; i++) { paramValues[i] = paramValues[i].trim(); } request.setAttribute(paramName, paramValues); } filterChain.doFilter(request, response); } } ``` 2. 在Spring Boot项目中注册该过滤器。 ```java import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FilterConfig { @Bean public FilterRegistrationBean<TrimRequestParamsFilter> trimRequestParamsFilter() { FilterRegistrationBean<TrimRequestParamsFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new TrimRequestParamsFilter()); // 设置过滤器的执行顺序,数字越小越先执行 registrationBean.setOrder(1); // 设置需要过滤的请求路径 registrationBean.addUrlPatterns("/*"); return registrationBean; } } ``` 该配置文件中创建了一个名为 `trimRequestParamsFilter` 的过滤器,并设置需要过滤的请求路径为 "/*",表示对所有请求进行参数清除操作。最后通过 `setOrder` 方法设置过滤器的执行顺序,数字越小越先执行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值