javax.servlet.ServletRequest中的
MapparameterMap = request.getParameterMap();不能被修改,原因如下:
org/apache/tomcat/embed/tomcat-embed-core/8.0.32/tomcat-embed-core-8.0.32-sources.jar!/org/apache/catalina/util/ParameterMap.java
/**
* Associate the specified value with the specified key in this map. If
* the map previously contained a mapping for this key, the old value is
* replaced.
*
* @param key Key with which the specified value is to be associated
* @param value Value to be associated with the specified key
*
* @return The previous value associated with the specified key, or
* null
if there was no mapping for key
*
* @exception IllegalStateException if this map is currently locked
*/
@Override
public V put(K key, V value) {
if (locked)
throw new IllegalStateException
(sm.getString("parameterMap.locked"));
return (super.put(key, value));
}
https://my.oschina.net/cwalet/blog/35431
处理过程:
(1)页面提交请求“/sa? userid=123456789& username=rensanning”
(2)通过Filter处理加入新参数“ name=newname”
(3)sa的Servlet中forward到“/sb? myname=rensanning& mycountry=china”
(4)sb的Servlet中生成页面输出所有参数:userid、username、myname、mycountry、name
第一步:
最简单,在页面上先输出一个href为改地址的链接即可。
第二步:
新作Filter类:ParameterFilter,配置web.xml
在doFilter方法中包装request,设置新参数值。
包装类代码如下:
第三步:
sa的Servlet中,doGet()方法做forward跳转。
第四步:
sb的Servlet中生成页面输出所有QueryString和ParameterMap的参数。(代码略)
问题:
(1)Filter也只执行了一次
由于RequestDispatcher.forward是Servlet之间的跳转,所以默认不走Filter。在Servlet2.4规范中定义了可以在web.xml中配置:
(2)结果的QueryString中存在forward时URL的两个参数(myname、mycountry),而ParameterMap中没有。
forward时QueryString中的参数未被放入ParameterMap???
如下修改wrapper类:
(1)页面提交请求“/sa? userid=123456789& username=rensanning”
(2)通过Filter处理加入新参数“ name=newname”
(3)sa的Servlet中forward到“/sb? myname=rensanning& mycountry=china”
(4)sb的Servlet中生成页面输出所有参数:userid、username、myname、mycountry、name
第一步:
最简单,在页面上先输出一个href为改地址的链接即可。
第二步:
新作Filter类:ParameterFilter,配置web.xml
- <filter-mapping>
- <filter-name>ParameterFilterfilter-name>
- <url-pattern>/*url-pattern>
- filter-mapping>
在doFilter方法中包装request,设置新参数值。
- Map
m = new HashMap (req.getParameterMap()); - m.put("name", new String[]{"newname"});
- req = new ParameterRequestWrapper((HttpServletRequest)req, m);
- chain.doFilter(req, res);
包装类代码如下:
- class ParameterRequestWrapper extends HttpServletRequestWrapper {
- private Map
params; - public ParameterRequestWrapper(HttpServletRequest request,
- Map
newParams) { - super(request);
- this.params = newParams;
- }
- @Override
- public String getParameter(String name) {
- String result = "";
- Object v = params.get(name);
- if (v == null) {
- result = null;
- } else if (v instanceof String[]) {
- String[] strArr = (String[]) v;
- if (strArr.length > 0) {
- result = strArr[0];
- } else {
- result = null;
- }
- } else if (v instanceof String) {
- result = (String) v;
- } else {
- result = v.toString();
- }
- return result;
- }
- @Override
- public Map getParameterMap() {
- return params;
- }
- @Override
- public Enumeration getParameterNames() {
- return new Vector(params.keySet()).elements();
- }
- @Override
- public String[] getParameterValues(String name) {
- String[] result = null;
- Object v = params.get(name);
- if (v == null) {
- result = null;
- } else if (v instanceof String[]) {
- result = (String[]) v;
- } else if (v instanceof String) {
- result = new String[] { (String) v };
- } else {
- result = new String[] { v.toString() };
- }
- return result;
- }
- }
第三步:
sa的Servlet中,doGet()方法做forward跳转。
- RequestDispatcher rd = getServletContext().getRequestDispatcher("/sb?myname=rensanning&mycountry=china");
- rd.forward(request, response);
第四步:
sb的Servlet中生成页面输出所有QueryString和ParameterMap的参数。(代码略)
问题:
(1)Filter也只执行了一次
由于RequestDispatcher.forward是Servlet之间的跳转,所以默认不走Filter。在Servlet2.4规范中定义了可以在web.xml中配置:
- <filter-mapping>
- <filter-name>ParameterFilterfilter-name>
- <url-pattern>/*url-pattern>
- <dispatcher>REQUESTdispatcher>
- <dispatcher>FORWARDdispatcher>
- filter-mapping>
(2)结果的QueryString中存在forward时URL的两个参数(myname、mycountry),而ParameterMap中没有。
forward时QueryString中的参数未被放入ParameterMap???
如下修改wrapper类:
- class ParameterRequestWrapper extends HttpServletRequestWrapper {
- private Map
params; - public ParameterRequestWrapper(HttpServletRequest request,
- Map
newParams) { - super(request);
- this.params = newParams;
- // RequestDispatcher.forward parameter
- renewParameterMap(request);
- }
- @Override
- public String getParameter(String name) {
- String result = "";
- Object v = params.get(name);
- if (v == null) {
- result = null;
- } else if (v instanceof String[]) {
- String[] strArr = (String[]) v;
- if (strArr.length > 0) {
- result = strArr[0];
- } else {
- result = null;
- }
- } else if (v instanceof String) {
- result = (String) v;
- } else {
- result = v.toString();
- }
- return result;
- }
- @Override
- public Map getParameterMap() {
- return params;
- }
- @Override
- public Enumeration getParameterNames() {
- return new Vector(params.keySet()).elements();
- }
- @Override
- public String[] getParameterValues(String name) {
- String[] result = null;
- Object v = params.get(name);
- if (v == null) {
- result = null;
- } else if (v instanceof String[]) {
- result = (String[]) v;
- } else if (v instanceof String) {
- result = new String[] { (String) v };
- } else {
- result = new String[] { v.toString() };
- }
- return result;
- }
- private void renewParameterMap(HttpServletRequest req) {
- String queryString = req.getQueryString();
- if (queryString != null && queryString.trim().length() > 0) {
- String[] params = queryString.split("&");
- for (int i = 0; i < params.length; i++) {
- int splitIndex = params[i].indexOf("=");
- if (splitIndex == -1) {
- continue;
- }
- String key = params[i].substring(0, splitIndex);
- if (!this.params.containsKey(key)) {
- if (splitIndex < params[i].length()) {
- String value = params[i].substring(splitIndex + 1);
- this.params.put(key, new String[] { value });
- }
- }
- }
- }
- }
- }
import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.util.Enumeration; import java.util.Map; import java.util.Vector; /** * Created by MyWorld on 2016/9/25. */ public class ParameterRequestWrapper extends HttpServletRequestWrapper { /** * Constructs a request object wrapping the given request. * * @param request The request to wrap * @throws IllegalArgumentException if the request is null * http://www.cnblogs.com/softidea/p/5903873.html * */ private Mapparams; public ParameterRequestWrapper(HttpServletRequest request, Map params) { super(request); this.params = params; addHeaderInfoToParams(request); } private void addHeaderInfoToParams(HttpServletRequest request) { request.getHeader("_pid"); } @Override public String getParameter(String name) { String[] values = getParameterValues(name); if (values == null || values.length == 0) { return null; } else { return values[0]; } } @Override public Map getParameterMap() { return params; } @Override public Enumeration getParameterNames() { return new Vector(params.keySet()).elements(); } @Override public String[] getParameterValues(String name) { String[] values = params.get(name); if (values == null) { return null; } else { return values; } } }
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * Created by MyWorld on 2016/9/25. */ public class AddExtraToParamsFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Mapparams = new HashMap<>(request.getParameterMap()); HttpServletRequest httpServletRequest = (HttpServletRequest) request; String pid = httpServletRequest.getHeader("_pid"); if (pid != null) { params.put("pid", new String[]{pid}); } request = new ParameterRequestWrapper(httpServletRequest, params); chain.doFilter(request, response); } @Override public void destroy() { } }
再次运行代码:
(1)Filter进入两次:
引用
URL:http://localhost:8080/t/sa
***-----From QueryString-----***
userid=123456789
username=rensanning
***-----From ParameterMap-----***
username=rensanning,
userid=123456789,
***-----From QueryString-----***
userid=123456789
username=rensanning
***-----From ParameterMap-----***
username=rensanning,
userid=123456789,
引用
URL:http://localhost:8080/t/sb
***-----From QueryString-----***
myname=rensanning
mycountry=china
***-----From ParameterMap-----***
username=rensanning,
name=newname,
userid=123456789,
***-----From QueryString-----***
myname=rensanning
mycountry=china
***-----From ParameterMap-----***
username=rensanning,
name=newname,
userid=123456789,
(2)最终页面结果:
引用
***-----From QueryString-----***
myname=rensanning
mycountry=china
***-----From ParameterMap-----***
username=rensanning,
name=newname,
userid=123456789,
mycountry=china,
myname=rensanning,
http://rensanning.iteye.com/blog/1706208