request.getParameterMap()が戻ってきたmapオブジェクトについて——私の一回の移植テストの経験があります。


ある時、仲間で移植テストを行いました。彼らはフィルタリングクラスのFirst Filter.javaを書いています。目的はrequest要求パラメータの中の敏感な文字をフィルタリングしてヒントを与えることです。そして要求を続けて行わせます。First Filter.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サーバの下でコードは正常です。apportedOperation異常をapportedアプリケーションサーバで報告します。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.printel("entry class name:"+entry.get Class().get Name();
コンソールでMap.Entryの変数の具体的な実現類を打ち出して、tomcatの下で打ち出します:entry class name:java.util.hashMap$Entry
    appicの下で打ち出します。entry class name:java.util.Coollections$UnimodifiablMap$Unimodifiable EntrySet$Unimodifiable Enttry
    JDK APIドキュメントにおいて、Map.EntryクラスのsetValueはオプション操作であり、setValue()自身もUnippordOperation Exceptionを抛り出すと宣言しています。sunの仕様がこの方法を実現しないということを理解しています。問題が発生した原因はtomcatの下でMap.Entryの再割当を許可するべきです。私達のサーバーは許可しません。
    その後、同僚とコミュニケーションを取って、servlet仕様を研究しました。この異常が投げ出されるのは、クライアントのプログラムの中でServletReqestのgetParameterMap()メソッドが返されたMapが原因で、java ee servlet 2.5の仕様要求によって、ServletRequest.getParameterMap()を修正しました。tomcatはこの面では厳密にルールを守っていませんが、appicは厳格にルールを守っていますので、異常が発生しました。その後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 ars are e e e e e e e e e e e the querrystring 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 aring.The values in the parameter map are of type.String.