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(); } }