定时推送任务
需求
需要定时推送我方的数据到对方那边
方法1 Apache HttpClient
此方法指定推送过去的信息转为utf-8格式的json字符串
@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
第二个业主也我们需要推送信息过去,按照上面的写法遇到一个报错,
报错信息为
<!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 的方法,直接拿来用了
@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
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResultVO<T> {
private Integer code;
private Integer taskId;
private T msg;
}