java微信公众号开发案例
|
微信公众号开发一般是针对企业和组织的,个人一般只能申请订阅号,并且调用的接口有限,下面我们就来简单的描述下接入公众号的步骤: 1、首先你需要一个邮箱在微信公众号平台进行注册; 2、注册完后,我们登录到公众号平台--->开发--->基本配置,这里需要填写URL和token,URL就是我们使用服务器的接口; 3、Java Web服务器程序编译好且在服务器上部署可以运行的话,可在微信公众号进行在线接口调试: 1)、选择合适的接口 eg:获取access_token的步骤: 1)、接口类型:基础支持 我们这里验证比较多的是消息接口调试:文本消息、图片消息、语音消息、视频消息、etc 4、接口有不理解的地方,可进入开发-->开发者工具-->开发者文档进行查询 5、接口权限:订阅号主要有基础支持、接收消息及网页服务里面的一些接口 下面我们主要讲订阅号怎么样接收消息的案例: 1、需要申请一个个人微信订阅号 1)、AccountsServlet.java类,验证来自微信服务器和微信服务器的消息处理
package cn.jon.wechat.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.jon.wechat.service.AccountsService;
import cn.jon.wechat.utils.SignUtil;
public class AccountsServlet extends HttpServlet {
public AccountsServlet() {
super();
}
public void destroy() {
super.destroy();
// Put your code here
}
/**
* 确认请求来自于微信服务器
*/
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException,IOException {
System.out.println("接口测试开始!!!");
//微信加密签名
String signature = request.getParameter("signature");
//时间戳
String timestamp = request.getParameter("timestamp");
//随机数
String nonce = request.getParameter("nonce");
//随机字符串
String echostr = request.getParameter("echostr");
PrintWriter out = response.getWriter();
//通过校验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
if(SignUtil.checkSignature(signature,timestamp,nonce)){
out.print(echostr);
}
out.close();
out = null;
// response.encodeRedirectURL("success.jsp");
}
/**
* 处理微信服务器发来的消息
*/
public void doPost(HttpServletRequest request,IOException {
//消息的接受、处理、响应
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
//调用核心业务类型接受消息、处理消息
String respMessage = AccountsService.processRequest(request);
//响应消息
PrintWriter out = response.getWriter();
out.print(respMessage);
out.close();
}
public void init() throws ServletException {
// Put your code here
}
}
2)、SignUtil.java类,请求校验工具类,token需要和微信中填写的token一致
package cn.jon.wechat.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* 请求校验工具类
* @author jon
*/
public class SignUtil {
//与微信配置中的的Token一致
private static String token = "";
public static boolean checkSignature(String signature,String timestamp,String nonce) {
String[] arra = new String[]{token,nonce};
//将signature,nonce组成数组进行字典排序
Arrays.sort(arra);
StringBuilder sb = new StringBuilder();
for(int i=0;i<arra.length;i++){
sb.append(arra[i]);
}
MessageDigest md = null;
String stnStr = null;
try {
md = MessageDigest.getInstance("SHA-1");
byte[] digest = md.digest(sb.toString().getBytes());
stnStr = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//释放内存
sb = null;
//将sha1加密后的字符串与signature对比,标识该请求来源于微信
return stnStr!=null?stnStr.equals(signature.toUpperCase()):false;
}
/**
* 将字节数组转换成十六进制字符串
* @param digestArra
* @return
*/
private static String byteToStr(byte[] digestArra) {
// TODO Auto-generated method stub
String digestStr = "";
for(int i=0;i<digestArra.length;i++){
digestStr += byteToHexStr(digestArra[i]);
}
return digestStr;
}
/**
* 将字节转换成为十六进制字符串
*/
private static String byteToHexStr(byte dByte) {
// TODO Auto-generated method stub
char[] Digit = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] tmpArr = new char[2];
tmpArr[0] = Digit[(dByte>>>4)&0X0F];
tmpArr[1] = Digit[dByte&0X0F];
String s = new String(tmpArr);
return s;
}
public static void main(String[] args) {
/*byte dByte = 'A';
System.out.println(byteToHexStr(dByte));*/
Map<String,String> map = new ConcurrentHashMap<String,String>();
map.put("4","zhangsan");
map.put("100","lisi");
Set set = map.keySet();
Iterator iter = set.iterator();
while(iter.hasNext()){
// String keyV = (String) iter.next();
String key =(String)iter.next();
System.out.println(map.get(key));
// System.out.println(map.get(iter.next()));
}
/*for(int i=0;i<map.size();i++){
}*/
}
}
3)、AccountsService.java服务类,主要是消息的请求和响应处理,并且当用户关注你的公众号的时候,可以设置默认推送消息
package cn.jon.wechat.service;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import cn.jon.wechat.message.req.ImageMessage;
import cn.jon.wechat.message.req.LinkMessage;
import cn.jon.wechat.message.req.LocationMessage;
import cn.jon.wechat.message.req.VideoMessage;
import cn.jon.wechat.message.req.VoiceMessage;
import cn.jon.wechat.message.resp.TextMessage;
import cn.jon.wechat.utils.MessageUtil;
/**
* 解耦,使控制层与业务逻辑层分离开来,主要处理请求,响应
* @author jon
*/
public class AccountsService {
public static String processRequest(HttpServletRequest request) {
String respMessage = null;
//默认返回的文本消息内容
String respContent = "请求处理异常,请稍后尝试!";
try {
//xml请求解析
Map<String,String> requestMap = MessageUtil.pareXml(request);
//发送方账号(open_id)
String fromUserName = requestMap.get("FromUserName");
//公众账号
String toUserName = requestMap.get("ToUserName");
//消息类型
String msgType = requestMap.get("MsgType");
//默认回复此文本消息
TextMessage defaultTextMessage = new TextMessage();
defaultTextMessage.setToUserName(fromUserName);
defaultTextMessage.setFromUserName(toUserName);
defaultTextMessage.setCreateTime(new Date().getTime());
defaultTextMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_TEXT);
defaultTextMessage.setFuncFlag(0);
// 由于href属性值必须用双引号引起,这与字符串本身的双引号冲突,所以要转义
defaultTextMessage.setContent("欢迎访问<a href="http://blog.csdn.net/j086924">jon的博客</a>!");
// defaultTextMessage.setContent(getMainMenu());
// 将文本消息对象转换成xml字符串
respMessage = MessageUtil.textMessageToXml(defaultTextMessage);
//文本消息
if(msgType.equals(MessageUtil.MESSSAGE_TYPE_TEXT)){
//respContent = "Hi,您发送的是文本消息!";
//回复文本消息
TextMessage textMessage = new TextMessage();
// textMessage.setToUserName(toUserName);
// textMessage.setFromUserName(fromUserName);
//这里需要注意,否则无法回复消息给用户了
textMessage.setToUserName(fromUserName);
textMessage.setFromUserName(toUserName);
textMessage.setCreateTime(new Date().getTime());
textMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_TEXT);
textMessage.setFuncFlag(0);
respContent = "Hi,你发的消息是:"+requestMap.get("Content");
textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);
}
//图片消息
else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_IMAGE)){
ImageMessage imageMessage=new ImageMessage();
imageMessage.setToUserName(fromUserName);
imageMessage.setFromUserName(toUserName);
imageMessage.setCreateTime(new Date().getTime());
imageMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_IMAGE);
//respContent=requestMap.get("PicUrl");
imageMessage.setPicUrl("http://img24.pplive.cn//2013//07//24//12103112092_230X306.jpg");
respMessage = MessageUtil.imageMessageToXml(imageMessage);
}
//地理位置
else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_LOCATION)){
LocationMessage locationMessage=new LocationMessage();
locationMessage.setToUserName(fromUserName);
locationMessage.setFromUserName(toUserName);
locationMessage.setCreateTime(new Date().getTime());
locationMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_LOCATION);
locationMessage.setLocation_X(requestMap.get("Location_X"));
locationMessage.setLocation_Y(requestMap.get("Location_Y"));
locationMessage.setScale(requestMap.get("Scale"));
locationMessage.setLabel(requestMap.get("Label"));
respMessage = MessageUtil.locationMessageToXml(locationMessage);
}
//视频消息
else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_VIDEO)){
VideoMessage videoMessage=new VideoMessage();
videoMessage.setToUserName(fromUserName);
videoMessage.setFromUserName(toUserName);
videoMessage.setCreateTime(new Date().getTime());
videoMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_VIDEO);
videoMessage.setMediaId(requestMap.get("MediaId"));
videoMessage.setThumbMediaId(requestMap.get("ThumbMediaId"));
respMessage = MessageUtil.videoMessageToXml(videoMessage);
}
//链接消息
else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_LINK)){
LinkMessage linkMessage=new LinkMessage();
linkMessage.setToUserName(fromUserName);
linkMessage.setFromUserName(toUserName);
linkMessage.setCreateTime(new Date().getTime());
linkMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_LINK);
linkMessage.setTitle(requestMap.get("Title"));
linkMessage.setDescription(requestMap.get("Description"));
linkMessage.setUrl(requestMap.get("Url"));
respMessage = MessageUtil.linkMessageToXml(linkMessage);
}
//语音消息
else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_VOICE)){
VoiceMessage voiceMessage=new VoiceMessage();
voiceMessage.setToUserName(fromUserName);
voiceMessage.setFromUserName(toUserName);
voiceMessage.setCreateTime(new Date().getTime());
voiceMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_VOICE);
voiceMessage.setMediaId(requestMap.get("MediaId"));
voiceMessage.setFormat(requestMap.get("Format"));
respMessage = MessageUtil.voiceMessageToXml(voiceMessage);
}
//事件推送
else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_EVENT)){
//事件类型
String eventType = requestMap.get("Event");
//订阅
if(eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)){
respContent = "谢谢关注!";
}
//取消订阅
else if(eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)){
//
System.out.println("取消订阅");
}
else if(eventType.equals(MessageUtil.EVENT_TYPE_CLICK)){
//自定义菜单消息处理
System.out.println("自定义菜单消息处理");
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return respMessage;
}
public static String getMainMenu()
{
StringBuffer buffer =new StringBuffer();
buffer.append("您好,我是jon,请回复数字选择服务:").append("n");
buffer.append("1、我的博客").append("n");
buffer.append("2、 歌曲点播").append("n");
buffer.append("3、 经典游戏").append("n");
buffer.append("4 、聊天打牌").append("nn");
buffer.append("回复"+"0"+"显示帮助菜单");
return buffer.toString();
}
}
(编辑:鄂州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
