Spring ServletRequest Data Binder

SpringMVC提供了request中的请求参数自动绑定到POJO的功能,但是有时候需要给指定的请求统一绑定某一个参数,具体实现如下:

  1. 增加一个filter,这里使用了SpringBoot,修改filterConfig
public class FilterConfig {

    /**
     * app Filter
     */
    @Bean
    @Order(4000)
    public FilterRegistrationBean appFilter() {
        //注册一个filter Bean
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new AppInitFilter());
        //过滤的请求
        bean.addUrlPatterns(Global.getAdminPath()+"/app/*");
        return bean;
    }

2.在Filter中,我们需要给request加入一个parameter参数,但是由于Request没有提供SetParameter方法,而且ParameterMap也是不可修改的,所以使用重写的Request:

/**
 * 请求摘要拦截器
 *
 */
public class AppInitFilter extends OncePerRequestFilter {

    /**
     * @see OncePerRequestFilter#doFilterInternal(HttpServletRequest,
     *      HttpServletResponse, FilterChain)
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        //使用新的request
        ParameterRequestWrapper requestWrapper = new
        ParameterRequestWrapper((HttpServletRequest)request);
        //加入需要的参数
        requestWrapper.addParameter("storeCode", EmpUtils.getCompany().getCompanyCode());
        filterChain.doFilter(requestWrapper, response);
    }
}
  1. 那么Spring是如何将request绑定到Pojo的呢?
    可以看一下代码:
ServletRequestDataBinder.bind() > WebUtils.getParametersStartingWith()

其中WebUtils.getParametersStartingWith():

public static Map getParametersStartingWith(ServletRequest request, String prefix) {
        Assert.notNull(request, "Request must not be null");
        Enumeration paramNames = request.getParameterNames();
        Map params = new TreeMap();
        if(prefix == null) {
            prefix = "";
        }

        while(paramNames != null && paramNames.hasMoreElements()) {
            String paramName = (String)paramNames.nextElement();
            if("".equals(prefix) || paramName.startsWith(prefix)) {
                String unprefixed = paramName.substring(prefix.length());
                String[] values = request.getParameterValues(paramName);
                if(values != null && values.length != 0) {
                    if(values.length > 1) {
                        params.put(unprefixed, values);
                    } else {
                        params.put(unprefixed, values[0]);
                    }
                }
            }
        }

        return params;
    }

可以看出,他是通过getParameterNames遍历request的参数的,那么我们只需要在定义的request中重写这个方法就可以了:


public class ParameterRequestWrapper extends HttpServletRequestWrapper {

    private Map params = new HashMap();


    @SuppressWarnings("unchecked")
    public ParameterRequestWrapper(HttpServletRequest request) {
        super(request);
        this.params.putAll(request.getParameterMap());
    }
    public ParameterRequestWrapper(HttpServletRequest request , Map extendParams) {
        this(request);
        addAllParameters(extendParams);
    }

    @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(MapotherParams) {
        for(Map.Entryentry : 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)});
            }
        }
    }

    private Map allParameters = null;


    @Override
    public Map getParameterMap() {
        if (allParameters == null) {
            allParameters = new TreeMap();
            allParameters.putAll(params);
        }
        // 返回unmodifiable集合
        return Collections.unmodifiableMap(allParameters);
    }

    @Override
    public Enumeration getParameterNames() {
        return Collections.enumeration(getParameterMap().keySet());
    }
}

你可能感兴趣的:(Spring ServletRequest Data Binder)