关于request.getParameterMap()返回的map对象——我的一次移植测试经历

    某次在伙伴处进行移植测试,他们写了一个过滤类FirstFilter.java,目的是实现对request请求参数中的敏感字符进行过滤提示,然后让请求继续进行,FirstFilter.java部分代码如下:

Map map = request.getParameterMap();
Set set = map.entrySet();
if (map != null) {
  for (Iterator it = set.iterator(); it.hasNext();) {
  Map.Entry entry = (Entry) it.next();
				
  //System.out.println("entry class name:" + entry.getClass().getName());
				
  if (entry.getValue() instanceof String[]) {
    String[] values = (String[]) entry.getValue();
      for (int i = 0; i < values.length; i++){
      values[i] = values[i].replace("'", "''");
      for (int j = 0; j < value_group.length; j++){
        if(values[i].equalsIgnoreCase(value_group[j])){
          System.out.println("有关键字");
        }
      }
    }
    entry.setValue(values);
  }
			}
}


    tomcat服务器下代码正常,在apusic应用服务器下报UnsupportedOperationException异常,提示Map.Entry不支持setValue()方法,异常堆栈信息如下:

2009-09-18 11:08:53 错误 [apusic.web.cangzhouOA./cangzhouOA] 执行Servlet时发生错误。
java.lang.UnsupportedOperationException
	at java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry.setValue(Collections.java:1434)
	at com.OA.filter.FirstFilter.doFilter(FirstFilter.java:77)
	at com.apusic.web.container.FilterComponent.doFilter(Unknown Source)
	at com.apusic.web.container.FilterChainImpl.performFilter(Unknown Source)
	at com.apusic.web.container.WebContainer.invoke(Unknown Source)
	at com.apusic.web.container.WebContainer.processRequest(Unknown Source)
	at com.apusic.web.http.VirtualHost.processRequest(Unknown Source)
	at com.apusic.web.http.HttpServer.processRequest(Unknown Source)
	at com.apusic.web.http.HttpConnectionHandler.service(Unknown Source)
	at com.apusic.web.http.ConnectionHandler.processRequest(Unknown Source)
	at com.apusic.web.http.ConnectionHandler.processConnection(Unknown Source)
	at com.apusic.web.http.ConnectionHandler.run(Unknown Source)
	at com.apusic.util.ThreadPoolImpl$WorkerThread.run(Unknown Source)


    我在他们代码中加入

System.out.println("entry class name:" + entry.getClass().getName());

在控制台打出Map.Entry类变量的具体实现类,在tomcat下打出:entry class name:java.util.HashMap$Entry

    在apusic下打出:entry class name:java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry

    我注意到JDK API文档中,Map.Entry类中setValue()方法是可选操作(optional operation),setValue()本身也声明会抛出UnsupportedOperationException,我的理解是sun的规范允许对这个方法不进行实现。问题出现原因应该是tomcat下允许Map.Entry进行重新赋值,而我们服务器不允许。

    后来经跟同事沟通,研究了servlet规范,确定这个异常之所以会抛出来,是因为客户的程序中试图去修改ServletReqest中getParameterMap()方法返回的Map引起的,根据java ee servlet2.5规范要求,ServletRequest.getParameterMap()需返回一个immutable(不可改变)的java.util.Map实现,tomcat在这方面没有严格遵照规范,而apusic严格遵照规范,所以导致抛出异常。后来在weblogic下进行测试,weblogic也抛出异常。

JavaEE规范之所以这样要求,是出于“安全因素”的考虑。规范描述如下:

public java.util.Map getParameterMap()

Returns a java.util.Map of the parameters of this request. Request parameters are extra information sent with the request. For HTTP servlets, parameters are contained in the query string or posted form data.

Returns: an immutable java.util.Map containing parameter names as keys and parameter values as map values. The keys in the parameter map are of type String. The values in the parameter map are of type String array.

猜你喜欢

转载自zydky.iteye.com/blog/558973
今日推荐