调用第三方接口获取数据写入数据库

系统框架:springboot(和框架没有什么太大关系,仅记录一下)

调用路径:controller→service

第三方接口:http://xx.xxx.com:9905/api/list?transtime=20181017105600&token=abcdefghijklmn

请求参数:{"data":"{\"xxx\":\"\",\"xx\":\"\",\"xxxx\":\"\",\"pageindex\":1}"}

(注:因为有些公司的后台是用.net写的,所以java给它传数据要像上面那么传,即包两层,json里面套json,且有斜杠;如果不是.net的话,就不用这么封装,具体请求方法看对方的要求)

一  controller层

@ApiOperation("数据抓取")
@ApiImplicitParam(name = "ImportListInput",value = "输入参数",required = true,dataType = "ImportListInput")
@PostMapping("interface")
@ResponseBody
@PreAuthorize("isAuthenticated()")
public Output getQualityLevel(@Valid @RequestBody ImportListInput importListInput)throws Exception {
    return mdmElianImportListService.getImportList(importListInput);
}

importListInput 为向第三方接口传送的请求参数,该接口的请求方式为POST,故,后面需要将我们输入的值转为json数据包传送

二 service层

public static final String ESB_ElIAN_XXX_EXCHANGE = "elian.xxx.exchange";//下面同步用到。我的需求里有同步。这和调用第三方接口无关。不用看
private static final Logger logger = LoggerFactory.getLogger(xxxService.class);
public Output getImportList(ImportListInput importListInput) throws IOException, YaolingException, ParseException {

    //获取token (获取token也是调用第三方提供的接口获取的,方法与下面记录的类似,不作赘述)
    String str = mdmElianGetTokenService.getToken();
    JSONObject oj = new JSONObject(str.toString());
    String errorcode = oj.get("errorcode").toString();
    if (ObjectUtils.isEmpty(errorcode)) {

        //单起一个线程 (当第三方的数据量过大时,需要起一个线程,以防止超时而造成的数据获取不全,应该有更好的优化方法,如线程       
//池之类的,暂不会;线程的使用代码用粉色标出)
        Thread ts =   new Thread(new Runnable() {
            @Override
            public void run() {
                JSONObject oj1 = new JSONObject(str.toString());
                String data = oj1.get("data").toString();
                JSONObject oj2 = new JSONObject(data.toString());
                String token = oj2.get("token").toString();
                int pageindex;
                if ((Integer) mdmElianImportListInput.getPageindex() == null||mdmElianImportListInput.getPageindex() ==0) {
                    pageindex = 1;  
                } else {
                    pageindex = mdmElianImportListInput.getPageindex();
                }
                //得到long类型当前时间
                long l = System.currentTimeMillis();
                //new日期对象
                Date date = new Date(l);
                //转换提日期输出格式
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");  
                SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyyMMdd");
                String time = dateFormat.format(date);//按要求生成请求url中的第一个参数transtime并与格式化为url示例中的样子            
                while (true) {


                    《--完整的请求示例从这里开始--》


                    //new一个JSONObject格式的参数inner将我们传入的参数转为json格式
                    JSONObject inner = new JSONObject();
                   //把我们传进来的参数分别赋值给inner中的各个参数,
//这些参数名要和请求包的参数名一致,毕竟这是传给对方的数据,如果和对方要求的
//参数名不一致,那么我们也拿不到数据
                    inner.put("xxx", importListInput.getDrugname());
                    inner.put("xx", importListInput.getCompanysceng());
                    inner.put("xxxx", importListInput.getEndTime());
                    inner.put("pageindex", pageindex);
                    // 这里参数是包装了两层的
//再new一个JSonObject类型的参数param,把上面的inner放到param中,实现两层包装,因为对方后台用的.net,所以包两层。具体包装几层,看接口要求,有的可能只一层就好了
                    JSONObject param = new JSONObject();
                    param.put("data", inner.toString());
                  //拼接请求的url,把url+transtime+token拼接在一起
                    String url = "http://xx.xxx.com:9905/api/importlist?transtime=" + time + "&token=".concat(token);
                 //定义一个JSONObject类型的rets用于接收返回的JSON数据
                    JSONObject rets = null;
                    try {
                 //调用第三方接口,并传参数给对方,jsonPost方法在最后面附上
                        rets = DataDownloadUtil.jsonPost(url, param.toString()); 
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
//如果返回结果中errorcode为空,即请求成功(具体看对方怎么标识错误信息,有的可能不用errorcode,所以不可直接生搬硬套此代码)
                    String errorCode = (String) rets.get("errorcode")
                    if (ObjectUtils.isEmpty(errorCode)) {
                        //调用成功
                        JSONArray jsonArray = rets.getJSONArray("data");
//用一个集合接收返回的json数据中的data的值,遍历集合,取出数据
                        for (int i = 0, len = jsonArray.length(); i < len; i++) {
                            JSONObject jsonObject2 = (JSONObject) jsonArray.get(i);
                           //定义一个接受类importList,将接收的数据写进数据库
                            ImportList importList = new ImportList();
//jsonObject2.get("x_x").toString()中的“x_x”要和实际返回的json数据中的字段名一致,否则可能会出现找不到字段的错误提示
                            importList.setXx(jsonObject2.get("x_x").toString());
                            importList.setXxx(jsonObject2.get("x_xx").toString());
                            importList.setXxxx(jsonObject2.get("x_xxx").toString());
                            importList.setDrugnameeng(jsonObject2.get("drugnameeng").toString());
//如果存在时间类的数据,且自己的数据库中设计时将时间字段的类型设置为了datetime,那么在接收时要进行转换,将string型的数据转为date型的数据存入数据库
                            SimpleDateFormat sdfs = new SimpleDateFormat("yyyy-MM-dd");
                            try {
                                importList.setLisencecodedate(sdfs.parse(jsonObject2.get("date").toString()));
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                            //保存此条数据,框架是springboot,所以有Repository。不要生搬硬套代码
                           importListRepository.save(importList);
                            // }

                     //     同步到xxxx平台,用不到就不用写了
     rabbitTemplate.convertAndSend(CommonConstant.ESB_ElIAN_XXX_EXCHANGE,CommonConstant.UPDATE, importList);

                        }
                  
                    } else {
                        try {
                            throw new YaolingException(errorCode);
                        } catch (YaolingException e) {
                            e.printStackTrace();
                        }
                    }
                    logger.debug("传过去的pageindex值:[{}]", pageindex);  //控制台做监控,看是否数据正确翻页
              //json数据中的null和一般的null不同,判断的时候要注意,不能用==null之类的
                    if (rets.isNull("nextpage")) {
                        logger.debug("返回的nextpage值为null,抓取结束");
                        break;
                    }
                    logger.debug("返回的nextpage值:[{}]", (Integer) rets.get("nextpage"));
//请求数据时,我们要告诉对方要第几页的数据,所以会传一个pageindex值过去,对方返回给我们数据时,会给我们一个nextpage值,如果这个值不为null或者“ ”就说明下一页还有数据,我们要把nextpage值赋值给pageindex继续传过去获取下一页的值,写进数据库,循环往复直至nextpage为null或者“”,这也就是上面为什么要用while循环的原因
                    pageindex = (Integer) rets.get("nextpage");
                    logger.debug("下一次要传的pageindex值:[{}]", pageindex); 
//至此,一条数据的获取、存入结束
                } //while
        



           《--一个完整的请求及获取数据到写入数据库到此结束--》
                 



            }//线程
        });//线程
        ts.start();  //启动线程

    } else {
        throw new YaolingException(errorcode);
    }
    return new Output();
}

(请求的代码是用“《-- --》《-- --》”包起来的部分,上面获取token之后,蓝色之前的代码都是为了蓝色代码中的url中的token做服务的,所以不用太在意。)

jsonPost方法

protected JSONObject jsonPost(String urls, String text) throws IOException {
    //创建一个HttpClient最新版的实现类CloseableHttpClient
    CloseableHttpClient httpClient = HttpClients.createDefault();
    //创建post方法请求对象,并把拼接好的地址url赋值给它的请求参数urls
    HttpPost httpPost = new HttpPost(urls);
   //设置报文头为Content-Type。具体格式看实际需求,我只知道如果请求的数据包为raw时,用Content-Type
    httpPost.setHeader("Content-Type", "application/json");
   //设置参数到请求对象中 
    httpPost.setEntity(new StringEntity(text));
   //执行请求操作,并拿到结果(同步阻塞)。(括号里的同步阻塞我也不知道什么意思,之后知道了再补上)
    CloseableHttpResponse response = httpClient.execute(httpPost);
   //获取结果实体
    HttpEntity entity = response.getEntity();
   //看返回状态是否正常,正常则把获取到的json字符串返回给调用者
    int statue = response.getStatusLine().getStatusCode();
    if (statue != HttpStatus.SC_OK) {
        logger.error("http connect fail:{}", response.getStatusLine());
    }
    //返回结果
    String result = EntityUtils.toString(entity, "utf-8");
    return new JSONObject(result);
}

之前做了颜色标记的,不知道为什么发布以后就变成了一个个大黑块,都不知道重点在哪了,第一次做这种,凑合看吧。 

你可能感兴趣的:(调用第三方接口获取数据写入数据库)