美文网首页
spring修改request的参数值,controller中参

spring修改request的参数值,controller中参

作者: wonfi_admin | 来源:发表于2018-01-10 16:17 被阅读0次
项目组某个接口的新需求,需要调用该接口的信息加密,不能显示明文的。加密都好说,调用方使用RSA公钥加密,服务端使用RSA私钥解密,这个不在这赘述了。
服务端解密过程我的思路是使用过滤器国女某些特别的请求,例如登录接口等。在过滤器内将加密的信息解密,再把解密的信息放到request内,之后controller使用解密的信息进行后续的操作。但是遇到了一些问题,问题如下:
1、过滤器中直接对request使用setAttribute方法,在之后的操作中,不能通过request.getParameter()获得对应参数。如果使用这种方法,对现有代码改动比较大,PASS。
2、为了使后续能够通过request.getParameter()获得参数,需自定义一个request参数处理类,RequestParameterWrapper.java,代码如下。
public class RequestParameterWrapper extends HttpServletRequestWrapper{
    private Map<String,String[]> params = null;
    
    //构造方法
    public RequestParameterWrapper(HttpServletRequest request){
        super(request);
        this.params = new HashMap<>(request.getParameterMap());
    }

    //添加参数的方法
    public void addParameters(Map<String,Object> extraParams){
        for(Entry<String,Object> entry : extraParams){
            addParameters(entry.getKey(),entry.getValue());
        }
    }
    
    //这四个重写的方法是很重要的!!!只有重写了这四个方法,后续才能在这个request中获取到对应的参数
    @Override
    public String getParameter(String name){
        String[] values = params.get(name);
        if(values == null || values.length == 0){
            return null;
        }
        return values[0];
    }

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

    @Override
    public String[] getParamaterValues(String name){
        return params.get(name);        
    }

    //一般网上的方法都没有重写这个方法,如果不重写这个方法,
    //而且controller中的参数为javaBean时,bean中的属性将不会自动绑定,下面会详细讲解这个
    @Override
    public Enumeration<String> getParameterNames(){
        Vector<String> nameList = new Vector<String>();
        for(Entry<String,String[]> entry: params.entrySet()){
            nameList.add(entry.getKey());
        }
        return nameList.elements();
    }

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

写完这个类之后,在filter中chain.doFilter(arg1,response)第一个参数arg1,直接写这个类的对象即可,这个网上一大堆。

为何不重写getParameterNames()方法会导致自动绑定不上bean的属性?看源码。这个多余的源码我就不赘述,直接看问题的所在,看org.springframework.web.util.WebUtils.getParametersStartingWith()这个方法,这个方法里第二行就是调用request.getParameterNames()方法获取所有参数名称,之后在根据这个参数名称列表获取参数进行绑定操作,如果不重写这个方法,那么获取到的还是原来的参数列表,自然无法绑定参数。

public static Map<String, Object> getParametersStartingWith(ServletRequest request, String prefix) {
        Assert.notNull(request, "Request must not be null");
        Enumeration<String> paramNames = request.getParameterNames();
        Map<String, Object> params = new TreeMap<String, Object>();
        if (prefix == null) {
            prefix = "";
        }
        while (paramNames != null && paramNames.hasMoreElements()) {
            String paramName = 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) {
                    // Do nothing, no values found at all.
                }
                else if (values.length > 1) {
                    params.put(unprefixed, values);
                }
                else {
                    params.put(unprefixed, values[0]);
                }
            }
        }
        return params;
    }

相关文章

网友评论

      本文标题:spring修改request的参数值,controller中参

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