zoukankan      html  css  js  c++  java
  • HTTPCLIENT 解决乱码方案 linfeng_0212的日志 网易博客

    HTTPCLIENT 解决乱码方案 - linfeng_0212的日志 - 网易博客

    HTTPCLIENT 解决乱码方案   

    2008-12-17 12:28:55|  分类: 技术 |  标签:  |字号  订阅

    使用 httpclient 通信时分两种乱码。

    1.向服务器post/get中文乱码

    解决方法:查看源代码

    public String getContentCharset() {
            String charset = (String) getParameter(HTTP_CONTENT_CHARSET);
            if (charset == null) {
                LOG.warn("Default content charset not configured, using ISO-8859-1");
                charset = "ISO-8859-1";
            }
            return charset;
        }

    一目了然如果http 消息中header 设置charset可以解决问题。

    method.addRequestHeader("Content-Type", "text/html; charset=gb2312");

    2.获得服务器返回的中文乱码

    问题分析

    不过在实际使用中, 还是发现按照最基本的方式调用 HttpClient 时, 并不支持 UTF-8 编码, 在网络上找过一些文章, 也不得要领, 于是查看了 commons-httpclient-3.0.1 的一些代码, 首先在 PostMethod 中找到了 generateRequestEntity() 方法:

    /**

    * 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 请求的参数最终都会转化为 RequestEntity 提交到 HTTP 服务器, 接着在 PostMethod 的父类 EntityEnclosingMethod 中找到了如下的代码:

    /**

    * Returns the request's charset. The charset is parsed from the request entity's

    * content type, unless the content type header has been set manually.

    *

    * @see RequestEntity#getContentType()

    *

    * @since 3.0

    */

    public String getRequestCharSet() {

    if (getRequestHeader("Content-Type") == null) {

    // check the content type from request entity

    // We can't call getRequestEntity() since it will probably call

    // this method.

    if (this.requestEntity != null) {

    return getContentCharSet(

    new Header("Content-Type", requestEntity.getContentType()));

    } else {

    return super.getRequestCharSet();

    }

    } else {

    return super.getRequestCharSet();

    }

    }

     

    解决方案

    从上面两段代码可以看出是 HttpClient 是如何依据 "Content-Type" 获得请求的编码(字符集), 而这个编码又是如何应用到提交内容的编码过程中去的. 按照这个原来, 其实我们只需要重载 getRequestCharSet() 方法, 返回我们需要的编码(字符集)名称, 就可以解决 UTF-8 或者其它非默认编码提交 POST 请求时的乱码问题了.

    测试

    首先在 Tomcat 的 ROOT WebApp 下部署一个页面 test.jsp, 作为测试页面, 主要代码片段如下:

    <%@ page contentType="text/html;charset=UTF-8"%>

    <%@ page session="false" %>

    <%

    request.setCharacterEncoding("UTF-8");

    String val = request.getParameter("TEXT");

    System.out.println(">>>> The result is " + val);

    %>

    接着写一个测试类, 主要代码如下:

    public static void main(String[] args) throws Exception, IOException {

    String url = "http://localhost:8080/test.jsp";

    PostMethod postMethod = new UTF8PostMethod(url);

    //填入各个表单域的值

    NameValuePair[] data = {

    new NameValuePair("TEXT", "中文"),

    };

    //将表单的值放入postMethod中

    postMethod.setRequestBody(data);

    //执行postMethod

    HttpClient httpClient = new HttpClient();

    httpClient.executeMethod(postMethod);

    }

    //Inner class for UTF-8 support

    public static class UTF8PostMethod extends PostMethod{

    public UTF8PostMethod(String url){

    super(url);

    }

    @Override

    public String getRequestCharSet() {

    //return super.getRequestCharSet();

    return "UTF-8";

    }

    }

    运行这个测试程序, 在 Tomcat 的后台输出中可以正确打印出 ">>>> The result is 中文" .

    代码下载

    本文所提到的所有代码, 以及测试程序(可直接导入 eclipse)提供打包下载: att:HttpClient POST 的 UTF-8 编码问题.httpClientUTF8.tar.bz2
    }
    } else {
    return super.getRequestCharSet();
    }
    }

     

    参考资料:http://thinkbase.net/w/main/Wiki?HttpClient+POST+%E7%9A%84+UTF-8+%E7%BC%96%E7%A0%81%E9%97%AE%E9%A2%98

  • 相关阅读:
    OCP-1Z0-053-V12.02-597题
    OCP-1Z0-053-V12.02-599题
    OCP-1Z0-053-V12.02-609题
    OCP-1Z0-053-V12.02-604题
    OCP-1Z0-053-V12.02-607题
    OCP-1Z0-053-V12.02-588题
    OCP-1Z0-053-V12.02-592题
    OCP-1Z0-053-V12.02-587题
    OCP-1Z0-053-V12.02-582题
    OCP-1Z0-053-V12.02-583题
  • 原文地址:https://www.cnblogs.com/lexus/p/2797401.html
Copyright © 2011-2022 走看看