您的位置:首页 > 移动开发 > 微信开发

微信企业号,文本信息发送

2016-12-14 16:40 225 查看
目录结构



maven文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>

<groupId>WeiXinEntp</groupId>
<artifactId>WeiXinEntp</artifactId>
<version>1.0</version>
<packaging>jar</packaging>

<name>WeiXinEntp</name>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 压缩 -->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.9.7</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-launcher</artifactId>
<version>1.9.7</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<finalName>weixinentp</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>WeiXinController.java
package com.guosen.weixin.controller;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.guosen.weixin.service.MsgService;

@RestController
public class WeiXinController {
private static final Logger logger = LoggerFactory.getLogger(WeiXinController.class);
@Autowired
MsgService msgService;

@RequestMapping(value = "/")
public String pint(){
return "hello";
}

@RequestMapping(value = "/sendText", method = RequestMethod.POST)
public String sendText(@RequestBody String textMsg) {
logger.info("收到发送请求[" + textMsg + "]");
ObjectMapper om = new ObjectMapper();
String result = "";
try {
result = msgService.sendText(textMsg);
} catch (Exception e) {
logger.error("发送微信出现异常", e);
Map<String, Object> map = new HashMap<String, Object>();
map.put("errcode", 999);
map.put("errmsg", e.getMessage());
try {
result = om.writeValueAsString(map);
} catch (JsonProcessingException e1) {
e1.printStackTrace();
}
}
logger.info("处理完请求,返回[" + result + "]");
return result;
}

}


MsgService.java
package com.guosen.weixin.service;

import java.nio.charset.Charset;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.guosen.weixin.util.WeiXinConfig;

@Service
public class MsgService {
@Aut
c311
owired
TokenService tokenService;
@Autowired
private WeiXinConfig weiXinConfig;
private RestTemplate restTemplate;

public RestTemplate getRestTemplate() {
if (restTemplate != null) {
return restTemplate;
}
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();

int count = -1;
for (int i = 0; i < converterList.size(); i++) {
HttpMessageConverter<?> message = converterList.get(i);
if (message.getClass() == StringHttpMessageConverter.class) {
count = i;
break;
}
}
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
converterList.set(count, stringConverter);
return restTemplate;
}

/**
* 发送消息
* @param textMsg
* @return
*/
public String sendText(String textMsg) throws Exception{
String returnMsg = "";
try {
String request = textMsg;
String token = tokenService.getToken();
if (token == null) {
throw new Exception("获取token失败");
}
String url = String.format("%s?access_token=%s", weiXinConfig.getSendurl(), token);
returnMsg = getRestTemplate().postForObject(url, request, String.class);
} catch (Exception e) {
throw e;
}
return returnMsg;
}
}


TokenService.java
package com.guosen.weixin.service;

import java.nio.charset.Charset;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.guosen.weixin.bean.TaskStatus;
import com.guosen.weixin.bean.WeiXinToken;
import com.guosen.weixin.mapper.TaskStatusMapper;
import com.guosen.weixin.mapper.WeiXinTokenMapper;
import com.guosen.weixin.util.CheckUtil;
import com.guosen.weixin.util.WeiXinConfig;

@Service
public class TokenService {
private static final Logger logger = LoggerFactory.getLogger(TokenService.class);

@Autowired
private WeiXinTokenMapper weiXinTokenMapper;
@Autowired
private TaskStatusMapper taskStatusMapper;
@Autowired
private WeiXinConfig weiXinConfig;

Map<String, WeiXinToken> tokenMap = new HashMap<String, WeiXinToken>();
/**
* 从tokenMap获取或者向tokenMap存放Token对象的key
*/
private static final String TOKEN_KEY = "token";
/**
* 自动任务类型(1为获取token)
*/
private static final int TASK_TYPE = 1;

@Bean
RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();

int count = -1;
for (int i = 0; i < converterList.size(); i++) {
HttpMessageConverter<?> message = converterList.get(i);
if (message.getClass() == StringHttpMessageConverter.class) {
count = i;
break;
}
}
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
converterList.set(count, stringConverter);
return restTemplate;
}

@Autowired
RestTemplate restTemplate;
/**
* 获取token(如果没有获取到,则返回null)
* @return
*/
public String getToken() throws Exception{
/**
* 1、从tokenMap中获取token
* 2、如果从tokenMap中获取到token
* 3、判断token是否超过有效期,如果没有超过有效期,返回token
* 4、从数据库查询token
* 5、如果没有查询到token,则报错
* 6、如果查询到token,判断是否超过有效期
* 7、如果超过有效期,则调用方法从微信获取token
* 8、如果没有超过有效期,则更新tokenMap中的值,并且返回token
*/
WeiXinToken wxt = tokenMap.get(TOKEN_KEY);
if (wxt != null && CheckUtil.checkToken(wxt)) {
return wxt.getToken();
}

wxt = getTokenFromTable();
if (wxt != null && CheckUtil.checkToken(wxt)) {
setToken(wxt);
return wxt.getToken();
}

wxt = getTokenFromUrl();
if (wxt != null && CheckUtil.checkToken(wxt)) {
setToken(wxt);
return wxt.getToken();
}
return null;
}

/**
* 从表中查询token
* @return
*/
public WeiXinToken getTokenFromTable(){
/**
* 循环查询5次,每次等待3秒,其中如果查询出自动任务执行完毕了,则跳出循环
* 1、从表中获取token对象
* 2、如果token在有效期范围之内,则终止循环返回token
* 3、如果不在token有效期范围之内,则看是否有自动任务正在更新token
* 4、如果无则终止循环返回token对象
* 5、如果有则等待5秒钟然后重复第一步
*/
int count = 0;
TaskStatus taskStatus = null;
WeiXinToken wxt = null;
while (count < 5) {
wxt = weiXinTokenMapper.find();
if (CheckUtil.checkToken(wxt)) {
break;
}
taskStatus = taskStatusMapper.findByType(TASK_TYPE);
if (taskStatus == null) {
taskStatusMapper.add(TASK_TYPE, 0, new Date());
}
boolean flag = CheckUtil.checkTaskStatus(taskStatus);
if (!flag) {
break;
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
}
return wxt;
}

/**
* 从微信服务器获取Token(如果没有获取到则返回null)
* @return
*/
@SuppressWarnings("unchecked")
public WeiXinToken getTokenFromUrl() throws Exception{
/**
* 1、设置获取token自动任务的状态为正在执行
* 2、从微信服务器获取token
* 3、更新token表中的token
* 4、返回token对象
*/
taskStatusMapper.update(TASK_TYPE, 1, new Date());
String url = String.format("%s?corpid=%s&corpsecret=%s", weiXinConfig.getTokenurl(), weiXinConfig.getCorpid(), weiXinConfig.getCorpsecret());
ObjectMapper om = new ObjectMapper();
WeiXinToken wxt = null;
try {
// 发送请求到微信服务器获取token
String token = this.restTemplate.getForObject(url, String.class);

logger.info("从微信服务器获取Token,得到[" + token + "]");
// 解析获取到的token信息json串
Map<String, String> map = om.readValue(token, Map.class);
// 如果返回的json串中包含access_token则表明本次请求成功,否则请求失败
if (map.containsKey("access_token")) {
wxt = new WeiXinToken();
wxt.setId(1);
wxt.setToken(map.get("access_token"));
wxt.setUpdatetime(new Date());

// 查询token对象
WeiXinToken tempwxt = weiXinTokenMapper.find();
// 如果获取到的token对象为空则执行插入操作
if (tempwxt == null) {
weiXinTokenMapper.add(0, wxt.getToken(), new Date());
}
// 如果获取到的token对象不为空则执行更新操作
if (tempwxt != null) {
weiXinTokenMapper.update(wxt.getToken(), new Date());
}
} else {
throw new Exception("从微信服务器获取Token出现异常,返回信息[" + token + "]");
}
} catch (Exception e) {
throw e;
} finally {
taskStatusMapper.update(TASK_TYPE, 0, new Date());
}
return wxt;
}

public void setToken(WeiXinToken weiXinToken) {
this.tokenMap.put(TOKEN_KEY, weiXinToken);
}
}


TokenTask.java
package com.guosen.weixin.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.guosen.weixin.bean.Content;
import com.guosen.weixin.bean.TaskStatus;
import com.guosen.weixin.bean.TextMsg;
import com.guosen.weixin.bean.WeiXinToken;
import com.guosen.weixin.mapper.TaskStatusMapper;
import com.guosen.weixin.mapper.WeiXinTokenMapper;
import com.guosen.weixin.service.MsgService;
import com.guosen.weixin.service.TokenService;
import com.guosen.weixin.util.CheckUtil;
import com.guosen.weixin.util.WeiXinConfig;

/**
* 定期从微信服务器获取token
*
* 创建于2016年12月9日
* @author guosen
*
*/
@Component
public class TokenTask {
private static final Logger logger = LoggerFactory.getLogger(TokenTask.class);
@Autowired
private TaskStatusMapper taskStatusMapper;
@Autowired
private WeiXinTokenMapper weiXinTokenMapper;
@Autowired
private WeiXinConfig weiXinConfig;
@Autowired
private TokenService tokenService;
@Autowired
private MsgService msgService;

/**
* 自动任务类型(1为获取token)
*/
private static final int TASK_TYPE = 1;

/**
* 每10分钟执行一次(600000)
*/
@Scheduled(fixedDelay = 600000)
public void tokenSchedule() {
WeiXinToken wxt = weiXinTokenMapper.find();
logger.info("开始执行从微信服务器获取token的自动任务");
int count = 0;
boolean flag = false;
while (count < 3) {
TaskStatus taskStatus = taskStatusMapper.findByType(TASK_TYPE);
if (!CheckUtil.checkToken(wxt) && !CheckUtil.checkTaskStatus(taskStatus)) {
try {
wxt = tokenService.getTokenFromUrl();
tokenService.setToken(wxt);
break;
} catch (Exception e) {
flag = true;
if (count == 0) {
send("自动任务从微信服务器第1次尝试获取token失败");
}
logger.error("执行定时获取token自动任务失败[第" + (count + 1) + "次]", e);
}
} else {
logger.info("由于token没有失效或者有自动任务正在更新token,略过本次自动任务");
break;
}
count++;
}
if (flag && !CheckUtil.checkToken(wxt)) {
send("自动任务从微信服务器3次尝试获取token失败");
}
if (flag && CheckUtil.checkToken(wxt)) {
send("自动任务从微信服务器" + (count + 1) + "次获取token成功");
}
logger.info("结束执行从微信服务器获取token的自动任务");
}

private void send(String text) {
try {
TextMsg tm = new TextMsg();
tm.setTouser(weiXinConfig.getTouser());
Content content = new Content();
content.setContent(text);
tm.setText(content);
tm.setAgentid(weiXinConfig.getAgentid());
ObjectMapper om = new ObjectMapper();
om.setSerializationInclusion(Include.NON_NULL);
String textMsg = om.writeValueAsString(tm);
msgService.sendText(textMsg);
} catch (Exception e) {
logger.error("自动任务从微信服务器获取token失败后发送微信消息出现异常", e);
}
}

}


application.yml
spring:
application:
name: WeiXinEntp
http:
encoding:
charset: UTF-8
enabled: true
datasource:
url: jdbc:mysql://localhost/weixin?useUnicode=true&useSSL=false&characterEncoding=UTF-8
username: root
password: 123456
driverClassName: com.mysql.jdbc.Driver

server:
port: 8080
tomcat:
uriEncoding: UTF-8

banner:
charset: UTF-8

#系统日志配置文件路径
logging:
config: classpath:log4j2.xml

#自定义配置
weixin:
tokenurl: https://qyapi.weixin.qq.com/cgi-bin/gettoken sendurl: https://qyapi.weixin.qq.com/cgi-bin/message/send corpid: xxxx
corpsecret: xxxx
touser: xxxxx
agentid: 43

mylog:
path: /root/logs/weixinentp/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: