关于在Spring过滤器中修改request的参数值遇到的问题(三)
2017-06-21 23:07
711 查看
继上一遍为背景
问题描述:
成功解密了reqeust中的参数后,在控制层Controller中获取到的参数,是没有解密的参数。例如:在过滤器中修改 参数名为username 的参数值432895328195783915781(一串加密的密文) 为 xiaomin(解密后的明文),在Cotroller中获取到的依然是加密后的密文432895328195783915781。
问题定位
百度,没有,心酸,跑不掉,一步一步debugger,终于发现
在SpringMVC框架中,request到controller层的数据bind(绑定)中,用到该类的方法org.springframework.web.method.annotation.RequestParamMethodArgumentResolver
如上注释,方法在一定条件下走了String[] paramValues = webRequest.getParameterValues(name);这一段代码,debugger发现,
这段代码走的的真正实现竟然是web容器Tomcat提供的request包装类org.apache.catalina.connector.RequestFacade中的方法。(因为这里的WebUtils.getNativeRequest(servletRequest, MultipartHttpServletRequest.class)最后返回了一个Tomcat提供的request包装类)
而该Tomcat的request包装类中的参数,确实是没有解密之前的值。由此猜测(个人猜测,不对的请指点迷津,感激) 1.服务器在接受请求时,Spring和Tomcat各自都创建了一个request的包装类(可以发现都实现了HttpServletRequest接口),在没有修改rquest参数时,这两个包装类几乎一样(指参数值都是一致的),当我在过滤器中修改了Spring的rquest包装类参数值,tomcat的request包装类是没有修改的。2.在SpringMVC的数据绑定中,应为某些原因,需要从tomcat的request包装类中获取参数值。这就导致了上述问题的发生。
4.解决方案
在之前的自定义包装类中(继承了ServletRequestWrapper)重写 getParameterValues(String name)方法
解决问题,如有不对的地方,还请高人路过指点。
4000
问题描述:
成功解密了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); } } }
解决问题,如有不对的地方,还请高人路过指点。
4000
相关文章推荐
- 关于今天在用spring字符集过滤器遇到的问题
- 关于springboot过滤器处理request参数问题
- 关于spring中加入两个不同数据库的sessionfactory遇到的问题.
- 关于编程中需要上传下载修改EXCEL时会遇到的问题
- maven+spring 遇到No mapping found for HTTP request with URI的问题
- 关于TP5视图分离到根目录的解决方法 原有: 为了方便前端开发,我想把视图(view)部分分离出来专门给前端进行修改 过程:在进行视图设置分离的过程遇到了问题 参考了官方文档http://www
- 本人小白一枚,刚学习SpringMVC+MyBatis,遇到了一个问题一直报错 **No mapping found for HTTP request with URI**
- 关于修改frameworks的源码遇到的一点问题以及解决方法
- 关于spring-mvc中使用ajax调用后台接口出现400 bad request的问题解决方案
- Spring学习笔记(二十三):关于STS提示"javax.servlet.http.HttpServletRequest cant be resolved"的问题
- 关于struts2.1.8 spring ibatis 与 dwr2的整合 遇到的问题( 二 )
- 关于spring2.5,spring-security2.0升级 遇到的问题
- 关于struts2.1.8 spring ibatis 与 dwr2的整合 遇到的问题
- 关于使用spring文件上传遇到的服务器中的图片访问不到报404的问题
- 关于SSM整合中遇到的org.springframework.beans.factory.BeanDefinitionStoreException: IOException pars 问题
- spring mvc使用过程中关于spring:bind和绑定java.util.Date遇到的问题
- 关于建立远程连接HttpRequest 遇到的问题
- 关于创建spring源码环境时遇到的缺少spring-cglib-repack-3.2.0.jar和spring-objenesis-repack-2.2.jar两个包的问题
- 关于用-jar运行springboot项目遇到的两个问题
- 关于Spring与Velocity结合的问题(获得request,session)