目次
ここはよく使う Jakarta Apache CommonsのメモURL Encodingの問題Commons-HttpClient? 3.0は URL Encodingに Commons-Codecを使っている。 具体的には諸々端折って書くと、以下の通り。HttpMethodBaseのメソッド public void setQueryString(NameValuePair [] params) { queryString = EncodingUtil.formUrlEncoding(params, "UTF-8"); } 以下、EncodingUtilのメソッド public static String formUrlEncoding(NameValuePari [] nvp, String charset) { return doFormUrlEncoding(nvp, charset); } private static String doFormUrlEncode(NameValuePair [] nvp, String cs) { StringBuffer sb = new StringBuffer(); for ( int i = 0; i < nvp.length; i++ ) { URLCodec codec = new URLCodec(); NameValuePair n = nvp[i]; if ( n.getName() != null ) { if ( i > 0 ) { sb.append("&"); } sb.append(codec.encode(n.getName(), cs); sb.append("="); } if ( n.getValue() != null ) { sb.append(codec.encode(n.getValue(),cs); } } return sb.toString(); }この Commons-Codecの encode()メソッドはRFC1738の 2.2節の最後の方で encodeしないでも使ってよい特殊文字 $-_.+!*'(),"に関しては encodeしない。 firefox等の一般的なweb browserではこれらの内、- があった場合、URL Encodeの 対象となっているが、HttpClient?では Commons-Codecが対象外としているみたいなので、 使うときに注意が必要である。
ツールを作っていた時に - が対象外になっていた事が問題だと思っていたら、/ と
間違えていた事が分かってしまい、、、^^;
Commons-Codec-1.3の実装を見るとencode対象外はURLCodecのprivate static final java.util.BitSet?変数WWW_FORM_URLに セットされている。対象外は[a-zA-Z0-0]と[-_.* ]。どうにもならんので、起動時のSystem propertyを見て、- を外せるように commons-codecを変えてbuildし直した。下記は、Commons-Codec 1.3の org.apache.commons.codec.net.URLCodecクラスの変更した箇所だけの抜粋。 // special edition private static final String MAGE_SPECIAL_KEY = "info.mage.commons.codec.special"; private static boolean isSpecialEdition = false; // Static initializer for www_form_url static { // special edition String specialKey = null; String default_specialKey = "_.* "; if ( System.getProperty(MAGE_SPECIAL_KEY) != null ) { isSpecialEdition = true; specialKey = System.getProperty(MAGE_SPECIAL_KEY); if ( specialKey.length() == 0 ) { specialKey = default_specialKey; } } // alpha characters for (int i = 'a'; i <= 'z'; i++) { WWW_FORM_URL.set(i); } for (int i = 'A'; i <= 'Z'; i++) { WWW_FORM_URL.set(i); } // numeric characters for (int i = '0'; i <= '9'; i++) { WWW_FORM_URL.set(i); } // special chars if ( !isSpecialEdition ) { WWW_FORM_URL.set('-'); WWW_FORM_URL.set('_'); WWW_FORM_URL.set('.'); WWW_FORM_URL.set('*'); // blank to be replaced with + WWW_FORM_URL.set(' '); } else { for ( int i = 0; i < specialKey.length(); i++ ) { WWW_FORM_URL.set(specialKey.charAt(i)); } } }と言うことで、起動時に -Dinfo.mage.commons.codec.specialを指定すれば、-だけ抜いた 形で動く。更に値をセットすると、1文字ずつ url encode対象外の文字になる。 上記の変更をしたのをここに 置いておきました。クラスファイルだけのzipです。まぁ、使えることもあろうかと言うことで。。。^^; 参考文献
|