代码改变世界

修改Request 中的数据

2016-01-31 18:24  兔子托尼啊  阅读(4022)  评论(0编辑  收藏

拦截器修改参数

今天一位网友开发中遇到一个需求,他需要在Request中修改传递过来的数据。开始的时候他在拦截器中修改,在拦截器中可以获取到从前台request中
传递过来的数据。他写法大致如下:自定义拦截器继承HandlerInterceptorAdapter

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        //在这里request中获取参数并修改。
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
       
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
      
    }


不过在controller 中获取在拦截器中修改的参数,发现参数还是以前老的数据,也就是说在拦截器中修改request中出传递过来的数据并没有生效。
数据没有生效 参考

于是我看了 HttpServletRequestWrapper 源码,在Filter中测试了,发现可以成功修改传递过来的参数


public class HTMLFilter implements Filter {

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {

		FilteredRequest requestWrapper = new FilteredRequest((HttpServletRequest) request);
		requestWrapper.getParameter("paramName");
		chain.doFilter(new FilteredRequest(request), response);
	}

	static class FilteredRequest extends HttpServletRequestWrapper {

		public FilteredRequest(ServletRequest request) {
			super((HttpServletRequest) request);
		}

		public String getParameter(String paramName) {
			String value = super.getParameter(paramName);
			return value + "modify";
		}

	}

	public void destroy() {
		// TODO Auto-generated method stub
	}

	public void init(FilterConfig paramFilterConfig) throws ServletException {
		// TODO Auto-generated method stub

	}

}

测试结果如下图

  • URL请求地址

  • 自定义过滤器修改传递参数的数据

  • Controller中查看传递过来的数据

接下来我们分析下代码

Controller 中的 request.getParameter("paramName") 这个调用的是什么?我们看下源码发现调用的是
package javax.servlet 包 下面的 ServletRequest 抽象接口ServletRequest 中的
public abstract String getParameter(String paramString);

package javax.servlet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;

public abstract interface ServletRequest
{
  public abstract Object getAttribute(String paramString);
  
  public abstract Enumeration<String> getAttributeNames();
  
  public abstract String getCharacterEncoding();
  
  public abstract void setCharacterEncoding(String paramString)  throws UnsupportedEncodingException;
  
  public abstract int getContentLength();
  
  public abstract String getContentType();
  
  public abstract ServletInputStream getInputStream()   throws IOException;
  
  public abstract String getParameter(String paramString);
  
  public abstract Enumeration<String> getParameterNames();
  
  public abstract String[] getParameterValues(String paramString);
  
  public abstract Map<String, String[]> getParameterMap();
  
  public abstract String getProtocol();
  
  public abstract String getScheme();
  
  public abstract String getServerName();
  
  public abstract int getServerPort();
  
  public abstract BufferedReader getReader()   throws IOException;
  
  public abstract String getRemoteAddr();
  
  public abstract String getRemoteHost();
  
  public abstract void setAttribute(String paramString, Object paramObject);
  
  public abstract void removeAttribute(String paramString);
  
  public abstract Locale getLocale();
  
  public abstract Enumeration<Locale> getLocales();
  
  public abstract boolean isSecure();
  
  public abstract RequestDispatcher getRequestDispatcher(String paramString);
  
  /**
   * @deprecated
   */
  public abstract String getRealPath(String paramString);
  
  public abstract int getRemotePort();
  
  public abstract String getLocalName();
  
  public abstract String getLocalAddr();
  
  public abstract int getLocalPort();
  
  public abstract ServletContext getServletContext();
  
  public abstract AsyncContext startAsync()  throws IllegalStateException;
  
  public abstract AsyncContext startAsync(ServletRequest paramServletRequest, ServletResponse paramServletResponse)   throws IllegalStateException;
  
  public abstract boolean isAsyncStarted();
  
  public abstract boolean isAsyncSupported();
  
  public abstract AsyncContext getAsyncContext();
  
  public abstract DispatcherType getDispatcherType();
}
接下来我们看下Filter的实现类,
public String getParameter(String paramName) {
	String value = super.getParameter(paramName);
	return value + "modify";
}

我们着重看super.getParameter 这个方法,我们点进去看源码发现的是 ServletRequestWrapper 类下面的

 public String getParameter(String name)
{
    return request.getParameter(name);
}

然而 public class ServletRequestWrapper implements ServletRequest

综上所述源头来源于 ServletRequest 我们在Controller 中的 request.getParameter("paramName") 最后就是找的 ServletRequest

我们来看看HttpServletRequestWrapper
public class HttpServletRequestWrapper   extends ServletRequestWrapper   implements HttpServletRequest
 {
   public HttpServletRequestWrapper(HttpServletRequest request)
   {
     super(request);
   }
   
   private HttpServletRequest _getHttpServletRequest() {
   return (HttpServletRequest)super.getRequest();
   }
 
   public String getAuthType()
   {
      return _getHttpServletRequest().getAuthType();
   }
 
   public Cookie[] getCookies()
   {
   return _getHttpServletRequest().getCookies();
   }
 
   public long getDateHeader(String name)
   {
     return _getHttpServletRequest().getDateHeader(name);
   }
  
   public String getHeader(String name)
   {
   return _getHttpServletRequest().getHeader(name);
   }
 
   public Enumeration<String> getHeaders(String name)
   {
     return _getHttpServletRequest().getHeaders(name);
   }
  
   public Enumeration<String> getHeaderNames()
   {
    return _getHttpServletRequest().getHeaderNames();
   }
 
   public int getIntHeader(String name)
   {
   return _getHttpServletRequest().getIntHeader(name);
   }
   
   public String getMethod()
   {
      return _getHttpServletRequest().getMethod();
   }
 
   public String getPathInfo()
   {
     return _getHttpServletRequest().getPathInfo();
   }
   
   public String getPathTranslated()
   {
     return _getHttpServletRequest().getPathTranslated();
   }
 
   public String getContextPath()
   {
   return _getHttpServletRequest().getContextPath();
   }
  
 
   public String getQueryString()
   {
    return _getHttpServletRequest().getQueryString();
   }
 
   public String getRemoteUser()
   {
   return _getHttpServletRequest().getRemoteUser();
   }
 
   public boolean isUserInRole(String role)
   {
   return _getHttpServletRequest().isUserInRole(role);
   }
   
   public Principal getUserPrincipal()
   {
      return _getHttpServletRequest().getUserPrincipal();
   }
   
   public String getRequestedSessionId()
   {
      return _getHttpServletRequest().getRequestedSessionId();
   }
   
   public String getRequestURI()
   {
   return _getHttpServletRequest().getRequestURI();
   }
   
   public StringBuffer getRequestURL()
   {
   return _getHttpServletRequest().getRequestURL();
   }
   
   public String getServletPath()
   {
      return _getHttpServletRequest().getServletPath();
   }
   
 
   public HttpSession getSession(boolean create)
   {
     return _getHttpServletRequest().getSession(create);
   }
   
   public HttpSession getSession()
   {
      return _getHttpServletRequest().getSession();
   }
 
   public boolean isRequestedSessionIdValid()
   {
    return _getHttpServletRequest().isRequestedSessionIdValid();
   }
  
   public boolean isRequestedSessionIdFromCookie()
   {
     return _getHttpServletRequest().isRequestedSessionIdFromCookie();
   }

//省略底下的方法