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

调用第三方接口获取数据写入数据库系统框架:springboot(和框架没有什么太大关系,仅记录一下)调用路径:controller→service第三方接口:http://xx.xxx.com:9905/api/list?transtime=20181017105600&token=abcdefghijklmn请求参数:{“data”:”{\”xxx\”:\”\”,\”xx\”:\”\”,\”xxxx\”:\…

大家好,又见面了,我是你们的朋友全栈君。

 

 

前言:关于调用第三方接口获取数据,我在后面的日子中写过一篇简易版的带图的博文https://blog.csdn.net/myme95/article/details/89359677,建议先看这个简易版的。

本篇博文是我当时第一次做【调用第三方接口获取数据】时写的文章,当时主要还是当做学习笔记记录,方便自己日后回顾。而且这篇博文主要是围绕我自己当时在做的公司的一个项目,所以在步骤方面的解释也很省(毕竟是我自己做的项目,我自己知道流程,所以就没写很清楚,比如介绍哪一步是在干什么),再加上这里面涉及的一些实体都是我们公司自己封装的,例如那个输出类Output,所以从总体上来看这篇文章对于很多人来说可能读起来有点费劲。

简易版的博文,我是围绕一个京东开放接口写的,当时是在写一个自己的小项目,不涉及泄露商业代码之类的,所以从头到尾能写多详细就写多详细。但可能由于我写的太详细了,所以可能读起来更像一团乱麻???可总体来说我觉得比这篇应该更好接受吧。另外,如果大家看我那篇简易版的,可以去找到我当时作为案例的那个京东的接口,然后跟着我的步骤一步一步写,我觉得一路跟下来的话应该没什么问题吧?

【2021-2-24补充】demo地址(简易版):https://github.com/ibfang/learning-examples.git

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

 

——————————————正文————————————————

系统框架: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);
}

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/134017.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • struts2在web.xml中配置详情

    struts2在web.xml中配置详情

  • Jenkins的三种启动方式「建议收藏」

    Jenkins的三种启动方式「建议收藏」前置条件Java8环境,参考:点击查看。(所有)docker环境,下载(第二种)ApacheTomcat环境,下载(第三种)一、war包启动下载Jenkins的war包打开终端命令行,找到war所在的路径运行java-jarjenkins.war浏览器打开http://localhost:8080,将会看到下图结果二、docker启动打开命令行终端或power…

  • sqlserver中exec/sp_executesql的使用

    sqlserver中exec/sp_executesql的使用–动态语句语法/******************************************************************************************************************************************************动态语句语法:exec/sp_executesql语法整理人:中国风(Roy

  • 批处理 %~dp0是什么意思「建议收藏」

    批处理 %~dp0是什么意思「建议收藏」cd/D%~dp0的意思如下:更改当前目录为批处理本身的目录比如你有个批处理a.bat在D:\qq文件夹下a.bat内容为cd/d%~dp0在这里cd/d%~dp0的意思就是cd/dd:\qq%0代表批处理本身d:\qq\a.bat~dp是变量扩充d既是扩充到分区号d:p就是扩充到路径\qqdp就是扩充到分区号路径d:\qq…

  • VB学习记录[通俗易懂]

    VB学习记录[通俗易懂]一、什么是VBVB程序设计是要干什么?1.添加、设置对象;2.对对象添加功能。编程的基本要素-对象object-类class-属性property-方法method-事件event事件过程的一般格式:privatesub对象名称_事件名称()……事件响应程序代码……En…

  • easyUI的时间控件[通俗易懂]

    easyUI的时间控件[通俗易懂]以前没怎么用过easyUI,今天用到时间控件,又了解到了一点东西时间控件的样式<inputclass="easyui-datetimebox"id="starttime"name="starttime"style="width:150px"/>然后通过js动态的添加的时候,使用append添加container.append(‘开始时间<inputclass="easyui-d

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号