赞
踩
其实你也可以使用RestTemplate,我这里主要是用到了webflux框架,所以需要实例化客户端请求对象
@Bean public WebClient webClient(){ HttpClient httpClient = getHttpClient(); return WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)).build(); } private HttpClient getHttpClient() { ConnectionProvider provider = ConnectionProvider.builder("你爱咋咋的,一般用你项目名即可") .maxConnections(500) .maxIdleTime(Duration.ofSeconds(10)) .maxLifeTime(Duration.ofSeconds(20)) .pendingAcquireTimeout(Duration.ofSeconds(30)) .pendingAcquireTimer((r, d) -> { Timeout t = wheel.newTimeout(timeout -> r.run(), d.toMillis(), TimeUnit.MILLISECONDS); return () -> t.cancel(); }) .fifo() .build(); HttpClient httpClient = HttpClient.create(provider); return httpClient; }
import cn.hutool.core.date.DateUtil; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.tomcat.util.codec.binary.Base64; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Map; import static com.paratera.console.notice.utils.Constants.*; /** * 机器人发送工具类(微信,飞书,钉钉) * * @author huxiang */ @Component @Slf4j public class RobotUtil { @Autowired private WebClient webClient; /** * 机器人发送消息(markdown格式) * * @param robotUrl 机器人地址 * @param type 类型:1微信,2飞书,3钉钉 * @param context markdown文本内容 * @param signSecret 签名校验(飞书,钉钉使用,可为空,具体要根据用户是否启用签名) */ public void sendMsg(String robotUrl, Integer type, String context, String signSecret) { JSONObject msgObj = JSONUtil.createObj(); JSONObject mdObj = JSONUtil.createObj(); switch (type) { case ROBOT_TYPE_WX: msgObj.set("msgtype", "markdown"); mdObj.set("content", context); msgObj.set("markdown", mdObj); break; case ROBOT_TYPE_FS: if (StringUtils.isNotEmpty(signSecret)) { msgObj = getFsSignObj(signSecret); } msgObj.set("msg_type", "interactive"); mdObj.set("tag", "lark_md"); mdObj.set("content", context); JSONArray elements = JSONUtil.createArray(); JSONObject wrapObj = JSONUtil.createObj(); wrapObj.set("tag", "div"); wrapObj.set("text", mdObj); elements.put(wrapObj); JSONObject cardObj = JSONUtil.createObj(); cardObj.set("elements", elements); msgObj.set("card", cardObj); break; case ROBOT_TYPE_DD: if (StringUtils.isNotEmpty(signSecret)) { robotUrl = getDdRobotURL(robotUrl, signSecret); } msgObj.set("msgtype", "markdown"); mdObj.set("title", "通知"); mdObj.set("text", context); msgObj.set("markdown", mdObj); break; } webClient.post() .uri(robotUrl) .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromValue(msgObj)) .retrieve().bodyToMono(String.class).subscribe( result -> { log.info("机器人通知发送结果:" + result); } ); } /** * 机器人有效性测试 0表示成功,其他表示失败 * * @param robotUrl 机器人地址 * @param type 类型:1微信,2飞书,3钉钉 * @param signSecret 签名校验(飞书,钉钉使用,可为空,具体要根据用户是否启用签名) * @return */ public Integer sendTestMsg(String robotUrl, Integer type, String signSecret) { JSONObject msgObj = JSONUtil.createObj(); JSONObject mdObj = JSONUtil.createObj(); ObjectMapper mapper = new ObjectMapper(); switch (type) { case ROBOT_TYPE_WX: msgObj.set("msgtype", "markdown"); mdObj.set("content", "机器人有效性测试!"); msgObj.set("markdown", mdObj); break; case ROBOT_TYPE_FS: if (StringUtils.isNotEmpty(signSecret)) { msgObj = getFsSignObj(signSecret); } msgObj.set("msg_type", "interactive"); mdObj.set("tag", "lark_md"); mdObj.set("content", "机器人有效性测试!"); JSONArray elements = JSONUtil.createArray(); JSONObject wrapObj = JSONUtil.createObj(); wrapObj.set("tag", "div"); wrapObj.set("text", mdObj); elements.put(wrapObj); JSONObject cardObj = JSONUtil.createObj(); cardObj.set("elements", elements); msgObj.set("card", cardObj); break; case ROBOT_TYPE_DD: if (StringUtils.isNotEmpty(signSecret)) { robotUrl = getDdRobotURL(robotUrl, signSecret); } msgObj.set("msgtype", "markdown"); mdObj.set("title", "通知"); mdObj.set("text", "机器人有效性测试!"); msgObj.set("markdown", mdObj); break; } Mono<String> mono = webClient.post() .uri(robotUrl) .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromValue(msgObj)) .retrieve().bodyToMono(String.class); String result = mono.block(); try { Map res = mapper.readValue(result, Map.class); return (Integer) (res.containsKey("errcode") ? res.get("errcode") : res.get("code")); } catch (JsonProcessingException e) { log.error("类型转换异常-RobotUtil.sendTestMsg:" + e); } return -1; } /** * 飞书获取带签名的消息体 * * @return */ public JSONObject getFsSignObj(String signSecret) { JSONObject signObj = JSONUtil.createObj(); Long timestamp = DateUtil.currentSeconds(); String sign = null; try { //把timestamp+"\n"+密钥当做签名字符串 String stringToSign = timestamp + "\n" + signSecret; //使用HmacSHA256算法计算签名 Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(stringToSign.getBytes(StandardCharsets.UTF_8), "HmacSHA256")); byte[] signData = mac.doFinal(new byte[]{}); sign = Base64.encodeBase64String(signData); } catch (Exception e) { log.error("飞书获取签名失败:" + e); } if (StringUtils.isEmpty(sign)) { return null; } signObj.set("timestamp", timestamp); signObj.set("sign", sign); return signObj; } /** * 钉钉获取带签名的机器人推送URL * * @return */ public String getDdRobotURL(String robotUrl, String signSecret) { Long timestamp = System.currentTimeMillis(); String stringToSign = timestamp + "\n" + signSecret; String sign = null; try { Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(signSecret.getBytes("UTF-8"), "HmacSHA256")); byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8")); sign = URLEncoder.encode(Base64.encodeBase64String(signData), "UTF-8"); } catch (Exception e) { log.error("钉钉获取签名失败:" + e); } if (StringUtils.isEmpty(sign)) { return null; } return robotUrl + "×tamp=" + timestamp + "&sign=" + sign; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。