定时推送任务 Apache HttpClient/okhttp3

定时推送任务

需求

需要定时推送我方的数据到对方那边

方法1 Apache HttpClient

此方法指定推送过去的信息转为utf-8格式的json字符串

java 复制代码
@Scheduled(initialDelay = 1000 * 120, fixedDelay = 1000 * 60 * 5)
public void diseaseInterface() {
    String lockKey = "lock:diseaseInterface";
    String requestId = UUID.randomUUID().toString();
    boolean acquired = false;
    try {
        // 加锁,锁定时间为15分钟
        acquired = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, Duration.ofMinutes(15L));
        if (acquired) {
            MainBody mainBody = interfaceService.diseaseInterface(new WebServiceBO());
            if (mainBody != null) {
                String sendUrl = "对方的接口";
                
                // 如果在数据库中配置了接口信息,就从数据库中查询并赋值
                Code code = codeService.selectByPrimaryKey(DATABASE_CODE_PK_JXZ);
                if (code != null && StringUtils.isNotEmpty(code.getCode())) {
                    sendUrl = code.getCode();
                }
                
                
                CloseableHttpClient httpClient = HttpClientBuilder.create().build();
                HttpPost httpPost = new HttpPost(sendUrl);
                StringEntity entity = new StringEntity(JSON.toJSONString(mainBody), "utf-8");
                entity.setContentEncoding("utf-8");
                entity.setContentType("application/json");
                httpPost.setEntity(entity);
                HttpResponse response;
                try {
                    
                    // 信息推送过去之后,对方会给返回值,结构就是常见的
                    //     {
                    //  code: 1,//接口返回码,成功0,失败1
                    //  msg: '',//提示详细信息,可以为空,可以为中文提示信息
                    //  data: {
                          //返回结果对象
                    //	}
                    //}
                    // data存放了已经同步过去的id,拿到id,我方这边更新字段,表示该信息已经同步,后续不用再同步
                    response = httpClient.execute(httpPost);
                    JSONObject resultJson = JSON.parseObject(EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8).trim());
                    if (resultJson != null) {
                        Utils.debug(resultJson.toJSONString());
                        if (200 == resultJson.getInteger("code")) {
                           // 更新字段
                            recSubmitService.updateReportedStateByRecSubId(resultJson.getInteger("data"), STATUS_YES);
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    } finally {
        // 释放锁
        Utils.debug("[释放锁]:" + lockKey);
        if (acquired) {
            redisTemplate.delete(lockKey);
        }
    }
}

方法2 okhttp3

第二个业主也我们需要推送信息过去,按照上面的写法遇到一个报错,

报错信息为

html 复制代码
<!DOCTYPE html>
<html>
  <head>
    <title>Error - 415</title>
    <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0">

    <style>
      body {
        padding: 50px 80px;
        font: 14px "Helvetica Neue", Helvetica, sans-serif;
      }

      h1 {
        font-size: 2em;
        margin-bottom: 5px;
      }

      pre {
        font-size: .8em;
      }
    </style>
  </head>
  <body>
    <div id="error">
      <h1>Error</h1>
      <p>Looks like something broke!</p>
      <pre>
        <code>
Error: Unsupported Content-Encoding: utf-8
    at inflate (D:\项目\道路巡检-2\ai-node-1\node_modules\inflation\index.js:35:15)
    at module.exports [as json] (D:\项目\道路巡检-2\ai-node-1\node_modules\co-body\lib\json.js:39:25)
    at parseBody (D:\项目\道路巡检-2\ai-node-1\node_modules\koa-bodyparser\index.js:87:26)
    at bodyParser (D:\项目\道路巡检-2\ai-node-1\node_modules\koa-bodyparser\index.js:67:25)
    at dispatch (D:\项目\道路巡检-2\ai-node-1\node_modules\koa-compose\index.js:42:32)
    at D:\项目\道路巡检-2\ai-node-1\node_modules\koa-compose\index.js:34:12
    at Application.handleRequest (D:\项目\道路巡检-2\ai-node-1\node_modules\koa\lib\application.js:186:12)
    at Server.handleRequest (D:\项目\道路巡检-2\ai-node-1\node_modules\koa\lib\application.js:157:21)
    at Server.emit (node:events:518:28)
    at parserOnIncoming (node:_http_server:1143:12)
    at HTTPParser.parserOnHeadersComplete (node:_http_common:119:17)
        </code>
      </pre>
    </div>
  </body>
</html>

直接返回了一个网页,看报错信息好像是node报错,不支持utf-8格式,具体怎么解决要看甲方那边调试。

有个现象就是将需要的信息用postman发送过去是正常了,但是写成方法一的代码就出错了,postman支持代码生成,看它提供了 okhttp3 的方法,直接拿来用了

java 复制代码
@Scheduled(initialDelay = 1000 * 120, fixedDelay = 1000 * 60 * 5)
public void diseaseInterfaceXC() {
    String lockKey = "lock:diseaseInterfaceOfXC";
    String requestId = UUID.randomUUID().toString();
    boolean acquired = false;
    try {
        // 加锁,锁定时间为15分钟
        acquired = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, Duration.ofMinutes(15L));
        if (acquired) {
            MainBody mainBody = interfaceService.diseaseInterfaceXC(new WebServiceBO());
            if (mainBody != null) {
                String sendUrl = "对方的接口";
                Code code = codeService.selectByPrimaryKey(DATABASE_CODE_PK_XC);
                if (code != null && StringUtils.isNotEmpty(code.getCode())) {
                    sendUrl = code.getCode();
                }

                // 换一种写法,不指定编码格式为utf-8
                OkHttpClient client = new OkHttpClient().newBuilder()
                    .build();
                MediaType mediaType = MediaType.parse("application/json");
                RequestBody body = RequestBody.create(mediaType,JSON.toJSONString(WebResponse.ok(mainBody)));
                Request request = new Request.Builder()
                    .url(sendUrl)
                    .method("POST", body)
                    .addHeader("Content-Type", "application/json")
                    .build();
                Response response = client.newCall(request).execute();
                String responseBody = response.body().string();
                ObjectMapper objectMapper = new ObjectMapper();
                // 用实体类接受返回值
                ResultVO resultVO = objectMapper.readValue(responseBody, ResultVO.class);
                if (resultVO.getCode() == 200) {
                    recSubmitService.updateReportedStateByRecSubId(resultVO.getTaskId(), STATUS_YES);
                }
            }
        }

    } catch (JsonMappingException e) {
        throw new RuntimeException(e);
    } catch (JsonProcessingException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        throw new RuntimeException(e);
    } finally {
        // 释放锁
        Utils.debug("[释放锁]:" + lockKey);
        if (acquired) {
            redisTemplate.delete(lockKey);
        }
    }
}

ResultVO

JAVA 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResultVO<T> {

    private Integer code;

    private Integer taskId;

    private T msg;
}
相关推荐
weisian1514 分钟前
Redis篇--常见问题篇6--缓存一致性1(Mysql和Redis缓存一致,更新数据库删除缓存策略)
数据库·redis·缓存
中草药z1 小时前
【Spring】深入解析 Spring 原理:Bean 的多方面剖析(源码阅读)
java·数据库·spring boot·spring·bean·源码阅读
地球资源数据云1 小时前
全国30米分辨率逐年植被覆盖度(FVC)数据集
大数据·运维·服务器·数据库·均值算法
Ahern_2 小时前
Oracle 普通表至分区表的分区交换
大数据·数据库·sql·oracle
夜半被帅醒2 小时前
MySQL 数据库优化详解【Java数据库调优】
java·数据库·mysql
不爱学习的啊Biao2 小时前
【13】MySQL如何选择合适的索引?
android·数据库·mysql
破 风2 小时前
SpringBoot 集成 MongoDB
数据库·mongodb
Rverdoser3 小时前
MySQL-MVCC(多版本并发控制)
数据库·mysql
m0_748233643 小时前
SQL数组常用函数记录(Map篇)
java·数据库·sql
dowhileprogramming3 小时前
Python 中的迭代器
linux·数据库·python