JSON格式数据的优点:
A.数据格式比较简单,易于读写,格式都是压缩的,占用带宽小,是非常轻量级的数据格式;
B.易于解析,客户端JavaScript可以简单的通过eval()进行JSON数据的读取;
C.支持多种语言,其中在Java端有丰富的工具操作和解析JSON;
D.因为JSON格式能直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,且完成任务不变,并且易于维护;
由于有以上的优点,因此在项目当中,项目当中的数据通信一般都采用的是json格式的数据。在使用HttpClient调用接口的时候,就涉及如何发送和接收JSON格式的数据,操作如下:
第一步:引入maven依赖
org.apache.httpcomponents
httpclient
4.5.2
第二步:写两个接口,第一个不接收参数直接返回json数据用来测试GET请求,第二个接收json数据返回json数据用来测试POST请求。
//直接返回json格式的字符串
@RequestMapping("/testGet")
@ResponseBody
public String testGet(){
Map 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 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 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();
}
}