<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推送企业微信消息的更多相关文章

  1. Java企业微信开发_05_消息推送之发送消息(主动)

    一.本节要点 1.发送消息与被动回复消息 (1)流程不同:发送消息是第三方服务器主动通知微信服务器向用户发消息.而被动回复消息是 用户发送消息之后,微信服务器将消息传递给 第三方服务器,第三方服务器接 ...

  2. Java企业微信开发_04_消息推送之发送消息(主动)

    源码请见: Java企业微信开发_00_源码及资源汇总贴 一.本节要点 1.发送消息与被动回复消息 (1)流程不同:发送消息是第三方服务器主动通知微信服务器向用户发消息.而被动回复消息是 用户发送消息 ...

  3. 让微信推送Jenkins构建消息

    Jenkins作为开发必备之神器,各家大小公司都在使用.Jenkins自身内置了基于邮件推送构建结果的功能.但是随着移动互联网的发展,邮件这玩意已经越来越少使用了,是否有一种办法能把jenkins构建 ...

  4. php 微信客服信息推送失败 微信重复推送客服消息 40001 45047

    /*** * 微信客服发送信息 * 微信客服信息推送失败 微信重复推送客服消息 40001 45047 * 递归提交到微信 直到提交成功 * @param $openid * @param int $ ...

  5. C++实现微信WeChat网页接口推送股票报警消息

    QStockView微信推送股票报警 1.功能简介 最近很多用户反馈,软件只能在电脑上使用,不能在手机上使用.所以增加了微信推送报警的功能,电脑端的报警提示消息可以通过微信同步发送到手机微信.这样即可 ...

  6. Docker最全教程之使用.NET Core推送钉钉消息(十九)

    前言 上一篇我们通过实战分享了使用Go推送钉钉消息,由于技痒,笔者现在也编写了一个.NET Core的Demo,作为简单的对照和说明. 最后,由于精力有限,笔者希望有兴趣的朋友可以分享下使用CoreR ...

  7. 使用Python发送企业微信消息

    准备工作: 到企业微信官网,注册一个企业:登录企业微信后台,创建一个“自建”应用, 获取企业ID.agentid.secret这3个必要的参数:在企业微信的通讯录中,创建多个测试账号:在手机端安装“企 ...

  8. Win10环境下使用Flask配合Celery异步推送实时/定时消息(Socket.io)/2020年最新攻略

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_163 首先得明确一点,和Django一样,在2020年Flask 1.1.1以后的版本都不需要所谓的三方库支持,即Flask-Ce ...

  9. .NET Core 企业微信消息推送

    接口定义 应用支持推送文本.图片.视频.文件.图文等类型.请求方式:POST(HTTPS)请求地址: https://qyapi.weixin.qq.com/cgi-bin/message/send? ...

  10. java如何对接企业微信

    前言 最近实现社群对接企业微信,对接的过程遇到一些点,在此记录. 企业微信介绍 企业微信具有和微信一样的体验,用于企业内部成员和外部客户的管理,可以由此构建出社群生态. 企业微信提供了丰富的api进行 ...

随机推荐

  1. DTL事务控制语言--sql事务

    DTL事务控制语言体格sql语句就是一个事务事务可以保证 一组sql语句要么都成功,要么都失败默认自动提交一可以关闭 set autocommit=0关闭自动提交最后 插入或者修改时 只有commit ...

  2. 【C++】static 知识整理 【静态与局部静态】

    目录 类外 类内 局部静态 local static 类外 类内 类外 C++的静态可以分为两种情况来讨论:在类外和在类内. 对于静态变量/函数,链接将只在内部 (如果不用static,那么在不同文件 ...

  3. C# 7.0 新特性:模式匹配 ( pattern matching)

    C# 7.0 新特性:模式匹配 ( pattern matching ) 在 C# 中,is 是一个关键字,可以用来检查某个数据的类型是否为特定类型.这是一个表达式,返回类型为 boolean. 例如 ...

  4. AlertManager警报通知 使用webhook 钉钉机器人

    # AlertManager警报通知 使用webhook 钉钉机器人 #启动钉钉webhook服务 #dingtalk webhook docker rm -f dingtalk docker run ...

  5. Mac触控板设置以及使用

    Mac 触控板体验是非常好的,很多同学甚至直接用触控板代替鼠标操作,但是默认设置中有一些功能是没有开启的,需要手动配置. 本文就来说说 如何更改 Mac 触控板默认设置,让触控板变得更高效. 一.启用 ...

  6. Qt编写地图综合应用35-设备分布图

    一.前言 设备分布图在所有的地图应用案例项目中,最常见最普遍最基础,就是将项目中的设备信息,比如设备名称.设备所在的经纬度坐标.设备的其他信息(设备地址.设备参数等),通过标注点的形式添加到地图中,至 ...

  7. 在CLion中如何为CMakeLists.txt文件添加第三方依赖库

    cmake_minimum_required(VERSION 3.5)project(ImageBasedModellingEdu)set(CMAKE_MODULE_PATH "${CMAK ...

  8. 在Win7 x64环境中将World Wind Java SDK 2.1.0嵌入到Eclipse中的方法

    1.解压worldwind-2.1.0.zip. 2.打开Eclipse,依次点击New–>Java project ,输入project的名称WorldWind,一路直到finish.然后就可 ...

  9. 即时通讯技术文集(第43期):直播技术合集(Part3) [共13篇]

    为了更好地分类阅读 52im.net 总计1000多篇精编文章,我将在每周三推送新的一期技术文集,本次是第 43 期. [-1-] 直播系统聊天技术(一):百万在线的美拍直播弹幕系统的实时推送技术实践 ...

  10. 即时通讯技术文集(第26期):实时音视频技术合集(Part1) [共16篇]

    为了更好地分类阅读 52im.net 总计1000多篇精编文章,我将在每周三推送新的一期技术文集,本次是第26 期. [- 1 -] 实时语音聊天中的音频处理与编码压缩技术简述 [链接] http:/ ...