注意:get是用于微信公众号的校验哒
post是用来接收公众号发送的请求进行处理
package com.youruan.logistics.controller;
import com.youruan.logistics.config.global.Mark;
import com.youruan.logistics.util.MessageUtil;
import com.youruan.logistics.util.SignUtil;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Enumeration;
import com.youruan.logistics.entity.TemplateParam;
import com.youruan.logistics.entity.WxTemplate;
import com.youruan.logistics.util.HttpUtilOfWx;
import com.youruan.logistics.util.SendWxMessage;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("wechat")
public class WeChatController {
private static Logger logger = Logger.getLogger(WeChatController.class);
@RequestMapping(value = "/wx.do")
public void get(HttpServletRequest request, HttpServletResponse response) throws Exception {
logger.info("WechatController ---- WechatController");
System.out.println("========WechatController========= ");
logger.info("请求进来了...");
Enumeration pNames = request.getParameterNames();
while (pNames.hasMoreElements()) {
String name = (String) pNames.nextElement();
String value = request.getParameter(name);
// out.print(name + "=" + value);
String log = "name =" + name + " value =" + value;
logger.info(log);
}
String signature = request.getParameter("signature");/// 微信加密签名
String timestamp = request.getParameter("timestamp");/// 时间戳
String nonce = request.getParameter("nonce"); /// 随机数
String echostr = request.getParameter("echostr"); // 随机字符串
PrintWriter out = response.getWriter();
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
out.print(echostr);
}
out.close();
out = null;
}
@PostMapping(value = "/wx.do")
public void doPost(HttpServletRequest request, HttpServletResponse response) throws Exception,IOException {
logger.info("接入成功,正在处理逻辑");
//接受微信服务器发送过来的XML形式的消息
InputStream in=request.getInputStream();
BufferedReader reader=new BufferedReader(new InputStreamReader(in,"UTF-8"));
String sReqData="";
String itemStr="";//作为输出字符串的临时串,用于判断是否读取完毕
while((itemStr=reader.readLine())!=null){
sReqData+=itemStr;
}
in.close();
reader.close();
System.out.println("收到消息:"+sReqData);
/*
1565690913
*/
//防止中文乱码
response.setCharacterEncoding("UTF-8");
MessageUtil.replyMessage(sReqData,response.getWriter());
/*InputStream inputStream = request.getInputStream();
Map params = XMLUtil.parseStreamToMap(inputStream);
String respXml = messageHandleService.handleMessage(params);
if (StringUtils.isNotEmpty(respXml)) {
// 输出流
response.getWriter().write(respXml);
}*/
}
/**
* 給用戶推送消息通知
* 參數:用戶openId 物流實體
* @return
* @throws Exception
*/
@PostMapping("test")
public String updateById() throws Exception {
//根据bid去查询出bos_customer中的数据
/*Bos_customer customer=projectService.findCustomerByBid(bid);
System.out.println("Bos_customer:"+customer.getCid()+"-------"+customer.getCname()+"-------"+customer.getOpenId());
*/
//接下来给这个客户发送模板消息
//先给模板中设置参数
WxTemplate tem=new WxTemplate();
tem.setTemplateId("Xk5hFStGRux8wP9Wqx45UR593LAOwYgoebi1oXVOcZA"); //模板id
tem.setTopColor("#00DD00");
tem.setToUser("o8ulT1hr9mAkR6i7-EI9vDr_lsio");//得到用户的openid
tem.setUrl("");
List paras=new ArrayList();
paras.add(new TemplateParam("first","我们将给您推送一些关于您订单进度的消息:","#FF3333"));
paras.add(new TemplateParam("keyword1","武汉物流有限公司","#0044BB"));//物流公司
paras.add(new TemplateParam("keyword2","420115124541","#0044BB"));//物流单号
paras.add(new TemplateParam("keyword3","武汉市","#0044BB"));//目的地
paras.add(new TemplateParam("keyword4","待取件","#0044BB"));//物流状态
paras.add(new TemplateParam("remark","感谢您的使用!!!!","#AAAAAA"));
tem.setTemplateParamList(paras);
//将Accesstoken拿到
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
String APPID = Mark.GZH_APPID;
String SECRET = Mark.GZH_APPSECRET;
url = url.replace("APPID", APPID);
url = url.replace("APPSECRET", SECRET);
String content = HttpUtilOfWx.httpUrlConnect(url, null, "GET");
System.out.println(content);
Map map=HttpUtilOfWx.getAccessTokenByJsonStr(content);
String accessToken=(String) map.get("access_token");
System.out.println(accessToken);
boolean result= SendWxMessage.sendTemplateMsg(accessToken,tem);
if(result==true){
System.out.println("发送成功");
}
return "redirect:showAll";
}
}
package com.youruan.logistics.util;
import com.alibaba.fastjson.JSONObject;
import com.youruan.logistics.config.excetion.ServiceException;
import com.youruan.logistics.config.global.Constant;
import com.youruan.logistics.config.global.Mark;
import org.dom4j.Document;
import org.dom4j.Element;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
public class MessageUtil {
public static void replyMessage(String message, PrintWriter out) throws IOException {
Document document = XMLUtil.readString2XML(message);
Element root = document.getRootElement();
String MsgType = XMLUtil.readNode(root, "MsgType");
String ToUserName = XMLUtil.readNode(root, "ToUserName"); //开发者微信号
String FromUserName = XMLUtil.readNode(root, "FromUserName");
String CreateTime = XMLUtil.readNode(root, "CreateTime");
String Event = XMLUtil.readNode(root, "Event");
System.out.println("MsgType="+MsgType+"\n---ToUserName="+ToUserName+"\n---FromUserName="
+FromUserName+"\n---CreateTime="+CreateTime+"\n---Event="+Event);
if (MsgType.equals(Constant.REQ_MESSAGE_TYPE_EVENT)) {
/**
* 用户关注了微信号啦
*/
if(Event.equals(Constant.EVENT_TYPE_SUBSCRIBE)){
/**
* 获取用户信息保存到数据库
*/
System.out.println("用户关注了微信号啦");
Map map = WxUserinfoByOpenId(FromUserName);
System.out.println(map.toString());
System.out.println("unionid=="+map.get("unionid"));
}
/**
* 用户取消关注啦
*/
else if(Event.equals(Constant.EVENT_TYPE_UNSUBSCRIBE)){
System.out.println("用户取消关注啦");
Map map = WxUserinfoByOpenId(FromUserName);
System.out.println(map.toString());
System.out.println("unionid=="+map.get("unionid"));
}
out.close();
}
}
/**
* 根據openId獲取微信端的用戶信息
* @param openId
* @return
* @throws IOException
*/
public static Map WxUserinfoByOpenId(String openId) throws IOException {
System.out.println("===========WxUserinfoByOpenId");
HttpUtil httpUtil = new HttpUtil();
String url = "https://api.weixin.qq.com/cgi-bin/user/info";
String accessToken = (String)getAccessToken().get("access_token");
String result = httpUtil.header("X-Requested-With", "XMLHttpRequest")
.data("openid", openId)
.data("access_token",accessToken)
.data("lang", "zh_CN")
.url(url)
.get();
System.out.println("WxUserinfoByOpenId==="+result);
Map map = JSONObject.parseObject(result, Map.class);
return map;
}
/**
* 獲取公眾號的access_token
* @return
* @throws IOException
*/
public static Map getAccessToken() throws IOException {
System.out.println("===========getAccessToken");
HttpUtil httpUtil = new HttpUtil();
String url = "https://api.weixin.qq.com/cgi-bin/token";
String result = httpUtil.header("X-Requested-With", "XMLHttpRequest")
.data("appid", Mark.GZH_APPID)
.data("secret", Mark.GZH_APPSECRET)
.data("grant_type", Mark.TOKEN_GRANT_TYPE)
.url(url)
.get();
System.out.println(result);
Map map = JSONObject.parseObject(result, Map.class);
if (!map.containsKey("access_token")) {
throw new ServiceException("错误信息:" + map.get("errmsg"));
}
return map;
}
}
package com.youruan.logistics.util;
import com.alibaba.fastjson.JSONObject;
import com.youruan.logistics.entity.WxTemplate;
/**
* 发送消息模板的类
*/
public class SendWxMessage {
public static boolean sendTemplateMsg(String token, WxTemplate template){
boolean flag=false;
String requestUrl="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";
requestUrl=requestUrl.replace("ACCESS_TOKEN", token);
String jsonResultT=CommonUtil.httpRequest(requestUrl, "POST", template.toJSON());
JSONObject jsonResult = JSONObject.parseObject(jsonResultT);
if(jsonResult!=null){
int errorCode=jsonResult.getInteger("errcode");
String errorMessage=jsonResult.getString("errmsg");
if(errorCode==0){
flag=true;
}else{
System.out.println("模板消息发送失败:"+errorCode+","+errorMessage);
flag=false;
}
}
return flag;
}
}
package com.youruan.logistics.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public class SignUtil {
private static String token = "tongfenfen";
/**
* 校验签名
*/
public static boolean checkSignature(String signature, String timestamp, String nonce) {
System.out.println("signature:" + signature + "timestamp:" + timestamp + "nonc:" + nonce);
String[] arr = new String[] { token, timestamp, nonce };
// 将token、timestamp、nonce三个参数进行字典序排序
Arrays.sort(arr);
StringBuilder content = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
content.append(arr[i]);
}
MessageDigest md = null;
String tmpStr = null;
try {
md = MessageDigest.getInstance("SHA-1");
// 将三个参数字符串拼接成一个字符串进行sha1加密
byte[] digest = md.digest(content.toString().getBytes());
tmpStr = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
content = null;
// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
System.out.println(tmpStr.equals(signature.toUpperCase()));
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
}
/**
* 将字节数组转换为十六进制字符串
*
* @param byteArray
* @return
*/
private static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
* 将字节转换为十六进制字符串
*
* @param mByte
* @return
*/
private static String byteToHexStr(byte mByte) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
char[] tempArr = new char[2];
tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
tempArr[1] = Digit[mByte & 0X0F];
String s = new String(tempArr);
return s;
}
}
package com.youruan.logistics.util;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
public class XMLUtil {
public static String content="";
public static Document readString2XML(String str){
Document document=null;
try {
document=DocumentHelper.parseText(str);
} catch (DocumentException e) {
e.printStackTrace();
}
return document;
};
/**
* 读取根节点下每一个节点信息
* @param node
* @return
*/
public static String readNodes(Element node){
content+=node.getName()+":"+node.getTextTrim()+"\n";
//递归遍历当前节点所有的子节点
List listElement=node.elements();//所有一级子节点的list
for(Element e:listElement){//遍历所有一级子节点
readNodes(e);//递归
}
return content;
}
/**
* 读取单个节点信息
* @param node
* @param name
* @return
*/
public static String readNode(Element node,String name){
Element e=node.element(name);
String nodeString=e.getTextTrim();
return nodeString;
}
}
package com.youruan.logistics.util;
import com.alibaba.fastjson.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
public class HttpUtilOfWx {
public static String httpUrlConnect(String httpUrl, String params,
String method) throws Exception {
URL url = new URL(httpUrl);
HttpURLConnection urlConnection = (HttpURLConnection) url
.openConnection();
urlConnection.setRequestProperty("accept", "*/*");
urlConnection.setRequestProperty("connection", "Keep-Alive");
urlConnection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setRequestMethod(method);
urlConnection.connect();
PrintWriter out = null;
BufferedReader in = null;
if (null != params && !"".equals(params)) {
out = new PrintWriter(new OutputStreamWriter(
urlConnection.getOutputStream(), "utf-8"));
out.print(params);
out.flush();
}
in = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream(), "utf-8"));
String line;
String result = "";
while ((line = in.readLine()) != null) {
result += line;
}
return result;
}
/**
* 根据字符串json数据解析access_token
* @param jsonStr
* @return map
*/
public static Map getAccessTokenByJsonStr(String jsonStr){
/* JSONObject jsonObj = new JSONObject(jsonStr);
if(jsonObj.has("access_token")){
map.put("access_token", jsonObj.get("access_token"));
}
if(jsonObj.has("expires_in")){
map.put("expires_in", jsonObj.get("expires_in"));
}*/
Map map = JSONObject.parseObject(jsonStr, Map.class);
/*if (!map.containsKey("openid")) {
throw new ServiceException("错误信息:" + map.get("errmsg"));
}*/
return map;
}
}
package com.youruan.logistics.entity;
public class TemplateParam {
//模板消息由于模板选取不同,那么就要封装俩个实体类
// 参数名称
private String name;
// 参数值
private String value;
// 颜色
private String color;
public TemplateParam() {
super();
// TODO Auto-generated constructor stub
}
public TemplateParam(String name,String value,String color){
this.name=name;
this.value=value;
this.color=color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
package com.youruan.logistics.entity;
import java.util.List;
/**
* 模板基类
*
*/
public class WxTemplate {
//消息接收方
private String toUser;
//模板id
private String templateId;
//模板消息详情链接
private String url;
//消息顶部的颜色
private String topColor;
//参数列表
private List templateParamList;
public WxTemplate() {
super();
// TODO Auto-generated constructor stub
}
public WxTemplate(String toUser, String templateId, String url,
String topColor, List templateParamList) {
super();
this.toUser = toUser;
this.templateId = templateId;
this.url = url;
this.topColor = topColor;
this.templateParamList = templateParamList;
}
public String getToUser() {
return toUser;
}
public void setToUser(String toUser) {
this.toUser = toUser;
}
public String getTemplateId() {
return templateId;
}
public void setTemplateId(String templateId) {
this.templateId = templateId;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getTopColor() {
return topColor;
}
public void setTopColor(String topColor) {
this.topColor = topColor;
}
public List getTemplateParamList() {
return templateParamList;
}
public void setTemplateParamList(List templateParamList) {
this.templateParamList = templateParamList;
}
public String toJSON() {
StringBuffer buffer = new StringBuffer();
buffer.append("{");
buffer.append(String.format("\"touser\":\"%s\"", this.toUser)).append(",");
buffer.append(String.format("\"template_id\":\"%s\"", this.templateId)).append(",");
buffer.append(String.format("\"url\":\"%s\"", this.url)).append(",");
buffer.append(String.format("\"topcolor\":\"%s\"", this.topColor)).append(",");
buffer.append("\"data\":{");
TemplateParam param = null;
for (int i = 0; i < this.templateParamList.size(); i++) {
param = templateParamList.get(i);
// 判断是否追加逗号
if (i < this.templateParamList.size() - 1){
buffer.append(String.format("\"%s\": {\"value\":\"%s\",\"color\":\"%s\"},", param.getName(), param.getValue(), param.getColor()));
}else{
buffer.append(String.format("\"%s\": {\"value\":\"%s\",\"color\":\"%s\"}", param.getName(), param.getValue(), param.getColor()));
}
}
buffer.append("}");
buffer.append("}");
return buffer.toString();
}
}
/**
* 微信触发的事件
*/
public static final Object REQ_MESSAGE_TYPE_EVENT = "event";
public static final Object EVENT_TYPE_SUBSCRIBE = "subscribe"; //关注
public static final Object EVENT_TYPE_UNSUBSCRIBE = "unsubscribe"; //取消关注