HTTPClient PostMethod文字化け問題


これは古い文章ですが、思わず振り返ってみました。
 
UTF-8 encoding http-client java  Http Client POSTのUTF-8符号化問題  Apache Http Client  http://jakarta.apache.org/commons/httpclient/ ) は、純粋なJavaのHTTPプロトコルのクライアントプログラミングツールパッケージです。HTTPプロトコルに対するサポートはかなり全面的で、より多くの詳細はIBMサイト上のこの記事HttpClient入門を参照することもできます。  http://www-128.ibm.com/developerworks/cn/opensource/os-httpclient/ ).  問題の分析  しかし、実際の使用では、最も基本的な方法でHttpClientを呼び出すとき、UTF-8コードをサポートしていないことが分かりました。インターネット上でいくつかの記事を探しましたが、要領を得られませんでした。そこで、commons-httpclient-3.0.1のコードを調べて、まずPostMethodの中にGEnese Request Entitityを見つけました。
 
# /**  
# * Generates a request entity from the post parameters, if present. Calls  
# * {@link EntityEnclosingMethod#generateRequestBody()} if parameters have not been set.  
# *  
# * @since 3.0  
# */   
# protected RequestEntity generateRequestEntity() {   
# if (!this.params.isEmpty()) {   
# // Use a ByteArrayRequestEntity instead of a StringRequestEntity.   
# // This is to avoid potential encoding issues. Form url encoded strings   
# // are ASCII by definition but the content type may not be. Treating the content   
# // as bytes allows us to keep the current charset without worrying about how   
# // this charset will effect the encoding of the form url encoded string.   
# String content = EncodingUtil.formUrlEncode(getParameters(), getRequestCharSet());   
# ByteArrayRequestEntity entity = new ByteArrayRequestEntity(   
# EncodingUtil.getAsciiBytes(content),   
# FORM_URL_ENCODED_CONTENT_TYPE   
# );   
# return entity;   
# } else {   
# return super.generateRequestEntity();   
# }   
# } 


 
NameValuePairを使って参加したHTTP要求のパラメータは最終的にはRequest Entityに変換してHTTPサーバに提出され、続いてPostMethodの親タイプEnttity EncosingMethodに下記のコードが見つかりました。
 
   1. /**  
   2. * Returns the request's charset. The charset is parsed from the request entity's  
   3. * content type, unless the content type header has been set manually.  
   4. *  
   5. * @see RequestEntity#getContentType()  
   6. *  
   7. * @since 3.0  
   8. */   
   9. public String getRequestCharSet() {   
  10. if (getRequestHeader("Content-Type") == null) {   
  11. // check the content type from request entity   
  12. // We can't call getRequestEntity() since it will probably call   
  13. // this method.   
  14. if (this.requestEntity != null) {   
  15. return getContentCharSet(   
  16. new Header("Content-Type", requestEntity.getContentType()));   
  17. } else {   
  18. return super.getRequestCharSet();   
  19. }   
  20. } else {   
  21. return super.getRequestCharSet();   
  22. }   
  23. }   
 
 
ソリューション  上の2つのコードからは、HttpClieventがどのように「Conteet Type」によって要求されたコード(文字セット)を取得し、このコードはどのようにコンテンツを提出するコードに適用されますか?これによって、実際にはget Request CharSet()方法を再読み込みし、必要なコード(文字セット)を返します。名前は、UTF-8または他の非デフォルト符号化がPOST要求に提出されたときの文字化けの問題を解決できます。
 
 
テスト  まずTomcatのROOT WebAppの下に一つのページtest.jspを配置して、テストページとして、主なコードのセグメントは以下の通りです。
 
   1. <%@ page contentType="text/html;charset=UTF-8"%>   
   2. <%@ page session="false" %>   
   3. <%   
   4. request.setCharacterEncoding("UTF-8");   
   5. String val = request.getParameter("TEXT");   
   6. System.out.println(">>>> The result is " + val);   
   7. %>   
 
 
次にテストクラスを書きます。主要コードは以下の通りです。
 
   1. public static void main(String[] args) throws Exception, IOException {   
   2. String url = "http://localhost:8080/test.jsp";   
   3. PostMethod postMethod = new UTF8PostMethod(url);   
   4. //            
   5. NameValuePair[] data = {   
   6. new NameValuePair("TEXT", "  "),   
   7. };   
   8. //       postMethod    
   9. postMethod.setRequestBody(data);   
  10. //  postMethod   
  11. HttpClient httpClient = new HttpClient();   
  12. httpClient.executeMethod(postMethod);   
  13. }   
  14.   
  15. //Inner class for UTF-8 support   
  16. public static class UTF8PostMethod extends PostMethod{   
  17. public UTF8PostMethod(String url){   
  18. super(url);   
  19. }   
  20. @Override   
  21. public String getRequestCharSet() {   
  22. //return super.getRequestCharSet();   
  23. return "UTF-8";   
  24. }   
  25. }   
 
このテストプログラムを実行して、Tomcatのバックグラウンド出力で正確に「>>」The reult is中国語を印刷できます。