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

目录结构


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 {
	@Autowired
	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/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值