攔截器修改參數
今天一位網友開發中遇到一個需求,他需要在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();
}
//省略底下的方法