HttpClient测试类请求端和服务端即可能出现乱码的解决
?
junit HttpClient 請求端 代碼:
package com.taotao.httpclient;import java.util.ArrayList; import java.util.List;import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicHeader; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.junit.Test;public class HTTPClientGTest2 {//不帶參數的get請求 @Testpublic void doGet() throws Exception {//創建一個可關閉的httpClient對象CloseableHttpClient httpClient = HttpClients.createDefault();//創建一個get對象HttpGet get = new HttpGet("http://localhost:8083/search/doGet/哈哈");//注意,如果請求這里設置了 Accept header,那么 服務層的Controller 中的Mapping上就可以不用 produces屬性,但是如果這樣設置,那么Controller方法的返回值只能是String,否則結果無法封裝會調用者get.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8"));//執行請求CloseableHttpResponse response = httpClient.execute(get);//取響應結果//先獲取響應碼int statusCode = response.getStatusLine().getStatusCode();System.out.println("======響應碼:"+statusCode); //200//獲取響應結果對象HttpEntity entity = response.getEntity();//將結果對象轉換為字符串String string = EntityUtils.toString(entity,"utf-8");//結果:=======結果值:username: 張三 password: 123System.out.println("======結果值:"+string);//關閉資源 response.close();httpClient.close();}//帶參數的get請求 @Testpublic void doGetWithParam() throws Exception {//創建一個可關閉的httpClient對象CloseableHttpClient httpClient = HttpClients.createDefault();//帶參數方法1:直接拼接在請求中 創建get對象/*HttpGet get = new HttpGet("http://localhost:8083/search/doGetWithParam?username=花千骨&password=123");*///帶參數方法2 用對象的方式添加參數//先創建一個基本的(不帶參數的)uri對象URIBuilder uriBuilder = new URIBuilder("http://localhost:8083/search/doGetWithParam");uriBuilder.addParameter("username", "花千骨");uriBuilder.addParameter("password", "123");//再創建get對象HttpGet get = new HttpGet(uriBuilder.build());//注意,如果請求這里設置了 Accept header,那么 服務層的Controller 中的Mapping上就可以不用 produces屬性,但是如果這樣設置,那么Controller方法的返回值只能是String,否則結果無法封裝會調用者get.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8"));//執行請求CloseableHttpResponse response = httpClient.execute(get);//取響應結果//先獲取響應碼int statusCode = response.getStatusLine().getStatusCode();System.out.println("======響應碼:"+statusCode);//獲取響應結果對象HttpEntity entity = response.getEntity();//將結果對象轉換為字符串String string = EntityUtils.toString(entity,"utf-8");//======結果值:username: 花千骨 password: 123System.out.println("======結果值:"+string);//關閉資源 response.close();httpClient.close();}//不帶參數的 post 請求 @Testpublic void doPost() throws Exception {CloseableHttpClient httpClient = HttpClients.createDefault(); // HttpPost post = new HttpPost("http://localhost:8082/httpclient/post.html"); // 注意:如果請求的url后綴是 .html則瀏覽器不能返回正確的json數據,會返回406錯誤,所以需要修改請求url的后綴為其他 // HttpPost post = new HttpPost("http://localhost:8082/httpclient/post.action");HttpPost post = new HttpPost("http://localhost:8083/search/doPost/哈哈");//注意,如果請求這里設置了 Accept header,那么 服務層的Controller 中的Mapping上就可以不用 produces屬性post.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8"));CloseableHttpResponse response = httpClient.execute(post);HttpEntity entity = response.getEntity();String string = EntityUtils.toString(entity, "utf-8");System.out.println(string);response.close();httpClient.close();}//帶參數的post請求 @Testpublic void doPostWithParam() throws Exception {CloseableHttpClient httpClient = HttpClients.createDefault();//創建一個post對象HttpPost post = new HttpPost("http://localhost:8083/search/doPostWithParam");//注意,如果請求這里設置了 Accept header,那么 服務層的Controller 中的Mapping上就可以不用 produces屬性,但是如果這樣設置,那么Controller方法的返回值只能是String,否則結果無法封裝會調用者post.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8"));//模擬一個表單List<NameValuePair> kvList = new ArrayList<NameValuePair>();kvList.add(new BasicNameValuePair("username", "張三"));kvList.add(new BasicNameValuePair("password", "123"));//包裝成一個Entity對象(后面加字符集是為了向服務端發送數據時不會亂碼)StringEntity paramEntity = new UrlEncodedFormEntity(kvList,"utf-8");//設置請求內容 post.setEntity(paramEntity);//執行post請求CloseableHttpResponse response = httpClient.execute(post);HttpEntity rtnEntity = response.getEntity();String string = EntityUtils.toString(rtnEntity, "utf-8");System.out.println(string);response.close();httpClient.close();} }?
對應的? springMVC 的 Controller? 端代碼:
package com.taotao.search.controller;import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;@Controller public class HttpClientController {//無參數的get請求/*prodcues的目的是為了返回給調用者時中文不亂碼,* 如果接口調用者請求的 http對象設置了* httpget.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8"));* 那么這里服務端可以不加produces,否則必須加*/@RequestMapping(value="/doGet/{pid}",produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")@ResponseBodypublic String doGet(@PathVariable String pid){System.out.println("============== "+pid); //這里不會亂碼 哈哈String username = "張三";String password = "123";String result = "username: "+username+"\tpassword: "+password;return result;}//帶參數的get請求響應/*** 同理,如果 接口調用者中 沒有加 setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8")* 這里必須加上 produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8"*/@RequestMapping(value="/doGetWithParam",produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")@ResponseBodypublic String doGetWithParam(String username,String password) throws Exception{//====== username: è±?éa¨password: 123System.out.println("====== username: "+username +"password: "+password);//為了避免亂碼我們需要轉碼(帶參數的 get 請求,必須在這里轉碼)username = new String(username.getBytes("iso8859-1"), "utf-8");password = new String(password.getBytes("iso8859-1"), "utf-8");//===轉碼后=== username: 花千骨password: 123System.out.println("===轉碼后=== username: "+username +"password: "+password);String result = "username: "+username+"\tpassword: "+password;return result;}//不帶參數的 post請求@RequestMapping(value="/doPost/{pid}",produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8")@ResponseBodypublic String doPost(@PathVariable String pid){System.out.println("============== "+pid); //哈哈String username = "張三";String password = "123";String result = "username: "+username+"\tpassword: "+password;return result;}//帶參數的 post 請求/*** 同理,如果 接口調用者中 沒有加 setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8")* 這里必須加上 produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8"*///注意:post請求,后臺服務接收端不用對參數進行轉碼@RequestMapping(value="/doPostWithParam"/*,produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8"*/)@ResponseBodypublic String doPost(String username,String password){//====== username: 張三password: 123System.out.println("====== username: "+username +"password: "+password);String result = "username: "+username+"\tpassword: "+password;return result;} }?
注意項總結:
1、無論哪種請求//注意,如果請求端設置了 Accept header 例如:
?? ???? httpget.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8"));
那么 服務層的Controller 中的Mapping上就可以不用 produces屬性,否則服務端的Controller中比如加入:
produces=MediaType.TEXT_PLAIN_VALUE+";charset=utf-8"
這樣才能保證請求端接收到的結果中的中文編碼正確。
?
但是,如果請求端設置了 Accept header ,那么Controller的方法的返回值 只能是 String類型,否則結果無法封裝會調用者,
所有強烈建議不要這樣做,最好還是在 Controller端返回值為字符串時,設置 produces 屬性
?
2、對于帶參數的 get 請求,必須在服務端 Controller 中進行字符串轉碼 例如:
username = new String(username.getBytes("iso8859-1"), "utf-8");
否則接收到的參數就是亂碼
?
轉載于:https://www.cnblogs.com/libin6505/p/9817034.html
總結
以上是生活随笔為你收集整理的HttpClient测试类请求端和服务端即可能出现乱码的解决的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 福庆家具板仓有哪些支持?知情人透露一下
- 下一篇: oracle查询重复数据出现次数