pom引入依赖
<!-- 企业公众号 -->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-cp</artifactId>
<version>3.0.0</version>
</dependency>
<!-- 生成二维码 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!-- 激活自动代理功能 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<bean id="wxCpConfigStorage" class="me.chanjar.weixin.cp.config.WxCpInMemoryConfigStorage">
<property name="aesKey" value="${wx.aesKey}" />
<property name="agentId" value="${wx.agentId}" />
<property name="token" value="${wx.token}" />
<property name="corpSecret" value="${wx.corpSecret}" />
<property name="corpId" value="${wx.corpId}" />
</bean>
<bean id="wxCpService" class="me.chanjar.weixin.cp.api.impl.WxCpServiceImpl">
<property name="wxCpConfigStorage" ref="wxCpConfigStorage"></property>
</bean>
<bean id="wxPortalManager" class="com.cnten.qywx.manager.WxPortalManager">
<property name="wxCpService" ref="wxCpService"></property>
</bean>
properties文件
wx.aesKey=sA4O
wx.agentId=100
wx.token=hk
wx.corpSecret=NPN
wx.corpId=wwb96
wx.url=http://57q2
#通讯录秘钥
wx.contactSecret=NPNlDXw
获取bean工具类
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class ApplicationContextAwareUtil implements ApplicationContextAware {
// Spring应用上下文环境
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}
使用场景
WxPortalService wxPortalService = (WxPortalService) applicationContext.getBean("wxPortalService");
String join = userIds;
String textMess = "友情提示:"+orgNowName+timeNow+"还没有举办"+mettingName+",请尽快举办";
String newsMess = textMess;
MessageAdvice advice = MessageAdvice.getModle(AdviceModles.AdviceModle.PB_ACTIVITY_METTING_TASK, "举办活动", newsMess,"86b00474daf7358",join, AdviceModles.AdviceType.TYPE_MESSAGE,"", "", AdviceModles.WxMsg.WXMSG_YES);
wxPortalService.sendWxPortal(advice);
消息通知类
public class MessageAdvice implements Serializable {
/**
*
* @param model 消息模块 发送消息的模块(统一在"AdviceModles.java"类中定义)
* @param title 标题
* @param content 内容
* @param sendUser 发送人
* @param receiveUsers 接受人ID 多个接收人已“,”隔开
* @param type 消息分类(消息通知:1;党务公开:2)
* @param range 消息范围
* @param from 消息来源
* @param wxMsg 是否发送微信消息 1发送 0 不发送
* @return
*/
public static MessageAdvice getModle(String model, String title, String content,String sendUser ,String receiveUsers, String type,
String range, String from, String wxMsgStatus) {
MessageAdvice advice = new MessageAdvice();
advice.setMessageAdviceId(CommonUtils.getUUID());
advice.setMessageContent(content);
advice.setMessageFrom(from);
advice.setMessageModel(model);
advice.setMessageRange(range);
advice.setMessageTitle(title);
advice.setMessageType(type);
advice.setReceiveUserId(receiveUsers);
advice.setSendTime(DateUtil.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
advice.setWxMsgStatus(wxMsgStatus);
advice.setSendUserId(sendUser);
return advice;
}
public static MessageAdvice getEntityModle() {
return new MessageAdvice();
}
/**
* 禁止初始化
*/
private MessageAdvice() {
}
private static final long serialVersionUID = 6674013991838914395L;
private String messageAdviceId;
private String messageTitle;
private String sendUserId;
private String sendUserIdName;
private String receiveUserId;
private String receiveUserIdName;
private String messageType;
private String messageContent;
private String messageRange;
private String messageFrom;
private String sendTime;
private String messageStatus;
private String messageStatusName;
private String messageModel;
private String sendWxMsg;
private String wxMsgStatus;
private String adviceTitle;
/**
* 总人数
*/
private Integer receiveUserNum;
/**
* 已读人数
*/
private Integer readedNum;
/**
* 未读人数
*/
private Integer unReadNum;
private String currentUserId;
public String getMessageAdviceId() {
return messageAdviceId;
}
public void setMessageAdviceId(String messageAdviceId) {
this.messageAdviceId = messageAdviceId;
}
/**
* 获得标题
*
* @return messageTitle
*/
public String getMessageTitle() {
return messageTitle;
}
/**
* 设置标题
*
* @param messageTitle
*/
public void setMessageTitle(String messageTitle) {
this.messageTitle = messageTitle;
}
/**
* 获得发送人
*
* @return sendUserId
*/
public String getSendUserId() {
return sendUserId;
}
public String getSendUserIdName() {
sendUserIdName = "";
String dictItemName = DictContext.getInstance().getDict("syuser", sendUserId);
if (StringUtil.isNotEmpty(dictItemName))
sendUserIdName = dictItemName;
return sendUserIdName;
}
/**
* 设置发送人
*
* @param sendUserId
*/
public void setSendUserId(String sendUserId) {
this.sendUserId = sendUserId;
}
/**
* 获得接收人
*
* @return receiveUserId
*/
public String getReceiveUserId() {
return receiveUserId;
}
public String getReceiveUserIdName() {
receiveUserIdName = "";
String dictItemName = DictContext.getInstance().getDict("syuser", receiveUserId);
if (StringUtil.isNotEmpty(dictItemName))
receiveUserIdName = dictItemName;
return receiveUserIdName;
}
/**
* 设置接收人
*
* @param receiveUserId
*/
public void setReceiveUserId(String receiveUserId) {
this.receiveUserId = receiveUserId;
}
/**
* 获得消息分类
*
* @return messageType
*/
public String getMessageType() {
return messageType;
}
/**
* 设置消息分类
*
* @param messageType
*/
public void setMessageType(String messageType) {
this.messageType = messageType;
}
/**
* 获得消息内容
*
* @return messageContent
*/
public String getMessageContent() {
return messageContent;
}
/**
* 设置消息内容
*
* @param messageContent
*/
public void setMessageContent(String messageContent) {
this.messageContent = messageContent;
}
/**
* 获得消息范围
*
* @return messageRange
*/
public String getMessageRange() {
return messageRange;
}
/**
* 设置消息范围
*
* @param messageRange
*/
public void setMessageRange(String messageRange) {
this.messageRange = messageRange;
}
/**
* 获得消息来源
*
* @return messageFrom
*/
public String getMessageFrom() {
return messageFrom;
}
/**
* 设置消息来源
*
* @param messageFrom
*/
public void setMessageFrom(String messageFrom) {
this.messageFrom = messageFrom;
}
/**
* 获得发送时间
*
* @return sendTime
*/
public String getSendTime() {
return sendTime;
}
/**
* 设置发送时间
*
* @param sendTime
*/
public void setSendTime(String sendTime) {
this.sendTime = sendTime;
}
public String getMessageStatus() {
return messageStatus;
}
}
public class WxPortalManager {
private WxCpServiceImpl wxCpService;
@Autowired
private EhCacheManagerImpl ehCaheMamger;
@Value("${wx.corpId}")
private String wxCorpId;
/**
* 通讯录secret
*/
@Value("${wx.contactSecret}")
private String contactSercet;
@Value("${wx.token}")
private String token;
@Value("${wx.aesKey}")
private String aesKey;
@Value("${wx.agentId}")
private String agentId;
/**
* 党建应用secret
*/
@Value("${wx.corpSecret}")
private String corpSecret;
public WxCpMessageSendResult sendTextMessage(CntenWxMessage cntenWxMessage) {
WxCpMessageSendResult result = null;
if (wxCpService == null || wxCpService.getWxCpConfigStorage() == null || getAgentId() <= 0) {
return result;
}
try {
WxCpMessage message = WxCpMessage.TEXT().agentId(getAgentId()) // 企业号应用ID
.toUser(cntenWxMessage.getRecipients()).toParty(cntenWxMessage.getRecipients())
.toTag(cntenWxMessage.getRecipients()).content(cntenWxMessage.getContext()).build();
result = wxCpService.messageSend(message);
} catch (WxErrorException e) {
e.printStackTrace();
}
return result;
}
WxCpMessageSendResult result = null;
public WxCpMessageSendResult sendNewsMessage(CntenWxMessage cntenWxMessage) {
if (wxCpService == null || wxCpService.getWxCpConfigStorage() == null || getAgentId() <= 0) {
return result;
}
try {
NewsBuilder builder = WxCpMessage.NEWS().agentId(getAgentId()) // 企业号应用ID
.toUser(cntenWxMessage.getRecipients()).toParty(cntenWxMessage.getRecipients())
.toTag(cntenWxMessage.getRecipients());
List<String> titles = cntenWxMessage.getTitles();
NewArticle article = null;
for (int i = 0; i < titles.size(); i++) {
article = new NewArticle();
article.setTitle(titles.get(i));
if (cntenWxMessage.getDescriptions().size() > i) {
article.setDescription(cntenWxMessage.getDescriptions().get(i));
}
if (cntenWxMessage.getPicUrls().size() > i) {
article.setPicUrl(cntenWxMessage.getPicUrls().get(i));
}
if (cntenWxMessage.getUrls().size() > i) {
article.setUrl(cntenWxMessage.getUrls().get(i));
}
builder.addArticle(article);
}
result = wxCpService.messageSend(builder.build());
} catch (WxErrorException e) {
e.printStackTrace();
}
return result;
}
public HashMap<String, Object> getCntenWxSign(String url) {
HashMap<String, Object> data = null;
try {
String jsapi_ticket = wxCpService.getJsapiTicket();
data = sign(jsapi_ticket, url, wxCorpId);
} catch (WxErrorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return data;
}
public WxCpServiceImpl getWxCpService() {
return wxCpService;
}
public void setWxCpService(WxCpServiceImpl wxCpService) {
this.wxCpService = wxCpService;
}
public int getAgentId() {
return wxCpService.getWxCpConfigStorage().getAgentId();
}
/**
* 签名工具,二维码
*
* @param url
* @return
*/
public static HashMap<String, Object> sign(String jsapi_ticket, String url, String appId) {
HashMap<String, Object> ret = new HashMap<String, Object>();
long timestamp = System.currentTimeMillis() / 1000;
String noncestr = RandomUtils.getRandomStr();
String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapi_ticket, "noncestr=" + noncestr,
"timestamp=" + timestamp, "url=" + url);
ret.put("url", url);
ret.put("nonceStr", noncestr);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
ret.put("appId", appId);
return ret;
}
/**
* 刷新通讯录accessToken
*
* @throws WxErrorException
*/
public void refreshContactAccessToken() throws WxErrorException
{
String contactAccessToken = "";
contactAccessToken = ehCaheMamger.get("accessToken", "contactAccessToken");
if(StringUtil.isEmpty(contactAccessToken))
{
WxCpInMemoryConfigStorage config = new WxCpInMemoryConfigStorage();
config.expireAccessToken();
config.setCorpId(wxCorpId); // 设置微信企业号的appid
config.setCorpSecret(contactSercet); // 设置微信企业号 通讯录Secret
config.setAgentId(Integer.valueOf(agentId)); // 设置微信企业号应用ID
config.setToken(token); // 设置微信企业号应用的token
config.setAesKey(aesKey); // 设置微信企业号应用的EncodingAESKey
wxCpService.setWxCpConfigStorage(config);
//每个secret 对应一个accessToken 需要缓存access_token
contactAccessToken = wxCpService.getAccessToken(true);
ehCaheMamger.put("accessToken", "contactAccessToken", contactAccessToken);
}
else
{
WxCpInMemoryConfigStorage wxStorage = (WxCpInMemoryConfigStorage) wxCpService.getWxCpConfigStorage();
wxStorage.setAccessToken(contactAccessToken);
wxCpService.getAccessToken();
}
}
/**
* 刷新应用accessToken
* @throws WxErrorException
*/
public void refreshAppAccessToken() throws WxErrorException
{
WxCpInMemoryConfigStorage config = new WxCpInMemoryConfigStorage();
config.setCorpId(wxCorpId); // 设置微信企业号的appid
config.setCorpSecret(corpSecret); // 设置微信企业号的app corpSecret
config.setAgentId(Integer.valueOf(agentId)); // 设置微信企业号应用ID
config.setToken(token); // 设置微信企业号应用的token
config.setAesKey(aesKey); // 设置微信企业号应用的EncodingAESKey
wxCpService.setWxCpConfigStorage(config);
String appAccessToken = wxCpService.getAccessToken(true);
ehCaheMamger.put("accessToken", "appAccessToken", appAccessToken);
}
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
import me.chanjar.weixin.cp.bean.WxCpUser;
@Service
public class WxPortalService {
private final static Logger log = LoggerFactory.getLogger(WxPortalService.class);
@Autowired
private WxPortalManager wxPortalManager;
@Autowired
private MessageAdviceMapper messageAdviceMapper;
@Autowired
private WxPortalMapper wxPortalMapper;
/**
*
* @param messageAdvice
* @return
*/
public boolean sendWxPortal(MessageAdvice messageAdvice) {
boolean isSuccess = false;
// 需要发送消息
if ("1".equals(messageAdvice.getWxMsgStatus())) {
CntenWxMessage message = new CntenWxMessage();
List<String> userIdList = new ArrayList<String>(Arrays.asList(messageAdvice.getReceiveUserId().split(",")));
Map<String,Object> param = new HashMap<String,Object>(1);
param.put("userIdList", userIdList);
List<String> idNumbers = wxPortalMapper.getUserIdNumberByUserIds(param);
String recievers = transRecipients(idNumbers);
message.setRecipients(recievers);
message.setContext(messageAdvice.getMessageContent());
WxCpMessageSendResult result = wxPortalManager.sendTextMessage(message);
if(null != result)
{
messageAdvice.setWxMsgStatus(String.valueOf(result.getErrCode()));
}
}
if (messageAdviceMapper.insert(messageAdvice) > 0) {
isSuccess = true;
}
return isSuccess;
}
/**
* 多个接收者用‘|’分隔
* @param idNumbers
* @return
*/
private String transRecipients(List<String> idNumbers)
{
StringBuffer recievers = new StringBuffer("");
if(CollectionUtils.isEmpty(idNumbers))
{
return recievers.toString();
}
for(String idNumber:idNumbers)
{
recievers.append(idNumber).append("|");
}
return recievers.toString();
}
/**
* 从微信端删除用户
* @param idNumber
* @return
*/
public boolean deleteUserFromWx(String idNumber)
{
try
{
WxCpUser wxUser = wxPortalManager.getWxCpService().getUserService().getById(idNumber);
if(wxUser == null)
{
return true;
}
wxPortalManager.refreshContactAccessToken();
wxPortalManager.getWxCpService().getUserService().delete(idNumber);
}
catch (WxErrorException e)
{
log.error("deleteUserFromWx "+ e);
Integer errorCode = e.getError().getErrorCode();
if(WebConsts.WX_USER_NOT_FOUND.equals(errorCode))
{
return true;
}
return false;
}
return true;
}
}
测试
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
/**
* * @author Binary Wang(https://github.com/binarywang)
*/
@RestController
@RequestMapping("/wx")
public class WxMessageController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private WxPortalManager wxPortalManager;
@Autowired
private WxPortalService wxPortalService;
@RequestMapping(value = "/authGet")
public String authGet(@RequestParam(value = "msg_signature", required = false) String signature,
@RequestParam(value = "timestamp", required = false) String timestamp,
@RequestParam(value = "nonce", required = false) String nonce,
@RequestParam(value = "echostr", required = false) String echostr) {
this.logger.info("\n接收到来自微信服务器的认证消息:signature = [{}], timestamp = [{}], nonce = [{}], echostr = [{}]",
signature, timestamp, nonce, echostr);
if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
throw new IllegalArgumentException("请求参数非法,请核实!");
}
if (this.wxPortalManager.getWxCpService().checkSignature(signature, timestamp, nonce, echostr)) {
return new WxCpCryptUtil(this.wxPortalManager.getWxCpService().getWxCpConfigStorage()).decrypt(echostr);
}
return "非法请求";
}
@ResponseBody
@RequestMapping(value = "/sendMessage")
public String post(String msg, String jsr) {
CntenWxMessage textMessage = new CntenWxMessage();
textMessage.setRecipients("@all");
textMessage.setContext("测试接口");
/**
* 测试发送文本消息
*/
WxCpMessageSendResult result = wxPortalManager.sendTextMessage(textMessage);
textMessage.setTitles(Arrays.asList(new String[] { "母亲节", "感谢母亲的节日" }));
textMessage.setDescriptions(Arrays.asList(new String[] { "母亲节,是一个感谢母亲的节日。母亲们在这一天通常会收到礼物,康乃馨被视为献给母亲的花,而中国的母亲花是萱草花,又叫忘忧草。",
"母亲节(Mother's Day),是一个感谢母亲的节日。母亲们在这一天通常会收到礼物,康乃馨被视为献给母亲的花,而中国的母亲花是萱草花,又叫忘忧草" }));
textMessage.setUrls(Arrays.asList(new String[] {"https://www.baidu.com/s?wd=%E6%AF%8D%E4%BA%B2%E8%8A%82&rsv_spt=1&rsv_iqid=0xb9d7f46c00036cd0&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=baiduhome_pg&rsv_enter=1&oq=%25E5%259B%25BE%25E7%2589%2587&inputT=3003&rsv_t=c686Ovnhz7%2B2VXukpx1gkTG%2F6NuYKk1R62V6uVX11c9TthZxVL0sq8eNHNiSjYhrdrYu&rsv_pq=c0b0605a000317ab&rsv_sug3=25&rsv_sug1=20&rsv_sug7=101&bs=%E5%9B%BE%E7%89%87",
"https://baike.baidu.com/item/%E6%AF%8D%E4%BA%B2%E8%8A%82/127378"}));
textMessage.setPicUrls(Arrays.asList(new String[] {"https://ss1.bdstatic.com/5aAHeD3nKgcUp2HgoI7O1ygwehsv/media/ch1000/png/muqinjiebeijing1.png",
"https://gss0.bdstatic.com/94o3dSag_xI4khGkpoWK1HF6hhy/baike/whfpf%3D180%2C140%2C50/sign=afd1bf2ed533c895a62bcb3bb72e42c8/b2de9c82d158ccbfcc747d8315d8bc3eb03541bb.jpg"}));
/**
* 测试发送图文消息
*/
result = wxPortalManager.sendNewsMessage(textMessage);
/**
* 测试发送消息通知
*/
MessageAdvice advice = MessageAdvice.getModle(AdviceModles.AdviceModle.PB_MESSAGE_ADVICE, "测试标题", "测试内容", "620860c86b00474daf735881d00e239d", "8dd59aa48dd64b13a1b2e3005d71a142,8dd59aa48dd64b13a1b2e3005d71dsd3", AdviceModles.AdviceType.TYPE_ADVICE, "测试", "测试", AdviceModles.WxMsg.WXMSG_YES);
wxPortalService.saveWxPortal(advice);
return result.getErrMsg();
}
}
jar包里面发送消息的源码
@Override
public WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException {
String url = httpsqyapi.weixin.qq.comcgi-binmessagesend;
Integer agentId = message.getAgentId();
if(null == agentId){
message.setAgentId(this.getWxCpConfigStorage().getAgentId());
}
return WxCpMessageSendResult.fromJson(this.post(url, message.toJson()));
}
@Override
public String[] getCallbackIp() throws WxErrorException {
String url = httpsqyapi.weixin.qq.comcgi-bingetcallbackip;
String responseContent = get(url, null);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
JsonArray jsonArray = tmpJsonElement.getAsJsonObject().get(ip_list).getAsJsonArray();
String[] ips = new String[jsonArray.size()];
for (int i = 0; i jsonArray.size(); i++) {
ips[i] = jsonArray.get(i).getAsString();
}
return ips;
}
public static WxCpMessageSendResult fromJson(String json) {
return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpMessageSendResult.class);
}
public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
Object object = fromJson(json, (Type) classOfT);
return Primitives.wrap(classOfT).cast(object);
}