1.微信公众号测试账号:
找到服务号的开发文档,点击进去。
-
Java代码:
准备工作:
(1)填写JS接口安全域名
(2)填写接口配置信息:(2)java的Token验证接口
@RequestMapping(value = "/verifier",method = {RequestMethod.GET})
public void processGet(HttpServletRequest request, HttpServletResponse response) throws Exception{
System.out.println("验证接口消息");
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
//校验证签名
boolean check = wxService.check(signature, timestamp, nonce);
if (check){
System.out.println("接入成功");
PrintWriter writerOut = response.getWriter();
writerOut.print(echostr);
writerOut.flush();
writerOut.close();
}else {
System.out.println("接入失败");
}
}
验证签名:
public boolean check(String signature, String timestamp, String nonce){
//字典排序
String token = "自定义的Token值";
String[] wxStrArr = {token, timestamp, nonce};
Arrays.sort(wxStrArr);
//进行sha1加密
String wxString = wxStrArr[0]+wxStrArr[1]+wxStrArr[2];
String wxSha1 = sha1(wxString);
//加密后的数据和signature进行对比
return StringUtils.equalsIgnoreCase(wxSha1,signature);
}
private static String sha1(String wxString) {
try {
//获取加密对象
MessageDigest sha1 = MessageDigest.getInstance("sha1");
byte[] digest = sha1.digest(wxString.getBytes());
StringBuilder sb = new StringBuilder();
char[] chars = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
//处理加密结果
for (byte b : digest) {
sb.append(chars[(b>>4)&15]);
sb.append(chars[b&15]);
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
###创建菜单;
(1)抽象的菜单类
public class AbstractButton {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public AbstractButton(String name) {
super();
this.name = name;
}
}
(2)view菜单
public class ViewButton extends AbstractButton {
private String type = "view";
private String url;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public ViewButton(String name, String url) {
super(name);
this.url = url;
}
}
###获取Token
public void getToken(){
String wxTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
String appId = "微信公众号的APPID值";
String appsecret = "微信公众号的APPSECRET值";
String url = StringUtils.replace(wxTokenUrl, "APPID", appId).replace("APPSECRET", appsecret);
String tokenStr = WechatUtils.get(url);
JSONObject tokenjson = JSONObject.fromObject(tokenStr);
String accessToken = tokenjson.getString("access_token");
String expiresIn = tokenjson.getString("expires_in");
//
wxAccessToken = new WxAccessToken(accessToken,expiresIn);
}
Token的有效时间为2小时,创建一个保存Token值和判断Token是否过期的类;
public class WxAccessToken {
private String accessToken;
private long expiresTime;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public long getExpiresTime() {
return expiresTime;
}
public void setExpiresTime(long expiresTime) {
this.expiresTime = expiresTime;
}
public WxAccessToken(String accessToken, String expiresIn) {
super();
this.accessToken = accessToken;
expiresTime = System.currentTimeMillis()+Integer.parseInt(expiresIn)*1000;
}
/**
*判断 accessToken是否过期
*/
public boolean isExpires(){
return System.currentTimeMillis()>expiresTime;
}
}
向外暴露 获取Token方法
/**
*向外暴露 获取Token方法
*
*/
public String getAccessToken(){
if (wxAccessToken == null || wxAccessToken.isExpires()){
getToken();
}
return wxAccessToken.getAccessToken();
}
创建微信公众号菜单的接口:
/**
*创建微信的自定义菜单
*/
public void createMenu(){
String creatMenuUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
String appId = "微信公众号的APPID值";
String reUrl = "点击菜单需要跳转的路径";
int result = 0;
String accessToken = getAccessToken();
String muenUrlAccessToken = StringUtils.replace(creatMenuUrl, "ACCESS_TOKEN", accessToken);
Button button = new Button();
//设置url要加https//
button.getButton().add(new ViewButton("菜单名称","https://open.weixin.qq.com/connect/oauth2/authorize?appid="+appId+"&redirect_uri="+reUrl+"/login&response_type=code&scope=snsapi_base&#wechat_redirect"));
String jsonObjectStr = JSONObject.fromObject(button).toString();
JSONObject jsonObject = WechatUtils.httpRequest(muenUrlAccessToken, "POST", jsonObjectStr);
if (null != jsonObject) {
if (0 != jsonObject.getInt("errcode")) {
result = jsonObject.getInt("errcode");
System.out.println("创建菜单失败 errcode:{}");
System.out.println(jsonObject.getString("errmsg"));
System.out.println(jsonObject.getInt("errcode"));
}
}
}
创建微信的工具类:
package cn.kkou.justice.common.utils;
import cn.kkou.justice.common.MyX509TrustManager;
import cn.kkou.justice.common.PropertiesLoader;
import net.sf.json.JSONObject;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLConnection;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author
* @version 1.0.0
*/
public class WechatUtils {
private static Logger logger = LoggerFactory.getLogger(PropertiesLoader.class);
/**
*向指定的地址发送get请求
*/
public static String get(String url){
try {
URL urlObj = new URL(url);
//开连接
URLConnection urlConnection = urlObj.openConnection();
InputStream is = urlConnection.getInputStream();
byte[] bytes = new byte[1024];
int len;
StringBuilder sb = new StringBuilder();
while ((len=is.read(bytes))!=-1){
sb.append(new String(bytes,0,len));
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 描述: 发起https请求并获取结果
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
httpUrlConn.setSSLSocketFactory(ssf);
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
// 设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod)){
httpUrlConn.connect();
}
// 当有数据需要提交时
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 将返回的输入流转换成字符串
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
logger.info("连接超时:",ce);
} catch (Exception e) {
logger.info("微信菜单创建请求错误:",e);
}
return jsonObject;
}
/*
* xml转map
*/
public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException {
HashMap<String, String> map = new HashMap<String,String>();
SAXReader reader = new SAXReader();
InputStream ins = request.getInputStream();
Document doc = reader.read(ins);
Element root = doc.getRootElement();
@SuppressWarnings("unchecked")
List<Element> list = (List<Element>)root.elements();
for(Element e:list){
map.put(e.getName(), e.getText());
}
ins.close();
return map;
}
}
推送模板消息给关注的用户:
//1,推送消息
JSONObject templateMessage = disposeTemInfo("用户的openId");
//3,如果是正式版发送模版消息,这里需要配置你的信息
JSONObject msgJsonObject = disposePushInfoList();
JSONObject jsonObject = JSONObject.fromObject(templateMessage);
jsonObject.put("data",msgJsonObject);
//发起推送
try {
sendTemplateMsg(jsonObject);
System.out.println("推送成功");
} catch (Exception e) {
System.out.println("推送失败:" + e.getMessage());
e.printStackTrace();
}
public JSONObject disposeTemInfo(String openId){
//openId是用户关注公众号的唯一标识
String wxTemplateId = "模板Id";
String appId = "APPID";
String url = "点击消息跳转的路径";
JSONObject templateMessageJson = new JSONObject();
templateMessageJson.put("touser",openId);
templateMessageJson.put("template_id",wxTemplateId);
templateMessageJson.put("url","https://open.weixin.qq.com/connect/oauth2/authorize?appid="+appId+"&redirect_uri="+url+"/login&response_type=code&scope=snsapi_base&#wechat_redirect");
return templateMessageJson;
}
public JSONObject disposePushInfoList(){
//对应微信公众号模板的.DATA 前面的值
String wxTemplateFirst = "";
String wxTemplateKey1 = "";
String wxTemplateKey2 = "";
String wxTemplateKey3 = "";
String wxTemplateRemark = "";
//字体颜色
String wxTemplateColor ="";
String firstStr = StringUtils.EMPTY;
JSONObject first = new JSONObject();
first.put("value",firstStr);
first.put("color",wxTemplateColor);
JSONObject KeyWord1 = new JSONObject();
KeyWord1.put("value","");
KeyWord1.put("color",wxTemplateColor);
JSONObject KeyWord2 = new JSONObject();
KeyWord2.put("value","");
KeyWord2.put("color",wxTemplateColor);
JSONObject KeyWord3 = new JSONObject();
KeyWord3.put("value","";
KeyWord3.put("color",wxTemplateColor);
JSONObject remark = new JSONObject();
remark.put("value","");
remark.put("color",wxTemplateColor);
JSONObject msgJson = new JSONObject();
msgJson.put(wxTemplateFirst,first);
msgJson.put(wxTemplateKey1,KeyWord1);
msgJson.put(wxTemplateKey2,KeyWord2);
msgJson.put(wxTemplateKey3,KeyWord3);
msgJson.put(wxTemplateRemark,remark);
return msgJson;
}
public void sendTemplateMsg(JSONObject templateMessage){
int result = 0;
String accessToken = getAccessToken();
String sendMsgUrlStr = StringUtils.replace("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN", "ACCESS_TOKEN", accessToken);
String msgJsonStr = templateMessage.toString();
JSONObject jsonObject = WechatUtils.httpRequest(sendMsgUrlStr, "POST", msgJsonStr);
if (null != jsonObject) {
if (0 != jsonObject.getInt("errcode")) {
result = jsonObject.getInt("errcode");
logger.error("推送消息失败");
}
}
}