使用apache的HttpGet\HttpPost获取返回内容编码问题

今天遇到了一个小问题,简单研究了一下,同时记录一下。

关于apache的HttpGet\HttpPost请求,做了一次访问,代码如下:

		String url = "http://xxxxxxx";
		HttpGet httpGet = new HttpGet(url);
		HttpClient httpClient = new DefaultHttpClient();
		try {		
			HttpResponse httpResponse = httpClient.execute(httpGet);		
			HttpEntity httpEntity = httpResponse.getEntity();
			//String result = EntityUtils.toString(httpEntity, "utf-8");
			InputStream is = null;
			is = httpEntity.getContent();
			BufferedReader reader = new BufferedReader(new InputStreamReader(is));
			String result = "";
			String line = "";
			while ((line = reader.readLine()) != null) {
				result = result + line;
			}
			System.out.println(result);
		} catch (Exception e) {
			e.printStackTrace();
		} 

结果出现了乱码。立刻对代码进行修改BufferedReader reader = new BufferedReader(new InputStreamReader(is, "utf-8"));

依旧出现乱码,到底是哪里出问题?

如果用第7行的方式来获取的话就不会有乱码。

第7行的方法很简单,深入研究下实际上也是获取流进行处理,只是在过程中加入了编码处理,那么到底是怎么处理的?

该方法源码如下:

		public static String toString(
			            final HttpEntity entity, final String defaultCharset) throws IOException, ParseException {
			        if (entity == null) {
			            throw new IllegalArgumentException("HTTP entity may not be null");
			        }
			        InputStream instream = entity.getContent();
			        if (instream == null) {
			            return "";
			        }
			        if (entity.getContentLength() > Integer.MAX_VALUE) {
			            throw new IllegalArgumentException("HTTP entity too large to be buffered in memory");
			        }
			        int i = (int)entity.getContentLength();
			        if (i < 0) {
			            i = 4096;
			        }
			        String charset = getContentCharSet(entity);
			        if (charset == null) {
			            charset = defaultCharset;
			        }
			        if (charset == null) {
			            charset = HTTP.DEFAULT_CONTENT_CHARSET;
			        }
			        Reader reader = new InputStreamReader(instream, charset);
			        CharArrayBuffer buffer = new CharArrayBuffer(i);
			        try {
			            char[] tmp = new char[1024];
			            int l;
			            while((l = reader.read(tmp)) != -1) {
			                buffer.append(tmp, 0, l);
			            }
			        } finally {
			            reader.close();
			        }
			        return buffer.toString();
			    } 

可以看见是在InputStreamReader这里处理的。和我处理的地方是一致的,那么还有什么问题?

后来仔细一看发现toString()方法传入的编码方式未必就是最后使用的,这中间还有个判断,就是判断HttpEntity返回的header是否存在charset,不存在才会使用传入的参数。

本来我一直认为这个参数就应该是utf-8,结果用EntityUtils的getContentCharSet方法一获取才发现是GBK。。。

这下就清楚了,修改代码BufferedReader reader = new BufferedReader(new InputStreamReader(is, "gbk"));

这回不是乱码了,不过这部分应该在前面做好判断,先用getContentCharSet获取一下,如果是空再自己设定一个才好。

至于getContentCharSet方法如何实现的,代码如下:

		public static String getContentCharSet(final HttpEntity entity)
	         throws ParseException {
	  
	         if (entity == null) {
	             throw new IllegalArgumentException("HTTP entity may not be null");
	         }
	         String charset = null;
	         if (entity.getContentType() != null) {
	             HeaderElement values[] = entity.getContentType().getElements();
	             if (values.length > 0) {
	                 NameValuePair param = values[0].getParameterByName("charset");
	                 if (param != null) {
	                     charset = param.getValue();
	                 }
	             }
	         }
	         return charset;
	     } 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BennuCTech

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值