zoukankan      html  css  js  c++  java
  • 使用SpringBoot使用过滤器去除@RequestBody参数两端的空格

    使用SpringBoot使用过滤器去除@RequestBody参数两端的空格

    使用SpringBoot使用过滤器去除@RequestBody参数两端的空格;一般我们去普通的请求我们都会对请求参数进行验证。Java也提供了@notNull和@notBlank这种验证方式,但是对@RequestBody 这种只能验证是不是非空,对数据两端的空格未进行处理,同时大家也不想遍历一遍参数然后再处理再封装到对象中,正好项目中有这个需要,所以就参考别的做了Post请求中针对application/json格式的有@RequestBody注解的参数进行了去空格处理

    协议:CC BY-SA 4.0 https://creativecommons.org/licenses/by-sa/4.0/

    版权声明:本文为原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

    第一步:编写一个配置信息

    ParamsFilterConfig.java

    package com.codepeople.framework.config;
    
    import javax.servlet.DispatcherType;
    
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import com.ruoyi.framework.filter.ParamsFilter;
    
    /**
     * @ClassName: ParamsFilterConfig
     * @Description: SpringBoot中去除@RequestBody中前后端空格
     * @Author 刘 仁
     * @DateTime 2020-7-23 10:07:02
     */
    @Configuration
    public class ParamsFilterConfig {
    
    	@Bean
    	public FilterRegistrationBean paramsFilterRegistration() {
    		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;
    	}
    }
    

    第二步:编写ParamsFilter过滤器

    ParamsFilter.java

    package com.codepeople.framework.filter;
    
    import java.io.IOException;
    
    import javax.servlet.DispatcherType;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.stereotype.Component;
    
    @Component
    @WebFilter(urlPatterns = "/**", filterName = "ParamsFilter", dispatcherTypes = DispatcherType.REQUEST)
    public class ParamsFilter implements Filter {
    
    	@Override
    	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    			throws IOException, ServletException {
    		ParameterRequestWrapper parmsRequest = new ParameterRequestWrapper((HttpServletRequest) request);
    		chain.doFilter(parmsRequest, response);
    	}
    
    	@Override
    	public void init(FilterConfig filterConfig) throws ServletException {
    		
    	}
    
    	@Override
    	public void destroy() {
    		
    	}
    
    	
    }
    

    第三步:实现ParameterRequestWrapper

    ParameterRequestWrapper.java

    package com.codepeople.framework.filter;
    
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    
    import javax.servlet.ReadListener;
    import javax.servlet.ServletInputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    import org.apache.commons.io.IOUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.MediaType;
    
    import com.alibaba.fastjson.JSON;
    import com.codepeople.framework.util.StringJsonUtils;
    
    public class ParameterRequestWrapper extends HttpServletRequestWrapper {
    
    	private Map<String , String[]> params = new HashMap<>();
    	
    	public ParameterRequestWrapper(HttpServletRequest request) {
    		// 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似
            super(request);
            //将参数表,赋予给当前的Map以便于持有request中的参数
            Map<String, String[]> requestMap=request.getParameterMap();
            this.params.putAll(requestMap);
            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.isEmpty(json)) {
                return super.getInputStream();
            }
            System.out.println("去除POST请求数据两端的空格前参数:"+json);
            Map<String,Object> map= StringJsonUtils.jsonStringToMap(json);
            System.out.println("去除POST请求数据两端的空格后参数:"+JSON.toJSONString(map));
            ByteArrayInputStream bis = new ByteArrayInputStream(JSON.toJSONString(map).getBytes("utf-8"));
            return new MyServletInputStream(bis);
        }
    
    	/**
    	 * @Title: modifyParameterValues
    	 * @Description:  将parameter的值去除空格后重写回去
    	 * @DateTime 2020-7-23 10:31:12
    	 */
        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);
            }
        }
        
        @Override
        public String getParameter(String name) {
            String[]values = params.get(name);
            if(values == null || values.length == 0) {
                return null;
            }
            return values[0];
        }
        /**
    	 * @Title: getParameterValues
    	 * @Description:  重写getParameterValues
    	 * @DateTime 2020-7-23 10:31:12
    	 */
        @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();
            }
        }
    
    }
    

    第四步:利用fastjson实现json字符串转map功能

    package com.codepeople.framework.util;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    /**
     * @ClassName: StringJsonUtils
     * @Description: 
     * @Author 刘 仁
     * @DateTime 2020-7-23 10:26:28
     */
    public class StringJsonUtils {
    	
    	/**
    	 * @Title: jsonStringToMap
    	 * @Description: 把jsonString转为Map
    	 * @Author 刘 仁
    	 * @DateTime 2020-7-23 10:27:11
    	 * @param jsonString
    	 * @return
    	 */
    	public static Map<String, Object> jsonStringToMap(String jsonString) {
            Map<String, Object> map = new HashMap<>();
            JSONObject jsonObject = JSONObject.parseObject(jsonString);
            for (Object k : jsonObject.keySet()) {
                Object o = jsonObject.get(k);
                if (o instanceof JSONArray) {
                    List<Map<String, Object>> list = new ArrayList<>();
                    Iterator<Object> it = ((JSONArray) o).iterator();
                    while (it.hasNext()) {
                        Object obj = it.next();
                        list.add(jsonStringToMap(obj.toString()));
                    }
                    map.put(k.toString(), list);
                } else if (o instanceof JSONObject) {
                    // 如果内层是json对象的话,继续解析
                    map.put(k.toString(), jsonStringToMap(o.toString()));
                } else {
                    // 如果内层是普通对象的话,直接放入map中
                   // map.put(k.toString(), o.toString().trim()); 
                     if (o instanceof String) {
                       map.put(k.toString(), o.toString().trim());
                    } else {
                        map.put(k.toString(), o);
                    }   
                }
            }
            return map;
        }
    
    }
    

    主要引入的包

    <!--常用工具类 -->
    		<dependency>
    			<groupId>org.apache.commons</groupId>
    			<artifactId>commons-lang3</artifactId>
    		</dependency>
    <!-- 阿里JSON解析器 -->
    		<dependency>
    			<groupId>com.alibaba</groupId>
    			<artifactId>fastjson</artifactId>
    		</dependency>
    <!-- io常用工具类 -->
    		<dependency>
    			<groupId>commons-io</groupId>
    			<artifactId>commons-io</artifactId>
    		</dependency>
    <!-- servlet包 -->
            <dependency>
    		    <groupId>javax.servlet</groupId>
    		    <artifactId>javax.servlet-api</artifactId>
    		</dependency>
    

    测试日志

    11:28:07.995 [http-nio-80-exec-17] INFO  c.r.f.f.ParameterRequestWrapper - [getInputStream,54] - 去除POST请求数据两端的空格前参数:{
    	"idNumber": "110101201003073036",
    	"password": " 123456 "
    }
    11:28:07.997 [http-nio-80-exec-17] INFO  c.r.f.f.ParameterRequestWrapper - [getInputStream,56] - 去除POST请求数据两端的空格后参数:{"password":"123456","idNumber":"110101201003073036"}
    

    博客地址:https://www.codepeople.cn

    =====================================================================

    微信公众号:

  • 相关阅读:
    《Effective java》读书笔记
    Ansible playbook
    Ansible模块
    Ansible介绍与安装
    HDFS完全分布式集群搭建
    screen配置窗口显示
    K8s下部署Istio
    使用RKE快速部署k8s集群
    Oracle批量创建同义词
    k8s基本概念
  • 原文地址:https://www.cnblogs.com/lr393993507/p/13367765.html
Copyright © 2011-2022 走看看