继上一遍为背景
问题描述:
成功解密了reqeust中的参数后,在控制层Controller中获取到的参数,是没有解密的参数。例如:在过滤器中修改 参数名为username 的参数值432895328195783915781(一串加密的密文) 为 xiaomin(解密后的明文),在Cotroller中获取到的依然是加密后的密文432895328195783915781。问题定位
百度,没有,心酸,跑不掉,一步一步debugger,终于发现
在SpringMVC框架中,request到controller层的数据bind(绑定)中,用到该类的方法org.springframework.web.method.annotation.RequestParamMethodArgumentResolver@Override protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest webRequest) throws Exception { HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class); MultipartHttpServletRequest multipartRequest = WebUtils.getNativeRequest(servletRequest, MultipartHttpServletRequest.class); Object arg; // 将被绑定的值 . . . if (multipartRequest != null) { List<MultipartFile> files = multipartRequest.getFiles(name); if (!files.isEmpty()) { arg = (files.size() == 1 ? files.get(0) : files); } } if (arg == null) { // 方法走了该判断体 String[] paramValues = webRequest.getParameterValues(name); if (paramValues != null) { arg = (paramValues.length == 1 ? paramValues[0] : paramValues); } } }
如上注释,方法在一定条件下走了String[] paramValues = webRequest.getParameterValues(name);这一段代码,debugger发现,
这段代码走的的真正实现竟然是web容器Tomcat提供的request包装类org.apache.catalina.connector.RequestFacade中的方法。(因为这里的WebUtils.getNativeRequest(servletRequest, MultipartHttpServletRequest.class)最后返回了一个Tomcat提供的request包装类)@Override public String[] getParameterValues(String name) { if (request == null) { throw new IllegalStateException( sm.getString("requestFacade.nullRequest")); } String[] ret = null; if (SecurityUtil.isPackageProtectionEnabled()){ ret = AccessController.doPrivileged( new GetParameterValuePrivilegedAction(name)); if (ret != null) { ret = ret.clone(); } } else { ret = request.getParameterValues(name); } return ret; }
而该Tomcat的request包装类中的参数,确实是没有解密之前的值。由此猜测(个人猜测,不对的请指点迷津,感激) 1.服务器在接受请求时,Spring和Tomcat各自都创建了一个request的包装类(可以发现都实现了HttpServletRequest接口),在没有修改rquest参数时,这两个包装类几乎一样(指参数值都是一致的),当我在过滤器中修改了Spring的rquest包装类参数值,tomcat的request包装类是没有修改的。2.在SpringMVC的数据绑定中,应为某些原因,需要从tomcat的request包装类中获取参数值。这就导致了上述问题的发生。
4.解决方案
在之前的自定义包装类中(继承了ServletRequestWrapper)重写 getParameterValues(String name)方法import org.apache.catalina.util.ParameterMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.util.Map; public class ParameterRequestWrapper extends HttpServletRequestWrapper { private ParameterMap<String, String[]> params; @SuppressWarnings("all") public ParameterRequestWrapper(HttpServletRequest request) { super(request); params = (ParameterMap) request.getParameterMap(); // TODO Auto-generated constructor stub } @Override public String getParameter(String name) { // TODO Auto-generated method stub String[] values = params.get(name); if (values == null || values.length == 0) { return null; } return values[0]; } @Override public Map<String, String[]> getParameterMap() { // TODO Auto-generated method stub return params; } // 就是该方法 @Override public String[] getParameterValues(String name) { return params.get(name); } public void addParameter(String name, Object value) { if (value != null) { params.setLocked(false); 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) }); } params.setLocked(true); } } }
解决问题,如有不对的地方,还请高人路过指点。
关于在Spring过滤器中修改request的参数值遇到的问题(三)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_29092471/article/details/73556658
猜你喜欢
转载自blog.csdn.net/baidu_29092471/article/details/73556658
今日推荐
周排行