美文网首页
sprintboot http请求参数如何优雅预处理

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

作者: 七秒的记忆_d4a7 | 来源:发表于2020-10-10 17:17 被阅读0次

    一、背景

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

    二、如何优雅实现处理

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

    • 过滤器Filter: 类级别,粒度较粗

    • 拦截器intecepter: 方法级别, 粒度较细

    由于针对的是所有类接口,选用过滤器进行粗粒度参数过滤即可。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() {}
    }
    

    相关文章

      网友评论

          本文标题:sprintboot http请求参数如何优雅预处理

          本文链接:https://www.haomeiwen.com/subject/oxfjpktx.html