SpringBoot使用过滤器过滤参数中的空格

前言

最近项目中需要对前台提交的参数进行去空格,这种事本来应该前台做,但是我想如果前台做的话,所有input框都得进行trim代价太大,我就想着后台可不可以对提交的参数进行去空格,查了一下,可以使用过滤器进行实现。

代码

过滤器

import org.springframework.stereotype.Component;

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

@Component
@WebFilter(urlPatterns = "/**", filterName = "ParamFilter", dispatcherTypes = DispatcherType.REQUEST)
public class ParamFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

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

    @Override
    public void destroy() {

    }
}
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class ParameterRequestWrapper extends HttpServletRequestWrapper {
    private Map<String, String[]> params = new HashMap<>();

    public ParameterRequestWrapper(HttpServletRequest request) {
        super(request);
        Map<String, String[]> requestMap = request.getParameterMap();
        this.params.putAll(requestMap);
        this.modifyParameterValues();
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        if (!super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)) {
            return super.getInputStream();
        }
        String json = IoUtil.read(super.getInputStream(), "utf-8");
        if (StrUtil.isEmpty(json)) {
            return super.getInputStream();
        }
        Object o = jsonStringToMap(json);
        // 防止循环引用
        ByteArrayInputStream bis = new ByteArrayInputStream(
                JSON.toJSONString(o, SerializerFeature.DisableCircularReferenceDetect)
                        .getBytes(StandardCharsets.UTF_8));
        return new MyServletInputStream(bis);
    }

    public void modifyParameterValues() {
        Set<String> set = params.keySet();
        for (String key : set) {
            String[] values = params.get(key);
            for (int i = 0; i < values.length; i++) {
                values[i] = values[i].trim();
            }
            params.put(key, values);
        }
    }

    @Override
    public String getParameter(String name) {
        String[] values = params.get(name);
        if (values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }

    @Override
    public String[] getParameterValues(String name) {
        return params.get(name);
    }

    public static Object jsonStringToMap(String jsonString) {
        Map<String, Object> map = new HashMap<>();
        Object obj1 = JSONObject.parse(jsonString);
        if (obj1 instanceof JSONArray) {
            List<Map<String, Object>> list = new ArrayList<>();
            JSONArray obj11 = (JSONArray) obj1;
            for (Object o11 : obj11) {
                Map<String, Object> map1 = new HashMap<>();
                recursionTrim(map1, (JSONObject) o11);
                list.add(map1);
            }
            return list;
        }
        if (obj1 instanceof JSONObject) {
            recursionTrim(map, (JSONObject) obj1);
        }

        return map;
    }

    private static void recursionTrim(Map<String, Object> map, JSONObject o11) {
        for (String k : o11.keySet()) {
            Object o = o11.get(k);
            if (o instanceof JSONArray) {
                List<Object> list = new ArrayList<>();
                for (Object obj : (JSONArray) o) {
                    if (obj instanceof JSONObject) {
                        list.add(jsonStringToMap(obj.toString()));
                    } else if (obj instanceof String) {
                        list.add(obj.toString().trim());
                    } else {
                        list.add(obj);
                    }
                }
                map.put(k, list);
            } else if (o instanceof JSONObject) {
                map.put(k, jsonStringToMap(o.toString()));
            } else {
                if (o instanceof String) {
                    map.put(k, o.toString().trim());
                } else {
                    map.put(k, o);
                }
            }
        }
    }

    static 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();
        }
    }
}

问题

当然这也是我从其他人的博文里抄来的,一开始发现get请求过滤成功了,我猜想可能参数列表是基本类型的他能过滤成功,但是post请求过滤失败了,但是我从swagger调的时候却没有任何问题,我和同事一起打断点,最后他看到了关键的一行代码

super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)

我的请求头类型是:application/json;charset=utf-8
所以这里如果post过滤失败的话,建议打断点看看是不是请求头那里判断出了问题。

传送门

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以通过自定义过滤器来实现参数前后端空格过滤。具体实现步骤如下: 1. 创建一个自定义的过滤器类,实现javax.servlet.Filter接口。 2. 在过滤器重写doFilter方法,在该方法参数进行空格过滤处理。 3. 在SpringBoot的配置类添加一个FilterRegistrationBean注册过滤器,并设置过滤器的优先级。 下面是一个示例代码: ```java @Component public class SpaceFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; Map<String, String[]> parameterMap = req.getParameterMap(); for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) { String[] values = entry.getValue(); for (int i = 0; i < values.length; i++) { values[i] = values[i].trim(); } entry.setValue(values); } chain.doFilter(request, response); } } @Configuration public class WebConfig { @Bean public FilterRegistrationBean<SpaceFilter> spaceFilter() { FilterRegistrationBean<SpaceFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new SpaceFilter()); registrationBean.addUrlPatterns("/*"); registrationBean.setName("SpaceFilter"); registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE); return registrationBean; } } ``` 在上面的示例,我们通过SpaceFilter类对所有请求的参数进行了空格过滤处理,并将该过滤器设置为最高优先级,确保所有请求都会经过该过滤器

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值