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进行 ...
随机推荐
- Go 内存管理
操作系统内存管理 操作系统管理内存的存储单元是页(page),在 linux 中一般是 4KB.而且,操作系统还会使用 虚拟内存 来管理内存,在用户程序中,我们看到的内存是不是真实的内存,而是虚拟内存 ...
- Member not found: ’packageRoot’ in Flutter
path/flutter/.pub-cache/hosted/pub.dartlang.org/platform-3.0.0/ lib/src/interface/local_platform.dar ...
- 【金TECH频道】企业架构转型组合拳来袭,助力金融机构一臂之力
当前,数字化转型已经成为时代共性课题在政策和技术的双重指引下金融机构逐渐走向差异化竞争的格局面对转型阵痛以契合.明晰的战略规划及企业架构调整来辅助业务变革成为助力企业数字化转型的有效路径金融机构也纷纷 ...
- Qt数据库应用8-数据导出组件示例说明
一.前言 为了方便用户学习使用本组件,特意针对每个功能模块,每种可能的应用场景,都编写了对应的示例demo,从初级示例到中级示例再到高级示例以及多线程示例等,层层加码,针对结构体数据都做了相当详细细致 ...
- Qt编写可视化大屏电子看板系统22-平滑曲线图
一.前言 平滑曲线是所有涉及到曲线图的项目中,绕不开的一个话题,尽管很多人爱看折线图,但是很多时候来个平滑曲线图,会更加赏心悦目,这就好比现在的手机app移动客户端上,从最初的四方四正到现在的平滑圆角 ...
- AutoCAD 2020中文版建筑设计从入门到精通下载链接
AutoCAD 2020中文版建筑设计从入门到精通下载链接 链接:https://pan.baidu.com/s/1EgFHOSKfPrr9Xdp3bNA-pA或https://pan.baidu.c ...
- 移动端弱网优化专题(十四):携程APP移动网络优化实践(弱网识别篇)
本文由携程技术团队Aaron分享,原题"干货 | 携程弱网识别技术探索",下文进行了排版和内容优化. 1.引言 网络优化一直是移动互联网时代的热议话题,弱网识别作为移动端弱网优化的 ...
- JavaScript 数组展平方法: flat() 和 flatMap()
从 ES2019 中开始引入了一种扁平化数组的新方法,可以展平任何深度的数组. flat flat() 方法创建一个新数组,其中所有子数组元素以递归方式连接到特定深度. 语法:array.flat(d ...
- CF div3 995 (A~G)
期末周之第三把网瘾(真是越来越放肆了...).这次赛时了一把div 3 , 又一次只做出了A~E,写完E后剩下的题没时间看了(受了些寝室噪音的干扰,最后二十分钟才出).赛后看了下F和G,感觉也是一时半 ...
- 前端(三)-JavaScript
1.基本语法 1.1 引入JavaScript 1.1.1行内引入 <input type="button" value="轻轻点我一下" onclick ...