HttpClient数据传输的编码方式

约定
1. HttpClient版本:HttpClient4.1
2. 服务端中间件:tomcat7
HttpGet请求的URI编码设置
1. 问题及原因
使用HttpClient的HttpGet方法进行get请求时,如果请求的URI中含有中文参数,则请求的服务端容易出现乱码问题。出现乱码的原因主要是因为请求URI中中文参数的编码和tomcat设置的编码不一致,导致乱码。
2. 解决方案
1) 设置tomcat编码
首先必须确定tomcat采用何种编码,才能确定请求的URI设置为何种编码。Tomcat的编码设置在tomcat的配置文件中设置,位置为: apache-tomcat-7.0.11\conf\server.xml,找到如下配置:

<Connector 
port="8181"
protocol="HTTP/1.1" 
connectionTimeout="20000" 
redirectPort="8443"  
URIEncoding="GB2312"/>

Tomcat默认是没有对URIEncoding进行配置,tomcat会采用默认的编码,一般是ISO-8859-1。
2) 设置URI编码
知道了tomcat(请求服务端)的编码方式,使用HttpGet请求时就需要对URI中的中文参数进行编码。上面设置了URIEncoding=”GB2312”,所以我们需要对中文参数进行GB2312的URI编码。例如:

HttpClient http = new DefaultHttpClient();
        String url = "http://127.0.0.1:8181/hello/httpclient?test=" + URLEncoder.encode("中文", "utf-8");
HttpGet get = new HttpGet(url);
HttpResponse response = http.execute(get);

这样服务端接收到HttpGet的请求,中文参数就不会出现乱码了。
HttpPost请求的URI及数据编码
1. 问题及原因
使用HttpClient的HttpPost方法进行Post请求时与Get不同的是,Post不仅有URI参数,还有请求body数据,如果这两种数据出现中文都有可能出现乱码。其中URI参数出现乱码的原因与上述Get方法出现乱码的原因相同,这里就不在叙述。Body数据出现乱码的原因则是请求数据的编码方式与服务端程序的解码方式不一致导致。
2. 解决方案
1) HttpClient端Post请求的编码设置

HttpClient http = new DefaultHttpClient();
String url = "http://127.0.0.1:8181/hello/httpclient?test=" + URLEncoder.encode("中文", "gb2312");
HttpPost post = new HttpPost(url);
JSONObject params = new JSONObject();
params.put("a", "测试1");
params.put("b", "测试2");
System.out.println(params.toString());
StringEntity entity = new StringEntity(params.toString(),"gb2312");
entity.setContentType("application/json;charset=gb2312");
post.setEntity(entity);
HttpResponse response = http.execute(post);

代码中

StringEntity entity = new StringEntity(params.toString(),"gb2312");

设置了以gb2312编码对数据进行编码。

如果不传入编码方式

new StringEntity(params.toString())

则会以默认的编码方式进行编码,一般是ISO-8859-1,这种编码无法表示中文字符,所以如果不进行设置,中文会出现乱码。

entity.setContentType("application/json;charset=gb2312");

设置请求的content-type,如果不设置,默认会根据

new StringEntity(params.toString(),"gb2312");

的编码方式来设置,text/plain;charset= gb2312
2) 服务端代码的解码

public void httpclientPost(HttpServletRequest req,HttpServletResponse resp) throws Exception {
        String a = req.getParameter("test");
        System.out.println("URI参数: test=" + a);
        System.out.println("req-content-type: " + req.getContentType() + "\ncharset: " + req.getCharacterEncoding());

        InputStream in = req.getInputStream();
        List<Byte> dataList = new ArrayList<Byte>();
        byte[] buffer = new byte[8*1024];
        while(in.read(buffer)>0){
            for(int i=0; i<buffer.length;++i){
                dataList.add(buffer[i]);
            }
        };
        byte[] data = new byte[dataList.size()+1];
        for(int i=0; i<dataList.size(); ++i){
            data[i] = dataList.get(i);
        }
System.out.println(new String(data,req.getCharacterEncoding()));
}

运行结果如下:

URI参数: test=中文
req-content-type: application/json;charset=gb2312
charset: gb2312
{"a":"测试1","b":"测试2"}

可以看到

new String(data,req.getCharacterEncoding())

这里使用请求中的数据编码方式来从数据流中生成对应的字符串,这样得到的中文数据就不会出现乱码了。
HttpClient请求响应数据中文乱码
1. 问题及原因
使用HttpClient的Get或Post方法请求得到的响应数据中的中文出现乱码。出现乱码的原因主要是因为对得到的响应数据解码方式和服务端的编码方式不一致。
2. 解决方案
1) 服务端设置返回数据的编码方式

public void httpclient(HttpServletRequest req,HttpServletResponse resp) throws Exception {
resp.setContentType("text/html;charset=gb2312");
        resp.setCharacterEncoding("gb2312");
        resp.getWriter().println("response返回中文");
}

setContentType与setCharacterEncoding都可以设置编码方式,但是必须调用setContentType来设置content-type,后面会说明原因。
2) HttpClient请求得到响应后解码

HttpResponse response = http.execute(get);
if (response.getStatusLine().getStatusCode() == 200) { 
    HttpEntity entity = response.getEntity();
    Header header = entity.getContentType();
    String strResp = EntityUtils.toString(response.getEntity());
    System.out.println(strResp);
}

这里的EntityUtils.toString()方法将得到的数据转换为字符串,那么就必须要考虑所使用的字符编码。如果在EntityUtils.toString()方法中没有显式的传入字符编码方式的参数,那么该方法就会根据response.getEntity()的ContentType的编码方式来进行解码。Header header = entity.getContentType();这个方法就可以获取entity的content-type。但是,如果服务端没有设置Content-Type,也就是在上面的服务端程序中没有调用setContentType()方法,那么这里获取的header将是null,也就是说无法获取到entity的Content-Type。那么EntityUtils.toString()方法也就无法知道服务端传过来的数据采用的何种编码方式,就会采用默认的ISO-8859-1编码方式进行转换,这样中文就会出现乱码。当然,也可以显式将编码方式传入EntityUtils.toString()函数中,但是必须确保传入的编码方式与服务端设置的返回数据的编码方式相同,EntityUtils.toString(response.getEntity(),”gb2312”);

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 答:使用Apache HttpClient可以实现这一目标。首先,你需要创建一个HttpClient实例,并配置它以支持大量数据传输。然后,使用HttpClient的execute方法,创建一个HttpPost对象,并将要传输的数据设置到HttpPost对象中,最后调用HttpClient的execute方法,发出HTTP请求,实现数据的传输。 ### 回答2: 在Java中,可以使用Apache HttpClient库来进行HTTP请求和响应的操作。下面是使用Java接口httpclient传输大量数据的示例代码: ```java import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.*; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import java.io.*; import java.util.ArrayList; import java.util.List; public class HttpClientExample { public static void main(String[] args) { String url = "http://example.com/post"; List<String> data = getData(); // 假设data为大量数据的集合 try { HttpClient client = HttpClientBuilder.create().build(); HttpPost post = new HttpPost(url); post.setEntity(new UrlEncodedFormEntity(data)); HttpResponse response = client.execute(post); HttpEntity entity = response.getEntity(); if (entity != null) { InputStream inputStream = entity.getContent(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } client.getConnectionManager().shutdown(); } catch (IOException e) { e.printStackTrace(); } } private static List<String> getData() { List<String> data = new ArrayList<>(); // 添加大量数据到data中 return data; } } ``` 上述代码使用ApacheHttpClient库创建了一个HttpClient实例,并通过HttpPost方法发送POST请求到指定的URL。使用`setEntity()`方法将数据添加到POST请求中。在本例中,使用`new UrlEncodedFormEntity(data)`将数据以表单编码的方式添加到请求中。如果数据是JSON格式的,可以使用`new StringEntity(data, ContentType.APPLICATION_JSON)`将数据作为JSON字符串添加到请求中。 执行POST请求后,通过获取响应的实体`HttpResponse.getEntity()`,可以得到服务器返回的数据。在本例中,使用`getContent()`方法获取输入流,并通过BufferedReader以行的形式读取返回的数据。 最后,最好在使用完HttpClient之后调用`client.getConnectionManager().shutdown()`方法释放相关的资源。 需要注意的是,传输大量数据时可能会遇到一些问题,例如超时、内存不足等。可以根据实际情况调整HttpClient的参数和配置,以确保传输过程的稳定性和性能。 ### 回答3: 在Java中使用HttpClient传输大量数据可以按照以下步骤进行: 1. 引入HttpClient库:首先,在Java工程中引入HttpClient库。可以通过在pom.xml文件中添加相应的依赖项来导入。 2. 创建HttpClient对象:使用HttpClientBuilder类创建一个HttpClient对象,该对象将用于发送HTTP请求。 ```java CloseableHttpClient httpClient = HttpClients.createDefault(); ``` 3. 创建HttpPost请求:创建一个HttpPost请求对象,并设置请求的URL和其他头部信息。如果有需要,还可以设置代理、身份验证、连接超时等。 ```java HttpPost httpPost = new HttpPost(url); httpPost.setHeader("Content-Type", "application/json"); httpPost.setEntity(new StringEntity(jsonData)); ``` 4. 设置请求体:如果需要发送大量数据,可以将数据作为请求体传递。可以使用StringEntity、FileEntity等类来设置请求体。 ```java httpPost.setEntity(new StringEntity(data, ContentType.TEXT_PLAIN)); ``` 5. 发送请求并获取响应:通过执行HttpPost请求对象发送请求,并获取响应对象。可以使用CloseableHttpResponse类来接收响应。 ```java CloseableHttpResponse response = httpClient.execute(httpPost); ``` 6. 解析响应:从响应对象中获取相应的数据,可以通过EntityUtils类将响应体转换为字符串。 ```java HttpEntity entity = response.getEntity(); String responseString = EntityUtils.toString(entity, "UTF-8"); ``` 7. 关闭连接:使用完毕后,需要关闭连接和释放资源。 ```java response.close(); httpClient.close(); ``` 以上是使用HttpClient传输大量数据的基本步骤。根据实际需求,可能还需要处理异常、设置重试机制、添加请求头等其他操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值