博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HTTPCLIENT 解决乱码方案 - linfeng_0212的日志 - 网易博客
阅读量:6589 次
发布时间:2019-06-24

本文共 3598 字,大约阅读时间需要 11 分钟。

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 = "

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://eeqno.baihongyu.com/

你可能感兴趣的文章
20160309作业
查看>>
python之路----文件操作
查看>>
探索MySQL高可用架构之MHA(1)
查看>>
tableView 的协议方法
查看>>
海量路由表的快速检索问题-Hash/Trie/快速交换
查看>>
BizTalk Orchestration execute Flat file disassembler ReceivePipeline
查看>>
我的友情链接
查看>>
只需三步轻松搞定 Foxmail 发送邮件“错误信息 ssl连接错误 error code 5”
查看>>
使用openssl加密文件
查看>>
启动ssh服务报错
查看>>
AIX系统中如何查看HBA卡的WWPN和微码版本
查看>>
check the manual that corresponds to your MySQL server version for the right syntax to use near
查看>>
spring创建连接池的几种方式
查看>>
在JSTL EL中处理java.util.Map,及嵌套List集合
查看>>
我的友情链接
查看>>
LAMP之网站搭建(二)
查看>>
nginx-负载均衡
查看>>
linux学习计划
查看>>
GCE 部署 ELK 7.1可视化分析 nginx
查看>>
Rancher2.0中邮件通知的设置
查看>>