Java如何调用接口API并返回数据(两种方法)
java处理请求接口后返回的json数据-直接处理json字符串
处理思路:
将返回的数据接收到一个String对象中(有时候需要自己选择性的取舍接收)
再将string转换为JSONObject对象
用get()方法获取到对应的值
注意:基于第三点的特殊情况,如果返回的json里面出现多组数据的情况,则需要转换为数据(用JSONObject.parseArrat()转换再进行操作 ,可无限套娃)
调用接口,请求数据
1.post方法
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
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.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;import java.io.IOException;
import java.net.URI;
import java.util.*;
public static JSONObject postResponse(String url,JSONObject jsonParam){HttpClient client = HttpClients.createDefault();
// 要调用的接口方法HttpPost post = new HttpPost(url);JSONObject jsonObject = null;try {StringEntity s = new StringEntity(jsonParam.toString(),"UTF-8");s.setContentType("application/json");post.setEntity(s);post.setHeader("Content-Type","application/json");HttpResponse res = client.execute(post);if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK){/*返回json格式*/jsonObject = JSONObject.parseObject(EntityUtils.toString(res.getEntity()));}} catch (IOException e) {System.out.println("接口调用出错!");e.printStackTrace();throw new RuntimeException(e);}return jsonObject;}
2.get方法
import com.alibaba.fastjson.JSONObject;
import edu.zhku.fire_ant_project.config.WxConstant;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;public class HttpCallOtherInterfaceUtils {public static void main(String args[]) {HttpClient client = HttpClients.createDefault();// 要调用的接口方法String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ WxConstant.appid +"&secret="+WxConstant.secret;HttpGet httpGet=new HttpGet(url);JSONObject jsonObject = null;try {HttpResponse res = client.execute(httpGet);if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {// 返回json格式:jsonObject = JSONObject.parseObject(EntityUtils.toString(res.getEntity()));System.out.println(jsonObject);}} catch (Exception e) {System.out.println("服务间接口调用出错!");e.printStackTrace();}}
}
处理返回后的json数据
参考代码:
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;public class JsonStr {public static void main(String[] args) {//1.比如从前端接收的是这个样子的json字符串,但是我们是不能直接获取到经度 纬度所对应的值的,所以必须要对这个字符串进行解析,String str = "{\"code\":\"0\"," +"\"error\":null," +"\"msg\":\"success\"," +"\"detail\":[\n" +" {\"phoneNum\":\"013012401091\",\n" +" \"lat\":34.431864,\n" +" \"lon\":109.25992,\n" +" \"height\":360,\n" +" \"speed\":33,\n" +" \"direction\":10,\n" +" \"gpsTime\":1615420800000,\n" +" \"gpsDateTime\":1615420800000,\n" +" \"mileage\":253830800,\n" +" \"alarms\":[24],\n" +" \"status\":[1,2,21],\n" +" \"property\":{}\n" +" }" +" ]" +" }";//先转换成JSONObject类型JSONObject jsonObj = JSON.parseObject(str);//通过JSONObject中的getString("key")方法,得到对应的值 {"code":"0","error":null,"msg":"success"}这种类型System.out.println("code:"+jsonObj.getString("code"));//2.字符串中含有数组的,比如像detail中的数据JSONArray jsonInfo = JSONObject.parseArray(jsonObj.getString("detail"));//将jsonObj解析成json数组for (int i = 0; i < jsonInfo.size(); i++) {//遍历detail信息JSONObject jsonDetailInfo = jsonInfo.getJSONObject(i);//根据下标以此拿数据,每一个数据又是一个JSONObject对象,所以用JSONObject接收String lat = jsonDetailInfo.getString("lat");String lon = jsonDetailInfo.getString("lon");String gpsDateTime = jsonDetailInfo.getString("gpsDateTime");//然后进行其他处理System.out.println("lat:"+lat+";lon:"+lon+";gpsDateTime:"+gpsDateTime);}}
}
例子: 请求数据要求分页 所以采取循环返回值说明:{"code": "200","data": {"endRow": 2,"firstPage": 1,"hasNextPage": true,"hasPreviousPage": false,"isFirstPage": true,"isLastPage": false,"lastPage": 8,"list": [{"packingUnit": "盒", //包装单位"factory": "河北百善药业有限公司", //生产企业"salePrice": 11.7, //销售价"fullSalePrice": 11.5, //整件销售价"inventoryQuantity": 172, //库存"pictureUrl": "/upload/product/pic/2021/11/20101013-2-424389.png", //商品图片"policyTitle": "10盒起积0.5分/盒,20盒起积1分/盒",//商品政策:比如10盒积1分意思是10盒每盒减1元,10s5:表示买10盒送5盒"policyStartDate": "2022-11-01",//商品政策开始日期"policyEndDate": "2022-11-30",//商品政策结束日期"validDateStr": "2024-09-07",//最近批号有效期"batchNumber": "2207012", //最近批号"registerFileUrl": "https://img.zc511.com/data/uploadRegisterFileOne.shtml?productCode=20101013-2", // 注册资料下载URL"authorizeNumber": "国药准字Z20063720","rowId": 1,"barCode": "6909557000263",//商品条码"parseProductName": "接骨片",//商品名称"productCode": "20101013-2",//商品条码"countryCode": "ZG01AAJ0247010302685",//国家码 医保码"packingAmount": 200,//大包装"parseProductSpec": "60片",//规格"retailPrice": 196,//市场零售价"minPackingNumber": 0//最小购买包装}],"navigatePages": 8,"navigatepageNums": [1,2,3,4,5,6,7,8],"nextPage": 2,"pageNum": 1,"pageSize": 2,"pages": 5627,"prePage": 0,"size": 2,"startRow": 1,"total": 11254},"msg": "","success": true
}
HttpCilentutil
请求接口数据
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
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.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;import java.io.IOException;
import java.net.URI;
import java.util.*;
public class HttpClientUtil
{public static JSONObject postResponse(String url,JSONObject jsonParam){HttpClient client = HttpClients.createDefault();
// 要调用的接口方法HttpPost post = new HttpPost(url);JSONObject jsonObject = null;try {StringEntity s = new StringEntity(jsonParam.toString(),"UTF-8");s.setContentType("application/json");post.setEntity(s);post.setHeader("Content-Type","application/json");HttpResponse res = client.execute(post);if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK){/*返回json格式*/jsonObject = JSONObject.parseObject(EntityUtils.toString(res.getEntity()));}} catch (IOException e) {System.out.println("接口调用出错!");e.printStackTrace();throw new RuntimeException(e);}return jsonObject;}
//请求一次接口 先获取分页后的总数据public static Map<String,Object> getOneRequest(){String url ="http://gateway.zc511.com/getway/v2/product_list_get.shtml";JSONObject params = new JSONObject();params.put("timestamp","1650865510301");params.put("appKey","ZBKJ");params.put("secret","123");params.put("sign","1186D2A92FC3AB4E5671EBF58B9896A6");params.put("buyerCode","3330020298-1");params.put("pageNum","1");params.put("pageSize","2000");JSONObject jsonObject = HttpClientUtil.postResponse(url,params);
// System.out.println("第一次请求:"+jsonObject);Boolean success = (Boolean) jsonObject.get("success");JSONObject data = (JSONObject) jsonObject.get("data");Boolean isLastPage =(Boolean) data.get("isLastPage");//是否为最后一页Integer pages =(Integer) data.get("pages");//一共多少页 按每页取多少条进行计算的(共可以获取多少次)Integer total = (Integer)data.get("total");// 总数据Integer pageNum = (Integer) data.get("pageNum");//当前页数Map<String, Object> response = new HashMap<>();response.put("pages",pages);response.put("isLastPage",isLastPage);response.put("total",total);response.put("data",data);response.put("pageNum",pageNum);return response;}
}
controller
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sun.org.apache.xpath.internal.operations.Bool;
import com.zc.zcdj.domain.LhkjHzhnData;
import com.zc.zcdj.domain.ResponseEntity;
import com.zc.zcdj.mapper.LhkjHzhnDataMapper;
import com.zc.zcdj.service.ILhkjHzhnDataService;
import com.zc.zcdj.utils.HttpClientUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;/*** <p>* 前端控制器* </p>** @author guoshanshan* @since 2023-03-21*/@Component
public class LhkjHzhnDataController {@Autowiredprivate ILhkjHzhnDataService lhkjHzhnDataService;@Autowiredprivate LhkjHzhnDataMapper lhkjHzhnDataMapper;@Autowiredprivate JdbcOperations jdbcTemplate;private static final Logger log = LoggerFactory.getLogger("获取珍诚全量数据");/*** 获取珍诚全量数据*/
// @Scheduled(cron = "0 14 13 ? * *")
// public void getAll(){
// System.out.println("111111111111111111111111111111");
// lhkjHzhnDataService.getProductList();
// }@Scheduled(cron = "0 49 19 ? * *")public void getProductList() {Map<String, String> AllTybm = lhkjHzhnDataMapper.getTybm().stream().filter(s -> s.get统一商品编码() != null).filter(s -> s.get规则() != null).collect(Collectors.toMap(s -> s.get规则(), s -> s.get统一商品编码()));log.info("第一次请求珍诚接口...");
// 请求第一次获取数据总条数 以及分页后循环次数Map<String, Object> response = HttpClientUtil.getOneRequest();Integer pages = (Integer) response.get("pages");//Integer total = (Integer) response.get("total");Integer pageNum = (Integer) response.get("pageNum");//当前页数
// Boolean isLastPage = (Boolean) response.get("isLastPage");
// JSONObject data = (JSONObject) response.get("data");log.info("获取珍诚商品列表全量数据共有" + total + "条,共有" + pages + "页数据");log.info("珍诚全量开始执行...");for (int i = 1; i <= pages; i++) {String url = "http://gateway.zc511.com/getway/v2/product_list_get.shtml";JSONObject params = new JSONObject();params.put("timestamp", "1650865510301");params.put("appKey", "ZBKJ");params.put("secret", "123");params.put("sign", "1186D2A92FC3AB4E5671EBF58B9896A6");params.put("buyerCode", "3330020298-1");params.put("pageNum", pageNum);params.put("pageSize", "2000");JSONObject jsonObject = HttpClientUtil.postResponse(url, params);log.info("开始获取第" + i + "页数据");JSONObject data = (JSONObject) jsonObject.get("data");Boolean isLastPage = (Boolean) data.get("isLastPage");//是否为最后一页// 获取list中的商品数据 JSONArrayJSONArray list = data.getJSONArray("list");for (int j = 0; j < list.size(); j++) {LhkjHzhnData hzhnData = new LhkjHzhnData();String packingUnit = list.getJSONObject(j).getString("packingUnit");//包装单位Double salePrice = list.getJSONObject(j).getDouble("salePrice");//销售价String factory = list.getJSONObject(j).getString("factory");//生产企业Integer inventoryQuantity = list.getJSONObject(j).getInteger("inventoryQuantity");//库存Date validDateStr = list.getJSONObject(j).getDate("validDateStr");//有效期String authorizeNumber = list.getJSONObject(j).getString("authorizeNumber");//国药准字String barCode = list.getJSONObject(j).getString("barCode");//商品条码String parseProductName = list.getJSONObject(j).getString("parseProductName");//商品名称String packingAmount = list.getJSONObject(j).getString("packingAmount");//大包装String parseProductSpec = list.getJSONObject(j).getString("parseProductSpec");//规格String minPackingNumber = list.getJSONObject(j).getString("minPackingNumber");//最小购买包装if (authorizeNumber != null && parseProductSpec != null) {String authorizeNumberNew = authorizeNumber.replaceAll("[^a-zA-Z/0-9]", "");String parseProductSpecNew = parseProductSpec.replaceAll("[^0-9]", "");String tj = authorizeNumberNew.toUpperCase() + parseProductSpecNew;hzhnData.set统一编码("0");String tybm = (String) AllTybm.get(tj);if (tybm != null && tybm != "0") {hzhnData.set统一编码(tybm);}}hzhnData.set药品名称(parseProductName);hzhnData.set规格(parseProductSpec);hzhnData.set产地(factory);hzhnData.set单位(packingUnit);hzhnData.set大包装(packingAmount);hzhnData.set批准文号(authorizeNumber);hzhnData.set库存数量(inventoryQuantity);hzhnData.set价格(salePrice);hzhnData.setTxm(barCode);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");if (validDateStr != null) {hzhnData.set有效期(sdf.format(validDateStr));} else {hzhnData.set有效期(null);}hzhnData.set库区("珍诚");hzhnData.set供应商("珍诚");hzhnData.set中包装(minPackingNumber);Date date = new Date();SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");hzhnData.setStoragedate(sdf1.format(date));
// hzhnData.set备注();
// hzhnData.setHyid();System.out.println("第" + (j + 1) + "条" + hzhnData);lhkjHzhnDataMapper.insert(hzhnData);}pageNum += 1;}log.info("获取珍诚全量数据运行完毕...");}}
若是使用频率比较多,推荐使用对象的形式处理
利用阿里的fastjson,请注意前引用
关于Java对json字符串的处理,可以直接获取;但当使用频率较多的时候,就不太方便了。既然是面向对象编程,那就向json的数据转化为对象!
处理思路:
需要根据接收到的json对象构建对象。
将所有需要的数据全部封装为对象!
再利用阿里(fastjson)/google(Gson)的json转对象的方法
直接转为对象,再直接操作对象
假设以下是我们接收到的json,我们需要的是detail中的数据;
则需要构建实体dataItems以及包含dataItems的实体
然后直接进行转换:
示例代码:实体(假设都是String类型)
dataItems
@Data
public class DataIteams {private String phoneNum;private String aramDateTime;private String aramType;private String lon;private String lat;private String devNo;private String descripton;private String since;private String amc;}
detail的实体
import java.util.List;
@Data
public class Detail {private String pageCount;private String totalCount;private String pageIndex;private String pageSize;/***这个实体就是DataItems里面的数据体*/private List<DataItems> dataItems;}
当构建了实体以后就可以利用方法转换了!
示例代码:
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;import java.util.HashMap;public class Main {public static void main(String[] args) {String str = "{\n" +" \"code\": \"0\",\n" +" \"error\": \"\",\n" +" \"msg\": \"success\",\n" +" \"detail\": {\n" +" \"pageCount\": 1,\n" +" \"totalCount\": 9,\n" +" \"pageIndex\": 1,\n" +" \"pageSize\": 1000,\n" +" \"dataItems\": [\n" +" {\n" +" \"phoneNum\": \"027044039989\",\n" +" \"aramDateTime\": 1616990185000,\n" +" \"aramType\": 1,\n" +" \"lon\": 114.224438,\n" +" \"lat\": 30.55706,\n" +" \"devNo\": \"\",\n" +" \"descripton\": \"\",\n" +" \"since\": \"\",\n" +" \"amc\": \"\"\n" +" },\n" +" {\n" +" \"phoneNum\": \"027044039989\",\n" +" \"aramDateTime\": 1616990186000,\n" +" \"aramType\": 1,\n" +" \"lon\": 114.224457,\n" +" \"lat\": 30.557187,\n" +" \"devNo\": \"\",\n" +" \"descripton\": \"\",\n" +" \"since\": \"\",\n" +" \"amc\": \"\"\n" +" },\n" +" {\n" +" \"phoneNum\": \"027044039989\",\n" +" \"aramDateTime\": 1616990190000,\n" +" \"aramType\": 1,\n" +" \"lon\": 114.224484,\n" +" \"lat\": 30.557565,\n" +" \"devNo\": \"\",\n" +" \"descripton\": \"\",\n" +" \"since\": \"\",\n" +" \"amc\": \"\"\n" +" },\n" +" {\n" +" \"phoneNum\": \"027044039989\",\n" +" \"aramDateTime\": 1616990195000,\n" +" \"aramType\": 1,\n" +" \"lon\": 114.224434,\n" +" \"lat\": 30.557971,\n" +" \"devNo\": \"\",\n" +" \"descripton\": \"\",\n" +" \"since\": \"\",\n" +" \"amc\": \"\"\n" +" },\n" +" {\n" +" \"phoneNum\": \"027044039989\",\n" +" \"aramDateTime\": 1616990196000,\n" +" \"aramType\": 1,\n" +" \"lon\": 114.224388,\n" +" \"lat\": 30.558073,\n" +" \"devNo\": \"\",\n" +" \"descripton\": \"\",\n" +" \"since\": \"\",\n" +" \"amc\": \"\"\n" +" },\n" +" {\n" +" \"phoneNum\": \"027044039989\",\n" +" \"aramDateTime\": 1616990200000,\n" +" \"aramType\": 1,\n" +" \"lon\": 114.224297,\n" +" \"lat\": 30.558436,\n" +" \"devNo\": \"\",\n" +" \"descripton\": \"\",\n" +" \"since\": \"\",\n" +" \"amc\": \"\"\n" +" },\n" +" {\n" +" \"phoneNum\": \"027044039989\",\n" +" \"aramDateTime\": 1614736039000,\n" +" \"aramType\": 27,\n" +" \"lon\": 114.204813,\n" +" \"lat\": 30.553443,\n" +" \"devNo\": \"\",\n" +" \"descripton\": \"\",\n" +" \"since\": \"\",\n" +" \"amc\": \"\"\n" +" },\n" +" {\n" +" \"phoneNum\": \"027044039989\",\n" +" \"aramDateTime\": 1615342530000,\n" +" \"aramType\": 27,\n" +" \"lon\": 114.216378,\n" +" \"lat\": 30.561051,\n" +" \"devNo\": \"\",\n" +" \"descripton\": \"\",\n" +" \"since\": \"\",\n" +" \"amc\": \"\"\n" +" },\n" +" {\n" +" \"phoneNum\": \"027044039989\",\n" +" \"aramDateTime\": 1616990178000,\n" +" \"aramType\": 27,\n" +" \"lon\": 114.222609,\n" +" \"lat\": 30.554516,\n" +" \"devNo\": \"\",\n" +" \"descripton\": \"\",\n" +" \"since\": \"\",\n" +" \"amc\": \"\"\n" +" }\n" +" ]\n" +" },\n" +"}";//先转换成JSONObject类型String json = JSON.parseObject(str).getString("detail");Detail detail = JSONObject.parseObject(json, Detail.class);System.out.println(detail);}}
获得的对象就可以直接使用get和set方法获取数据了
方法:
//Javabean对象转换成String类型的JSON字符串
JSONObject.toJSONString(Javabean对象)
//String类型的JSON字符串转换成Javabean对象
JSONObject.toJavaObject(JSON字符串,Javabean.class)
//Json字符串转换成JSONObject对象
JSONObject.parseObject(JSON字符串)
//JSON字符串转换成Javabean对象
JSONObject.parseObject(JSON字符串,Javabean.class)