java推送企业微信消息
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.8</version>
</dependency>
所需配置
cropId: 企业微信id
corpsecret 应用的凭证密钥
agentid 企业应用的id
1、封装消息体
//封装消息体 可以直接用json也可以创建对象
public void send(String msg, String userIds) {
//1.创建文本消息对象
TextMessage message = new TextMessage();
message.setTouser(userIds);
//1.2必需
message.setMsgtype("text");
message.setAgentid(agentId);
Text text = new Text();
text.setContent(msg);
message.setText(text);
sendMessage(0, message);
}
@Data
public class TextMessage extends BaseMessage {
/**
* 文本TextMessage
*/
private Text text;
/**
* 表示是否是保密消息,0表示否,1表示是,默认0
*/
private int safe;
}
@Data
public class Text {
/**
* 消息内容,最长不超过2048个字节
*/
private String content;
}
2.请求token及推送消息
public void sendMessage(Integer mark, BaseMessage message) {
String key = "wx_accessToken:" + platformVO.getAppId() + "_secret:" + platformVO.getSecret();
String token = null;
token = redisTemplate.opsForValue().get(key);
//mark大于0代表token失效
if (null == token || mark > 0) {
log.info("获取token");
//2.获取access_token:根据企业id和通讯录密钥获取access_token,并拼接请求url
AccessToken accessToken = WeiXinUtil.getAccessToken(platformVO.getAppId(), platformVO.getSecret());
token = accessToken.getToken();
redisTemplate.opsForValue().set(key, accessToken.getToken(), accessToken.getExpiresIn() - 4, TimeUnit.SECONDS);
}
log.info("企业微信token:" + token);
//3.发送消息:调用业务类,发送消息
String jsonMessage = JSONObject.toJSONString(message);
//2.获取请求的url
String sendMessage_url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + token;
//3.调用接口,发送消息
String result = HttpUtil.doPost(sendMessage_url, null, jsonMessage, null);
JSONObject jsonObject = JSONObject.parseObject(result, JSONObject.class);
List<String> errorCode = Lists.newArrayList();
errorCode.add("40014");
errorCode.add("42001");
//4.错误消息处理
if (null != jsonObject) {
if (errorCode.contains(jsonObject.getString("errcode")) && mark < 3) {
log.info("消息推送失败 errcode:{}", jsonObject.getInteger("errcode") + "重新获取token");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
sendMessage(mark + 1, message);
} else if (0 != jsonObject.getInteger("errcode")) {
log.error("消息推送失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
} else {
log.info("企业微信消息推送成功!");
}
}
}
/**
* 所需要用到的工具类
* @author tangh
*/
@Slf4j
public class WeiXinUtil {
/**
* 微信的请求url
* 获取access_token的接口地址(GET) 限200(次/天)
*/
public final static String ACCESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpId}&corpsecret={corpsecret}";
/**
* 1.发起https请求并获取结果
*
* @param requestUrl 请求地址
* @param outputStr 提交的数据
* @return JSONObject(通过JSONObject.get ( key)的方式获取json对象的属性值)
*/
public static JSONObject httpRequest(String requestUrl, String outputStr) {
JSONObject jsonObject = null;
CloseableHttpResponse response = null;
try {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(requestUrl);
StringEntity requestEntity = new StringEntity(outputStr, "utf-8");
httpPost.setEntity(requestEntity);
httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
response = httpClient.execute(httpPost);
String result = EntityUtils.toString(response.getEntity(), "utf-8");
jsonObject = JSONObject.parseObject(result);
} catch (ConnectException ce) {
ce.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
log.error("POST请求response关闭异常,错误信息为{}", e.getMessage(), e);
}
}
return jsonObject;
}
/**
* 发起http请求获取返回结果
*
* @param requestUrl 请求地址
* @return
*/
public static String httpRequest(String requestUrl) {
String result = null;
HttpGet httpGet = new HttpGet(requestUrl);
CloseableHttpResponse response = null;
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
response = httpClient.execute(httpGet);
result = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
log.error("GET请求response关闭异常,错误信息为{}", e.getMessage(), e);
}
}
return result;
}
/**
* 3.获取access_token
*
* @param appid 凭证
* @param appsecret 密钥
* @return
*/
public static AccessToken getAccessToken(String appid, String appsecret) {
AccessToken accessToken = null;
String requestUrl = ACCESS_TOKEN_URL.replace("{corpId}", appid).replace("{corpsecret}", appsecret);
JSONObject jsonObject = JSONObject.parseObject(httpRequest(requestUrl), JSONObject.class);
// 如果请求成功
if (null != jsonObject) {
try {
accessToken = new AccessToken();
accessToken.setToken(jsonObject.getString("access_token"));
accessToken.setExpiresIn(jsonObject.getInteger("expires_in"));
} catch (JSONException e) {
accessToken = null;
// 获取token失败
log.error("获取token失败 errcode:{} errmsg:{}" + jsonObject.getInteger("errcode") + ":" + jsonObject.getString("errmsg"));
}
}
return accessToken;
}
}
@Slf4j
public final class HttpUtil {
/**
* 超时时间
*/
private static final Integer TIMEOUT = 20000;
private HttpUtil() {
}
/**
* 发送post请求
*
* @param url url
* @param header header
* @param body body
* @param param param
* @return string
*/
public static String doPost(String url, Map<String, String> header, String body, Map<String, Object> param) {
String result = "";
BufferedReader in = null;
PrintWriter out = null;
try {
// 设置 url
url = getUrl(url, param);
URL realUrl = new URL(url);
HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
connection.setRequestMethod("POST");
// 设置 header
if (header != null) {
for (String key : header.keySet()) {
connection.setRequestProperty(key, header.get(key));
}
}
// 设置请求 body
connection.setDoOutput(true);
connection.setDoInput(true);
//设置连接超时和读取超时时间
connection.setConnectTimeout(TIMEOUT);
connection.setReadTimeout(TIMEOUT);
try {
out = new PrintWriter(connection.getOutputStream());
// 保存body
out.print(body);
// 发送body
out.flush();
} catch (Exception e) {
e.printStackTrace();
}
log.info("connection: " + connection);
log.info("body: " + out);
try {
// 获取响应body
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 发送get请求
*
* @param url url
* @param header header
* @param param param
* @return string
*/
public static String doGet(String url, Map<String, String> header, Map<String, Object> param) {
String result = "";
BufferedReader in = null;
try {
url = getUrl(url, param);
// 设置 url
URL realUrl = new URL(url);
HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setUseCaches(false);
connection.setRequestMethod("GET");
// 设置 header
if (header != null) {
for (String key : header.keySet()) {
connection.setRequestProperty(key, header.get(key));
}
}
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
log.error(e.getMessage());
return null;
}
return result;
}
/**
* @param url url
* @param param 请求参数
* @return String
*/
public static String getUrl(String url, Map<String, Object> param) {
if (null != param && param.size() > 0) {
StringBuilder stringBuilder = new StringBuilder(url);
stringBuilder.append("?");
Set<Map.Entry<String, Object>> entries = param.entrySet();
for (Map.Entry<String, Object> entry : entries) {
stringBuilder.append(entry.getKey() + "=" + entry.getValue() + "&");
}
url = stringBuilder.substring(0, stringBuilder.length() - 1);
}
return url;
}
}
java推送企业微信消息的更多相关文章
- Java企业微信开发_05_消息推送之发送消息(主动)
一.本节要点 1.发送消息与被动回复消息 (1)流程不同:发送消息是第三方服务器主动通知微信服务器向用户发消息.而被动回复消息是 用户发送消息之后,微信服务器将消息传递给 第三方服务器,第三方服务器接 ...
- Java企业微信开发_04_消息推送之发送消息(主动)
源码请见: Java企业微信开发_00_源码及资源汇总贴 一.本节要点 1.发送消息与被动回复消息 (1)流程不同:发送消息是第三方服务器主动通知微信服务器向用户发消息.而被动回复消息是 用户发送消息 ...
- 让微信推送Jenkins构建消息
Jenkins作为开发必备之神器,各家大小公司都在使用.Jenkins自身内置了基于邮件推送构建结果的功能.但是随着移动互联网的发展,邮件这玩意已经越来越少使用了,是否有一种办法能把jenkins构建 ...
- php 微信客服信息推送失败 微信重复推送客服消息 40001 45047
/*** * 微信客服发送信息 * 微信客服信息推送失败 微信重复推送客服消息 40001 45047 * 递归提交到微信 直到提交成功 * @param $openid * @param int $ ...
- C++实现微信WeChat网页接口推送股票报警消息
QStockView微信推送股票报警 1.功能简介 最近很多用户反馈,软件只能在电脑上使用,不能在手机上使用.所以增加了微信推送报警的功能,电脑端的报警提示消息可以通过微信同步发送到手机微信.这样即可 ...
- Docker最全教程之使用.NET Core推送钉钉消息(十九)
前言 上一篇我们通过实战分享了使用Go推送钉钉消息,由于技痒,笔者现在也编写了一个.NET Core的Demo,作为简单的对照和说明. 最后,由于精力有限,笔者希望有兴趣的朋友可以分享下使用CoreR ...
- 使用Python发送企业微信消息
准备工作: 到企业微信官网,注册一个企业:登录企业微信后台,创建一个“自建”应用, 获取企业ID.agentid.secret这3个必要的参数:在企业微信的通讯录中,创建多个测试账号:在手机端安装“企 ...
- Win10环境下使用Flask配合Celery异步推送实时/定时消息(Socket.io)/2020年最新攻略
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_163 首先得明确一点,和Django一样,在2020年Flask 1.1.1以后的版本都不需要所谓的三方库支持,即Flask-Ce ...
- .NET Core 企业微信消息推送
接口定义 应用支持推送文本.图片.视频.文件.图文等类型.请求方式:POST(HTTPS)请求地址: https://qyapi.weixin.qq.com/cgi-bin/message/send? ...
- java如何对接企业微信
前言 最近实现社群对接企业微信,对接的过程遇到一些点,在此记录. 企业微信介绍 企业微信具有和微信一样的体验,用于企业内部成员和外部客户的管理,可以由此构建出社群生态. 企业微信提供了丰富的api进行 ...
随机推荐
- 在CodeBolcks+wxWidgets下的C++编程教程——用向导创建一个wxWidgets项目(xTetris)
0.前言 我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程.我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识. 了解我编写教 ...
- 六步取消win11开机PIN密码登录
0.前言 新买的电脑打开后首先要进行一系列的操作激活操作系统.在这些操作中最令人讨厌的是设置开机密码(pin). 也许有很多人的电脑需要保密,限制别人登录,这时使用登录pin是很有必要的.而还有很多人 ...
- uniapp多次触发跳转问题
问题描述:快速点击跳转页面后会闪退到登陆页面 解决方案:重新封装uniapp跳转api,加防抖锁,To.ts import { NavigateToOptions, RedirectToOptions ...
- k8s单节点改为高可用和更新证书
master单节点添加master节点 apiServer添加域名更新证书 更新kubenertes证书有效期 环境 kubernetes v1.22.12 使用kubeadm安装的集群 #添加节点 ...
- NoSQL 述评
作为主库的 nosql 只有 CockroachDB.TiKV 以及 MongoDB(从4.0后事务似乎可用了),CockrouchDB 已经收费,另外 YugabyteDB 也可选,但大家的反馈都不 ...
- Kali Linux上安装Openvas 漏洞分析器
第一步:安装 apt-get update apt-get install openvas openvas-setup 第二步:自定义密码 openvas-stop #停止openvas服务 open ...
- docker容器间互相访问 docker bridge网络
方式一.虚拟ip访问安装docker时,docker会默认创建一个内部的桥接网络docker0,每创建一个容器分配一个虚拟网卡,容器之间可以根据ip互相访问. [root@33fcf82ab4dd / ...
- jacoco代码覆盖率报告分析
一.目的 对Jacoco代码覆盖率统计维度.报告字段说明.报告详细分析描述.并为精准测试.健壮性测试提供指导. 二.Jacoco代码覆盖率统计维度 Jacoco是从代码指令(Instructions, ...
- Qt编写地图综合应用38-覆盖物矩形
一.前言 矩形的应用场景和多边形基本一致,也是用来框起一块区域,然后根据坐标点集合,找到该区域内的标注点集合,比如指定某个县市区域多边形,然后找到这个县市对应的所有站点,拿到这些站点在做其他处理. 二 ...
- VueRouter案列
案列内容,包含,模板,路由传参,路由重定向,路由嵌套,能够复习路由基本使用,成果如图: 完整代码: 1 <!DOCTYPE html> 2 <html lang="en&q ...