springboot统一请求参数修改(可复制HttpServletRequest流)

springboot统一请求参数修改

http请求对象HttpServletRequest中的数据要么通过流(json请求时)或者参数的形式(form表单)向后台传输数据,如果是通过流的方式向后端传输数据,那么在后端读取数据都是一次性的,如果在拦截器或者AOP中读取过,则不能映射到controller的参数。但可以通过在过滤器中定义可复制的request进行读取,而不影响controller参数的映射。本文主要介绍如何通过过滤器实现可复制流来解决实际业务中遇到的相关问题。

假设这种场景:我需要将请求参数中的用户名进行解密。下述内容可以解决这个问题。

定义body请求包装类

public class BodyRequestWrapper extends HttpServletRequestWrapper {
    
    private String body;

    public BodyRequestWrapper(HttpServletRequest request, String context) {
        super(request);
        body = context;
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes("UTF-8"));
        ServletInputStream servletInputStream = new ServletInputStream() {
            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener listener) {

            }
        };
        return servletInputStream;
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }
}

定义form表单请求包装类

public class ParameterRequestWrapper extends HttpServletRequestWrapper {

    private Map<String, String[]> params = new HashMap<String, String[]>();
    
    public ParameterRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        this.params.putAll(request.getParameterMap());
    }

    /**
     * 重载一个构造方法
     *
     * @param request
     * @param extendParams
     */
    public ParameterRequestWrapper(HttpServletRequest request, Map<String, String[]> extendParams) throws IOException {
        this(request);
        addAllParameters(extendParams);
    }

    @Override
    public Enumeration<String> getParameterNames() {
        return Collections.enumeration(params.keySet());
    }

    @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 void addAllParameters(Map<String, String[]> otherParams) {
        for (Map.Entry<String, String[]> entry : otherParams.entrySet()) {
            addParameter(entry.getKey(), entry.getValue());
        }
    }


    public void addParameter(String name, Object value) {
        if (value != null) {
            if (value instanceof String[]) {
                params.put(name, (String[]) value);
            } else if (value instanceof String) {
                params.put(name, new String[]{(String) value});
            } else {
                params.put(name, new String[]{String.valueOf(value)});
            }
        }
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        return this.params;
    }
    
}

定义过滤器

@Component
@WebFilter(filterName = "myFilter", urlPatterns = "/")
@Order(10000)
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    	if(req instanceof HttpServletRequest){
			HttpServletRequest request = (HttpServletRequest) req;
	        String contentType = request.getContentType();
	        //body形式(json)
	        if (contentType.equals(MediaType.APPLICATION_JSON_UTF8_VALUE)
	                || contentType.equals(MediaType.APPLICATION_JSON_VALUE)) {
            	//获取request的body参数
            	String postContent = getBody(request);
            	//如果body中存在数据放入HttpServletRequest
            	if (StringUtils.isNotEmpty(postContent)) {
                	//修改、新增、删除参数
                	JSONObject jsStr = JSONObject.parseObject(postContent);
                	if(jsStr.containsKey("userName")){
                    	jsStr.put("userName", "对用户名进行解密");
                	}
                	postContent = jsStr.toJSONString();
                	//将参数放入重写的方法中
                	request = new BodyRequestWrapper(request, postContent);
            	}
            }
            //form表单形式
        	if ((contentType.equals(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
                	|| contentType.contains(MediaType.MULTIPART_FORM_DATA_VALUE))
                	&& !request.getParameterMap().isEmpty()) {
            	//修改、新增、删除参数
            	Map<String, String[]> parameterMap = request.getParameterMap();
            	//对请求参数进行处理
            	if(parameterMap.containsKey("userName")){
                	parameterMap.put("userName", new String[]{"对用户名进行解密"});
            	}
            	//将参数放入重写的方法中
            	request = new ParameterRequestWrapper(request, parameterMap);
        	}
        	chain.doFilter(request, response);
		}else{
			filterChain.doFilter(req, response);
		}
    }

    //获取Request的body数据
    private String getBody(ServletRequest request) {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        InputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {

        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return stringBuilder.toString();
    }

    @Override
    public void destroy() {

    }
}

测试controller

@RestController
@RequestMapping("/user")
@Slf4j
public class IccAuthCallBackController {

    @PostMapping("test1")
    public Response test1(@RequestBody User user){
        Response response=null;
        return response;
    }

    @PostMapping("test2")
    public Response test2(@RequestParam("userName")String userName){
        IccAuthResponse response = null;

        return response;
    }
}
  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值