sprintboot http请求参数如何优雅预处理

2020-10-10  本文已影响0人  七秒的记忆_d4a7

一、背景

在做管理后台页面查询,我们经常会遇到多条件查询的情况,而且每个条件字段,对应的value值类型也可能不同, 可能是整型,也可能是字符串类型,也可能是null。 总结下查询传入后端接口的值有 null, "", undefined,正常的数字,正常的字符串。常规的做法,会在每个查询接口的入口处(正式做业务逻辑前)做参数校验,只接收预期的值。这样实现起来,会发现一堆的if else,如果查询接口多的话,会看起来非常的臃肿。

二、如何优雅实现处理

我们知道对客户端请求过滤有两种方式,如下:

由于针对的是所有类接口,选用过滤器进行粗粒度参数过滤即可。Filter可以过滤想要它过滤的每一个请求,在这请求中有HttpServletRequest、HttpServletResponse, 我们知道服务器取得客户端发送的参数都是通过HttpServletRequest来获取的。 但遗憾的是HttpServletRequest没有提供对应的setParameter方法,允许修改客户端发送过来的值。因此我们需要自定义HttpServletRequestWrapper来包装一下当前HttpServletRequest请求, 自定义HttpServletRequestWrapper的提供可修改客户端值的setParameter方法。

/**
*
*自定义HttpServletRequestWrapper
*/

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.HashMap;
import java.util.Map;

public class MyHttpServletRequestWapper  extends HttpServletRequestWrapper {
    /**
     *  用于存储请求参数
     */
    private Map<String , String[]> params = new HashMap<String, String[]>();

    /**
     * 包装一下当前请求
     * @param request
     * @throws IllegalArgumentException if the request is null
     */
    public MyHttpServletRequestWapper(HttpServletRequest request) {
        super(request);
        // 把请求参数添加到我们自己的map当中
        this.params.putAll(request.getParameterMap());
    }
    
    /**
     * 添加参数到map中
     * @param name
     * @param value
     */
    public void setParameter(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)});
            }
        }
    }

    /**
     * 重写getParameter,代表参数从当前类中的map获取
     * @param name
     * @return
     */
    @Override
    public String getParameter(String name) {
        String[]values = params.get(name);
        if(values == null || values.length == 0) {
            return null;
        }
        return values[0];
    }

    /**
     * 重写getParameterValues方法,从当前类的 map中取值
     * @param name
     * @return
     */
    @Override
    public String[] getParameterValues(String name) {
        return params.get(name);
    }

}
/**
 *
 * 不合法参数过滤器
 */
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;


public class InvalidParamFilter implements Filter {

    private static final Logger log = LoggerFactory.getLogger(InvalidParamFilter.class)


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

    /**
     * 参数预处理
     * @param request
     * @param response
     * @param chain
     * @throws IOException
     * @throws ServletException
     */
    @SuppressWarnings("unchecked")
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //包装一下请求
        MyHttpServletRequestWapper requestWrapper = new MyHttpServletRequestWapper(
                    (HttpServletRequest) request);
        //获取原始请求参数
        Map<String, String[]> paramterMap =  requestWrapper.getParameterMap();

        //预处理原始请求参数
        for(Map.Entry<String, String[]> entry : paramterMap.entrySet()){
            String[] values = entry.getValue();
            //1、只处理单个参数
            if(values.length !=1){
                continue;
            }
            if(Objects.isNull(values[0]) || StringUtils.isBlank(values[0]) || values[0].equals("undefined")) {
                 //2、把处理后的参数放回去, null、""、undefined等输入参数值统一转换为字符串"0"
                 requestWrapper.setParameter(entry.getKey(), "0");

            }
        }
        // 3、放行,把我们的requestWrapper放到方法当中
        chain.doFilter(requestWrapper, response);
        
    }

    @Override
    public void destroy() {}
}
上一篇 下一篇

猜你喜欢

热点阅读