JSON格式數據的優點:
A.數據格式比較簡單,易於讀寫,格式都是壓縮的,佔用帶寬小,是非常輕量級的數據格式;
B.易於解析,客戶端JavaScript可以簡單的通過eval()進行JSON數據的讀取;
C.支持多種語言,其中在Java端有豐富的工具操作和解析JSON;
D.因爲JSON格式能直接爲服務器端代碼使用,大大簡化了服務器端和客戶端的代碼開發量,且完成任務不變,並且易於維護;
由於有以上的優點,因此在項目當中,項目當中的數據通信一般都採用的是json格式的數據。在使用HttpClient調用接口的時候,就涉及如何發送和接收JSON格式的數據,操作如下:
第一步:引入maven依賴
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
第二步:寫兩個接口,第一個不接收參數直接返回json數據用來測試GET請求,第二個接收json數據返回json數據用來測試POST請求。
//直接返回json格式的字符串
@RequestMapping("/testGet")
@ResponseBody
public String testGet(){
Map<String,String> map = Maps.newHashMap();
map.put("paramF","第一個參數");
map.put("paramS","第二個參數");
return ApiResponse.buildSuccessResponse(ResultConstant.OPERATOR_SUCCESS,ResultConstant.MESSAGE_OPERATE_SUCCESS,map);
}
//接收json格式的字符串並返回json格式的字符串
@RequestMapping("/testPost")
@ResponseBody
public String testPost(@RequestBody(required = false)String requestJson){
try{
JSONObject jsonObject = JSON.parseObject(requestJson);
logger.info("接收到的消息是:"+jsonObject.toJSONString());
Map<String,String> map = Maps.newHashMap();
map.put("paramF","第一個參數");
map.put("paramS","第二個參數");
return ApiResponse.buildSuccessResponse(ResultConstant.OPERATOR_SUCCESS,ResultConstant.MESSAGE_OPERATE_SUCCESS,map);
}
catch (Exception e){
return ApiResponse.buildFailResponse(ResultConstant.OPERATOR_FAIL,ResultConstant.MESSAGE_SYSTEM_EXCEPTION);
}
}
public class ApiResponse implements Serializable {
//狀態碼
private Integer statusCode;
//返回消息
private String message;
//返回對象
private Object data;
public static String buildFailResponse(Integer statusCode, String message)
{
return JSONObject.toJSONString(new ApiResponse(statusCode,message,"NULL"));
}
public static String buildSuccessResponse(String message)
{
return JSONObject.toJSONString(new ApiResponse(ResultConstant.OPERATOR_SUCCESS,message,"NULL"));
}
public static String buildSuccessResponse(Integer statusCode, Object data)
{
return JSONObject.toJSONString(new ApiResponse(ResultConstant.OPERATOR_SUCCESS,"NULL",data));
}
public static String buildSuccessResponse(Integer statusCode,String message, Object data)
{
return JSONObject.toJSONString(new ApiResponse(ResultConstant.OPERATOR_SUCCESS,message,data));
}
public ApiResponse(Integer statusCode, String message, Object data) {
this.statusCode = statusCode;
this.message = message;
this.data=data;
}
public ApiResponse(Integer statusCode, String message) {
this.statusCode = statusCode;
this.message = message;
}
public ApiResponse() {
}
public Integer getStatusCode() {
return statusCode;
}
public void setStatusCode(Integer statusCode) {
this.statusCode = statusCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
return "ApiResponse{" +
"statusCode=" + statusCode +
", Message='" + message + '\'' +
", data=" + data +
'}';
}
}
第三步:使用HttpClient來發送請求獲取數據,分別測試GET和POST
//CloseableHttpClient:建立一個可以關閉的httpClient
//這樣使得創建出來的HTTP實體,可以被Java虛擬機回收掉,不至於出現一直佔用資源的情況。
CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
//設置請求超時時間
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(60000)
.setConnectTimeout(60000)
.setConnectionRequestTimeout(60000)
.build();
try {
String url = "http://localhost:8012/testGet";//我的項目運行在8012端口
HttpGet request = new HttpGet(url);
//給這個請求設置請求配置
request.setConfig(requestConfig);
request.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) ...");
CloseableHttpResponse response = closeableHttpClient.execute(request);
if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
String result = EntityUtils.toString(response.getEntity());// 返回json格式:
logger.info("GET返回過來的信息是:"+result);
}
}
catch (Exception e){
logger.info("發生了異常:"+e.getMessage());
}
finally {
try { //關閉流並釋放資源
closeableHttpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
得到的logger記錄如下:
GET返回過來的信息是:{"data":{"paramF":"第一個參數","paramS":"第二個參數"},"message":"操作成功","statusCode":100}
//CloseableHttpClient:建立一個可以關閉的httpClient
//這樣使得創建出來的HTTP實體,可以被Java虛擬機回收掉,不至於出現一直佔用資源的情況。
CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
//設置請求超時時間
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(60000)
.setConnectTimeout(60000)
.setConnectionRequestTimeout(60000)
.build();
try {
HttpPost post = new HttpPost("http://localhost:8012/testPost");
post.setConfig(requestConfig);
//發送的參數數據
Map<String,String> map = Maps.newHashMap();
map.put("content","wwgfgfbb");
map.put("value","rerrrh");
//設置發送的數據
StringEntity s = new StringEntity(JSON.toJSONString(map));
s.setContentEncoding("UTF-8");
s.setContentType("application/json");//發送json數據需要設置contentType
post.setEntity(s);
//獲取返回值
CloseableHttpResponse res = closeableHttpClient.execute(post);
if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
String result = EntityUtils.toString(res.getEntity());// 返回json格式:
logger.info("POST請求返回的數據是:"+result);
}
}
catch (Exception e){
logger.info("發生了異常:"+e.getMessage());
}
finally {
try { //關閉流並釋放資源
closeableHttpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
POST請求在接口端的日誌記錄:
接收到的消息是:{"value":"rerrrh","content":"wwgfgfbb"}
在請求端接收到的消息:
POST請求返回的數據是:{"data":{"paramF":"第一個參數","paramS":"第二個參數"},"message":"操作成功","statusCode":100}
通過以上的測試,都能夠正確的發送和接收JSON格式數據。
我們還可以配置CloseableHttpClient交給spring去管理,需要的時候直接給注入就行了。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.context.annotation.Scope;
@Configuration
public class HttpClientConfig {
@Bean
public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
poolingHttpClientConnectionManager.setMaxTotal(10);
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(5);
return poolingHttpClientConnectionManager;
}
@Bean
public HttpClientBuilder httpClientBuilder() {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager());
return httpClientBuilder;
}
@Bean
@Scope("prototype")
public CloseableHttpClient closeableHttpClient() {
return httpClientBuilder().build();
}
}