`
zhangzcz1999
  • 浏览: 147578 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

转:HttpClient POST 的 UTF-8等编码问题

阅读更多
Apache HttpClient ( 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 中找到了 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 中文"
分享到:
评论
1 楼 f_zongjian 2009-06-01  
HttpClient3.1中没有遇到此类问题了。

不过自己在服务端发送响应信息给请求端的时候犯了个错误:
PrintWriter out = resp.getWriter();//(1)
resp.setContentType("text/xml;charset=utf-8");//(2)
out.write("zhongwen中文");
这样是以默认的ISO-8859-1格式发送信息,请求端获取到的可能就是"zhongwen????"。
如果(1)(2)顺序换一下,那样就能以utf-8的格式发往请求端,对方接收到的就是正常的"zhongwen中文"。

相关推荐

    android POST数据遇到的UTF-8编码(乱码)问题解决办法

    这里我们详细探讨一下如何解决Android POST数据时遇到的UTF-8编码(乱码)问题。 首先,问题的根源在于客户端发送的数据未指定正确的字符编码,导致服务器在接收到数据并尝试以UTF-8格式解码时出现错误。在示例中,...

    commons-httpclient-3.1短信发送包

    4. 参数编码:在设置请求参数时,确保正确地对字符串进行URL编码,防止乱码问题。 总结,Apache Commons HttpClient 3.1是一个功能强大的HTTP客户端库,虽然在现代开发中可能有更先进的选择,但它仍能满足基本的...

    HttpClient、乱码解决:实例

    entity.getContentEncoding().getValue() : "UTF-8"; String responseBody = EntityUtils.toString(entity, encoding); // 处理responseBody ``` 通过上述步骤,你应该能有效地解决HttpClient在发送和接收数据时...

    解决HttpClient中文乱码问题jar文件

    默认情况下,HttpClient可能使用ISO-8859-1作为编码,而我们的中文字符通常需要UTF-8编码才能正确显示。以下是一些解决HttpClient中文乱码问题的关键知识点: 1. **设置字符编码**:在发送HTTP请求时,我们需要确保...

    commons-httpclient.zip

    httpMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8"); // 发送请求 int statusCode = httpClient.executeMethod(httpMethod); // 检查状态码 if (statusCode == ...

    使用HttpClient发送POST请求,并获取响应内容(附详细步骤).txt

    - 使用`StringEntity`对象包装该字符串,并设置编码为UTF-8。 - 将`StringEntity`对象设置为HttpPost对象的实体。 5. **执行请求**: - 使用HttpClient实例执行HttpPost对象代表的请求。 - 获取HttpResponse...

    httpclient.post例子

    StringEntity entity = new StringEntity("{\"key\":\"value\"}", "UTF-8"); entity.setContentType("application/json"); httpPost.setEntity(entity); ``` 这里以JSON格式为例,创建了一个包含键值对的实体,...

    httpclient 4.2.2

    String responseBody = EntityUtils.toString(entity, StandardCharsets.UTF_8); ``` 5. **关闭资源**:完成操作后,别忘了关闭 HttpClient 和响应对象以释放资源。 ```java response.close(); httpClient.close()...

    最新3.3支付宝即时到账交易接口demo源码c#-utf-8源码

    在本文中,我们将深入探讨如何使用C#语言和UTF-8编码来实现这个接口的Demo源码。 首先,`create_direct_pay_by_user`是支付宝接口中的一个关键方法,用于创建并执行即时到账交易。此接口主要由以下几个步骤组成: ...

    httpclient发送post请求.docx

    这里的UrlEncodedFormEntity用于编码和设置请求实体,包含NameValuePairs列表,而Consts.UTF_8确保数据使用UTF-8编码。 3. 发送请求和处理响应: 发送POST请求使用httpClient的execute()方法,并捕获返回的...

    java HttpClient 发送GET请求和带有表单参数的POST请求教程例子

    - 在处理响应时,注意编码问题,例如上述代码中的“UTF-8”。 - 如果在生产环境中使用,建议使用`CloseableHttpClient`代替`DefaultHttpClient`,以利用其更好的资源管理机制。 通过上述示例和解释,你应该能够理解...

    HttpClient实现POST GET和文件下载

    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8"); httpPost.setEntity(entity); ``` 文件下载则涉及HttpEntity和FileOutputStream的使用。首先,获取响应中的HttpEntity,然后通过...

    彻底解决httpClient乱码问题

    此时,需要编写健壮的异常处理代码,以应对这些情况,比如使用默认的编码(如UTF-8)或者尝试其他常见编码。 综上所述,解决HttpClient乱码问题涉及多个环节,包括正确设置字符编码、理解HTTP头信息、自定义...

    HttpClient发送http请求(post+get)需要的jar包+内符java代码案例+注解详解

    String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8"); System.out.println("响应状态码:" + response.getStatusLine().getStatusCode()); System.out.println("响应内容:" + ...

    HttpClient应用实例2

    在发送POST请求时,特别是包含中文字符的表单数据,我们需要使用`URLEncoder.encode()`方法将中文字符转换为URL友好的格式,并指定UTF-8编码。例如: ```java String param = "中文参数"; String encodedParam = ...

    一个使用HttpClient调用天气预报接口的例程

    在Android中,如果服务器返回的数据不是UTF-8编码,而使用了GBK,那么在处理文本时需要进行正确的字符编码转换,以防止乱码问题。 5. **源码解析**: - `HttpGet`对象:创建一个HttpGet实例,设置其请求URL,用于...

    c#post multipart/form-data和JSON数据

    1. **编码问题**:确保正确设置字符编码,如UTF-8,以避免数据传输过程中的乱码问题。 2. **错误处理**:对于HTTP响应,应检查其状态码,处理可能出现的错误情况,如400 Bad Request或500 Internal Server Error。 3...

    解决了中文乱码的http的get和post请求demo

    因此,我们需要明确指定为UTF-8编码,例如: ```java String param = "中文参数"; String encodedParam = URLEncoder.encode(param, "UTF-8"); ``` 然后将编码后的参数添加到URL。 2. **POST请求中的中文乱码*...

    httpclient测试登录并提交表单功能

    2. **`UTF8PostMethod`** 类:自定义类用于支持UTF-8编码的POST请求。 ##### `HttpTest` 类详解 - **静态变量初始化**: - `CONN`:创建一个`HttpClient`对象用于发送HTTP请求。 - `DATA_ACTION`:表单提交的...

Global site tag (gtag.js) - Google Analytics