开发步骤
1.准备应用开发服务器,获取访问地址,开发者中心服务器配置须用到。
2.通过测试号申请系统,可通过微信扫描二维码快速申请一个接口测试号,可查看接口权限表
3.配置公众号菜单
自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。
一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。
创建自定义菜单后,由于微信客户端缓存,需要24小时微信客户端才会展现 出来。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的 效果。
自定义菜单格式如下(测试服务号):
"menu": {
"button": [
{
"name": "课程中心",
"sub_button": [
{
"type": "view",
"name": "我的课程",
"url": "http://v4.21tb.com/wx/checkLogin.do?functionName=myCourse",
"sub_button": [ ]
},
{
"type": "view",
"name": "可选课程",
"url": "http://v4.21tb.com/wx/checkLogin.do?functionName=selectCourse",
"sub_button": [ ]
}
]
},
{
"name": "个人中心",
"sub_button": [
{
"type": "view",
"name": "我的考试",
"url": "http://v4.21tb.com/wx/checkLogin.do?functionName=myExam",
"sub_button": [ ]
},
{
"type": "view",
"name": "我的问卷",
"url": "http://v4.21tb.com/wx/checkLogin.do?functionName=myQuestionnaire",
"sub_button": [ ]
},
{
"type": "view",
"name": "我的评估",
"url": "http://v4.21tb.com/wx/checkLogin.do?functionName=myOem",
"sub_button": [ ]
},
{
"type": "view",
"name": "我的资讯",
"url": "http://v4.21tb.com/wx/checkLogin.do?functionName=myNews",
"sub_button": [ ]
},
{
"type": "view",
"name": "我的档案",
"url": "http://v4.21tb.com/wx/checkLogin.do?functionName=myPortfolio",
"sub_button": [ ]
}
]
},
{
"name": "其他",
"sub_button": [
{
"type": "view",
"name": "ELP微平台",
"url": "http://v4.21tb.com/wx/checkLogin.do?functionName=wxElnIndex",
"sub_button": [ ]
},
{
"type": "view",
"name": "个人名片",
"url": "http://v4.21tb.com/wx/checkLogin.do?functionName=myCard",
"sub_button": [ ]
},
{
"type": "view",
"name": "在线反馈",
"url": "http://v4.21tb.com/wx/checkLogin.do?functionName=feedback",
"sub_button": [ ]
},
{
"type": "view",
"name": "退出",
"url": "http://v4.21tb.com/wx/loginOut.do?functionName=checkLogin",
"sub_button": [ ]
}
]
}
]
}
手机端菜单显示如下:
4.应用与微信对接
服务端接收逻辑:
/**
* /wx/wechat/index.do
*
* Date: 2/18/14
* Time: 12:07 AM
*/
public class WeChatAction extends BaseAction<IndexModel> {
public String index() throws IOException {
String corpCode = request.getParameter("corpCode");
if(StringUtils.isNotBlank(corpCode)){
ExecutionContext.setCorpCode(corpCode);
}
if (RequestUtil.isGet()) {
// 微信加密签名
String signature = request.getParameter("signature");
// 随机字符串
String echostr = request.getParameter("echostr");
// 时间戳
String timestamp = request.getParameter("timestamp");
// 随机数
String nonce = request.getParameter("nonce");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
if (StringUtils.isBlank(signature)) {
out.print("wechat param not found");
} else if (SignUtil.checkSignature(signature, timestamp, nonce)) {
out.print(echostr);
}
out.close();
out = null;
} else if (RequestUtil.isPost()) {
// 将请求、响应的编码均设置为UTF-8(防止中文乱码)
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
// 调用核心业务类接收消息、处理消息
String respMessage =CoreService.processRequest(request,response);
// 响应消息
PrintWriter out = response.getWriter();
out.print(respMessage);
out.close();
}
return null;
}
}
public class CoreService {
/**
* 处理微信发来的请求
*
* @param request
* @return
*/
public static String processRequest(HttpServletRequest request,HttpServletResponse response) {
String respMessage = null;
try {
// 默认返回的文本消息内容
StringBuilder respContent = new StringBuilder();
// xml请求解析
Map<String, String> requestMap = MessageUtil.parseXml(request);
// 发送方帐号(open_id)
String fromUserName = requestMap.get("FromUserName");
// 公众帐号
String toUserName = requestMap.get("ToUserName");
// 消息类型
String msgType = requestMap.get("MsgType");
String content = requestMap.get("Content");
String eventKey = requestMap.get("EventKey");
// 回复文本消息
TextMessage textMessage = new TextMessage();
textMessage.setToUserName(fromUserName);
textMessage.setFromUserName(toUserName);
textMessage.setCreateTime(new Date().getTime());
textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
textMessage.setFuncFlag(0);
// 文本消息
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
if (content.equalsIgnoreCase("授权")
|| content.equalsIgnoreCase("登录")
|| content.equalsIgnoreCase("登陆")
|| content.equalsIgnoreCase("\"登录\"")
|| content.equalsIgnoreCase("dl")) {
respContent.append(loginMsg(request, fromUserName));
} else {
//respContent.append("您发送的是文本消息!");
}
}
// 图片消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {
//respContent.append("您发送的是图片消息!");
}
// 地理位置消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {
//respContent.append("您发送的是地理位置消息!");
}
// 链接消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {
//respContent.append("您发送的是链接消息!");
}
// 音频消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {
//respContent.append("您发送的是音频消息!");
}
// 事件推送
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
// 事件类型
String eventType = requestMap.get("Event");
// 订阅
if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
respContent.append(subscribeMsg(request, fromUserName));
}
//取消订阅
else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {
//取消订阅后用户再收不到公众号发送的消息,因此不需要回复消息,取消授权关系
ApplicationContext app = new ClassPathXmlApplicationContext(new String [] {"classpath:applicationContext.xml","classpath:spring-localCache.xml"});
JedisCommands jedis = app.getBean("jedisSession", JedisCommands.class);
Map<String,String> object = jedis.hgetAll(fromUserName);
if(MapUtils.isNotEmpty(object)){
ExecutionContext.setCorpCode(object.get(ELNConfigure.CORP_CODE));
UserService userService = app.getBean("userService",UserService.class);
userService.cancelBindWCharId(fromUserName,object.get(ELNConfigure.CORP_CODE));
}else{
String serverName = request.getServerName();
String baseDomain = CustomDomainUtil.getBaseDomain(serverName);
String cookieDomain = "." + baseDomain;
CookieUtil.setCookie(response, ELNConfigure.WX_ELN_SESSION_ID, null,
ELNConfigure.COOKIE_PATH, "0", cookieDomain);
CookieUtil.setCookie(response, ELNConfigure.CORP_CODE, null,
ELNConfigure.COOKIE_PATH, "0", cookieDomain);
CookieUtil.setCookie(response, "_wcharId", null,
ELNConfigure.COOKIE_PATH, "0", cookieDomain);
}
ExecutionContext.setCorpCode(null);
}
// 自定义菜单点击事件
else
if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {
if (eventKey.equalsIgnoreCase("LOGIN")) {
respContent.append(loginMsg(request, fromUserName));
}
// else {
// //respContent.append("您发来的是点击菜单事件");
// }
else if(eventKey.equalsIgnoreCase("send_news")){
NewsMessage newsMessage = new NewsMessage();
newsMessage.setToUserName(fromUserName);
newsMessage.setFromUserName(toUserName);
newsMessage.setCreateTime(new Date().getTime());
newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
newsMessage.setArticleCount(2);
List<Article> articles = new ArrayList<Article>();
Article article = new Article();
article.setTitle("文章1");
article.setDescription("挺好的一篇文章");
article.setPicUrl("http://yufa.21tb.com/wx/images/course/els_course_cover_default.png");
article.setUrl("");
articles.add(article);
Article article1 = new Article();
article1.setTitle("文章2");
article1.setDescription("挺好的一篇文章");
article1.setPicUrl("http://yufa.21tb.com/wx/images/course/els_course_cover_default.png");
article1.setUrl("");
articles.add(article1);
newsMessage.setArticles(articles);
respMessage = MessageUtil.newsMessageToXml(newsMessage);
return respMessage;
}
}
} else {
respContent.append("请求处理异常,请稍候尝试!");
}
textMessage.setContent(respContent.toString());
respMessage = MessageUtil.textMessageToXml(textMessage);
} catch (Exception e) {
e.printStackTrace();
}
return respMessage;
}
}
5.实现自己的服务业务