SpringBoot实现钉钉机器⼈消息推送的⽰例代码
零、前⾔
上⼀次做消息推送,是的定时消息通知。
由于⾃⼰当时的⽔平不够,加上企鹅家的开发⽂档普遍不太友好,导致根本看不懂⽂档在写什么,不得不去看第三⽅博客来学习的开发。
这次就不⼀样了,昨天刚看了⼀下,阿⾥的开发⽂档⽐鹅⼚要清晰的多,⽽且在同⼀功能上,使⽤了多种语⾔作为⽰例代码,可以说很友好了。可能这就是阿⾥和鹅⼚的区别吧...辣鸡⽂档和好⽂档的区别...
本着“授之以渔”的态度,写了这篇⽂章,作为的补充。
⼀、在⾥添加机器⼈
在设置的智能助⼿中添加⾃定义机器⼈,它长这个样⼦:
⽐较关键的⼀步,是进⾏安全设置。
加密⽅式⼀共有三种,既可以选择⼀种也可以使⽤多种⽅式组合:
⾃定义关键词springboot推荐算法
加签
IP地址
为了让博客起到效果,我们选择相对安全、也⽐较难的加签⽅式。
选择加签之后,把密钥复制出来,然后就可以点确定了。
⼆、构建请求地址和内容
先看看官⽅⽂档怎么描述加签的:
第⼀步,把timestamp+"\n"+密钥当做签名字符串,使⽤HmacSHA256算法计算签名,然后进⾏Base64 encode,最后再把签名参数再进⾏urlEncode,得到最终的签名(需要使⽤UTF-8字符集)。
第⼆步,把 timestamp和第⼀步得到的签名值拼接到URL中。
官⽅的解释很⾼⼤上,其实原理很简单,就是把机器⼈密钥加密后,放在URL的参数中,所以我们需要分别获取时间戳和密钥,组合⼀下,加密⼀下,再拼接⼀下就好了,如图:
I have a Pen,
I have an Apple,
Oh~ Applepen~
官⽅给出了这样的⽰例代码:
pto.Mac;
pto.spec.SecretKeySpec;
import dec.binary.Base64;
import java.URLEncoder;
public class Test {
public static void main(String[] args) throws Exception {
Long timestamp = System.currentTimeMillis();
String secret = "this is secret";
String stringToSign = timestamp + "\n" + secret;
Mac mac = Instance("HmacSHA256");
mac.init(new Bytes("UTF-8"), "HmacSHA256"));
byte[] signData = mac.Bytes("UTF-8"));
String sign = de(new deBase64(signData)),"UTF-8");
System.out.println(sign);
}
}
然⽽,dec.binary.Base64不是Java的内置类,也就是说,⽰例代码并不能直接拿过来⽤:
查了⼀下,发现Java8中内置的java.util已经包含了Base64,因此⽤它替换掉原来的codec,⽆需再引⼊第三⽅包:pto.Mac;
pto.spec.SecretKeySpec;
import java.util.Base64;
import java.URLEncoder;
public class ding {
public static void main(String[] args) throws Exception {
//获取时间戳
Long timestamp = System.currentTimeMillis();
//定义密钥
String secret = "this is secret";
//把时间戳和密钥拼接成字符串,中间加⼊⼀个换⾏符
String stringToSign = timestamp + "\n" + secret;
//声明⼀个Mac对象,⽤来操作字符串
Mac mac = Instance("HmacSHA256");
//初始化Mac对象,设置Mac对象操作的字符串是UTF-8类型,加密⽅式是SHA256
mac.init(new Bytes("UTF-8"), "HmacSHA256"));
//把字符串转化成字节形式
byte[] signData = mac.Bytes("UTF-8"));
//新建⼀个Base64编码对象
Base64.Encoder encoder = Encoder();
//把上⾯的字符串进⾏Base64加密后再进⾏URL编码
String sign = de(new deToString(signData)),"UTF-8");
//分别输出时间戳和加密信息
System.out.println(timestamp);
System.out.println(sign);
}
}
⽤最笨的⽅法,在终端执⾏⼀下看看:
成功输出了时间戳和验证信息。
我们测试上述代码的时候,可以⼿动拼接URL,直接发起请求:
(URL⼀共有三个参数:access_token、timestamp、sign,需要换成⾃⼰的,也就是上⾯终端输出的结果)
//替换参数后,在终端执⾏
curl 'oapi.dingtalk/robot/send?access_token=70c168d03e73728ef36abea63c3c10048cbd054913cfeb×tamp=1584607421017&sign=gJ3l4mhnlMuHxK1qFUx1kKUSdjuCNntsdG%2Bv%2BTCrLQM%3D' \ -H 'Content-Type: application/json' \
-d '{"msgtype": "text",
"text": {
"content": "我就是我, 是不⼀样的烟⽕"
},
"sign": "gJ3l4mhnlMuHxK1qFUx1kKUSdjuCNntsdG%2Bv%2BTCrLQM%3D"
}'
然后就出现了:
经过测试,代码正常运⾏,接下来就是部署到⽣产环境了。
三、部署代码
我们需要先⼀下Spring如何发起HTTP请求。
以前,笔者只⽤过前台的HttpClient,对于后台的HTTP⼯具并不了解。
⼀开始尝试⽤Spring内置的RestTemplate,去⽹上查了它的⽤法,写了⼀堆代码,但怎么也不成功。由于从来没⽤过RestTemplate,也没耐⼼去看它的源码,于是放弃。
后来,只能⽼⽼实实的⽤apache的httpClient,查了⼀下⽤法,虽然有点⿇烦,很多操作没法⾃动完成,但还算通俗易懂,⽽且它的包托管在Maven上,导⼊很⽅便。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.9</version>
</dependency>
httpClient的使⽤很灵活,这⾥使⽤的是POST⽅式,有⼀个参数,发起POST请求时,必须将字符集编码设置成UTF-8。
粗略步骤如图:
直接来⼀段稍微改⼀下就能⽤的代码:
public class DingService {
//请求地址以及access_token
String Webhook = "oapi.dingtalk/robot/send?access_token=YOUR TOKEN";
//密钥
String secret = "YOUR SECRET";
/*
** ⽣成时间戳和验证信息
*/
public String encode() throws Exception {
//获取时间戳
Long timestamp = System.currentTimeMillis();
//把时间戳和密钥拼接成字符串,中间加⼊⼀个换⾏符
String stringToSign = timestamp + "\n" + this.secret;
//声明⼀个Mac对象,⽤来操作字符串
Mac mac = Instance("HmacSHA256");
//初始化,设置Mac对象操作的字符串是UTF-8类型,加密⽅式是SHA256
mac.init(new SecretKeySpec(Bytes("UTF-8"), "HmacSHA256"));
//把字符串转化成字节形式
byte[] signData = mac.Bytes("UTF-8"));
//新建⼀个Base64编码对象
Base64.Encoder encoder = Encoder();
//把上⾯的字符串进⾏Base64加密后再进⾏URL编码
String sign = de(new deToString(signData)),"UTF-8");  System.out.println(timestamp);
System.out.println(sign);
String result = "×tamp=" + timestamp + "&sign=" + sign;
return result;
};
/* param: message 要发送的信息
** return: void ⽆返回值
** 作⽤:把传⼊的message发送给钉钉机器⼈*/
public void dingRequest(String message){
CloseableHttpClient httpClient = ate().build();
String url = null;
try {
url = this.Webhook + de();
} catch (Exception e) {
e.printStackTrace();
}
HttpPost httpPost = new HttpPost(url);
//设置http的请求头,发送json字符串,编码UTF-8
httpPost.setHeader("Content-Type", "application/json;charset=utf8");
//⽣成json对象传⼊字符
JSONObject result = new JSONObject();
JSONObject text = new JSONObject();
text.put("content", message);
result.put("text", text);
result.put("msgtype", "text");
String jsonString = JSONString(result);
StringEntity entity = new StringEntity(jsonString, "UTF-8");
//设置http请求的内容
httpPost.setEntity(entity);
/
/ 响应模型
CloseableHttpResponse response = null;
try {
// 由客户端执⾏(发送)Post请求
response = ute(httpPost);
// 从响应模型中获取响应实体
HttpEntity responseEntity = Entity();
System.out.println("响应状态为:" + StatusLine());
if (responseEntity != null) {
System.out.println("响应内容长度为:" + ContentLength());
System.out.println("响应内容为:" + String(responseEntity));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// 释放资源
if (httpClient != null) {
httpClient.close();
}
if (response != null) {
response.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
总结
其实消息推送的功能并不难,只是由于初次接触,需要查很多的⽂档,在这个过程中,锻炼了⽂本阅读能⼒和独⽴解决问题的能⼒。
参考资料
到此这篇关于SpringBoot实现钉钉机器⼈消息推送的⽰例代码的⽂章就介绍到这了,更多相关SpringBoot 钉钉机器⼈消息推送内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!