Record the development process of Wechat Public Number.
First, we register a public test account of Wechat. Although the subscription number registered by the individual has this function, it has no user management function. So we will develop the public account of Wechat with the test account first.
Application for Wechat Test Number is here http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
Successful applications will be followed by their own APPID and appsecret...
The Wechat Developer Document is here... http://mp.weixin.qq.com/wiki/home/index.html
Developers can develop the interface of Wechat Public Number according to this document.
After a simple application... To try to configure the interface configuration information, you need to fill in the public network accessible link address and TOKEN to make sure that Wechat can access your program...
Link addresses accessible by public networks are not necessarily domain names or server purchases. Some network mapping tools available in China can be used. Here I use Sunny-Ngrok startup tools, or peanut shells.
According to these mapping tools, the website can be accessed on the public network. In this way, Wechat can also access my program to invoke the corresponding services...
package org.ssm.maven.test1.controller;
import java.security.MessageDigest;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/wechat")
public class WechatValidToken {
public static final String TOKEN = "ivy";
private static char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
'f' };
@RequestMapping(value="/valid", method = RequestMethod.GET)
@ResponseBody
public String validToken( HttpServletRequest request) {
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
String[] paramStr = new String[] { TOKEN, timestamp, nonce };
Arrays.sort(paramStr);
String str="";
for(String s : paramStr){
str += s;
}
String afterSha1 = sha1(str);
if (afterSha1.equals(signature))
return echostr;
else
return "null";
}
private static String sha1(String source) {
if ((source == null) || source.isEmpty()) {
return source;
}
try {
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
byte[] sha1Bytes = sha1.digest(source.getBytes());
return toHexArray(sha1Bytes);
} catch (Exception e) {
// do nothing
}
return source;
}
private static String toHexArray(byte[] array) {
char[] resultCharArray = new char[array.length * 2];
int index = 0;
for (byte b : array) {
resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
resultCharArray[index++] = hexDigits[b & 0xf];
}
return new String(resultCharArray);
}
}
This code is used to verify the receipt of information by Wechat.
The background of my Wechat Public Number is a java enterprise-class program based on ssm, and the configuration files about SSM can be found on Baidu at will on the Internet...
For subscription number message management, Wechat Public Platform provides a simple function for message management... For non-developers, this function has been able to meet the needs of ordinary Wechat public numbers...
But it's just the tip of the iceberg for a system that needs more than just ordinary information management.
Message information management can be divided into the following categories:
1 text message 2 Picture Messages 3 Voice message 4 Video Messages 5 Small Video Messages 6 Geographical location information 7 Link Messages
When ordinary micro-credit users send messages to public accounts, the micro-credit server sends the XML packet of POST messages to the developer's URL...
Text message
package org.ssm.maven.test1.controller;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.ssm.maven.test1.model.TextMessage;
import org.ssm.maven.test1.util.MessageType;
import org.ssm.maven.test1.util.MessageUtil;
@Controller
@RequestMapping("/wechat")
public class WechatController {
@RequestMapping(value = "/valid", method = RequestMethod.POST)
@ResponseBody
public String accpetMessage(HttpServletRequest request) throws IOException {
request.setCharacterEncoding("utf-8");
Map<String, String> param = MessageUtil.xmlToMap(request);
String fromUserName = param.get("FromUserName");
String toUserName = param.get("ToUserName");
String msgType = param.get("MsgType");
String content = param.get("Content");
Long createTime = Long.valueOf(param.get("CreateTime"));
Long msgId = Long.valueOf(param.get("MsgId") );
System.out.println("--------->" + param);
String message = null;
if (MessageType.TEXT.equals(msgType)) {
if ("1".equals(content)) {
message = MessageUtil.initText(MessageUtil.firstMenu(), createTime, fromUserName, toUserName, msgId);
} else if ("2".equals(content)) {
message = MessageUtil.initNewsMessage(toUserName, fromUserName);
} else if ("?".equals(content)) {
message = MessageUtil.initText(MessageUtil.menuText(), createTime, fromUserName, toUserName, msgId);
} else {
TextMessage text = new TextMessage();
text.setContent("the message is:" + content);
text.setCreateTime(createTime);
text.setToUserName(fromUserName);
text.setFromUserName(toUserName);
text.setMsgType("text");
message = MessageUtil.textMessageToXml(text);
System.out.println("message--------->" + message);
}
// StringBuffer sb = new StringBuffer();
// sb.append("<xml>");
// sb.append("<ToUserName><![CDATA[" + fromUserName +
// "]]></ToUserName>");
// sb.append("<FromUserName><![CDATA[" + toUserName +
// "]]></FromUserName>");
// sb.append("<CreateTime>" + new Date().getTime() +
// "</CreateTime>");
// sb.append("<MsgType><![CDATA[text]]></MsgType>");
// sb.append("<Content><![CDATA[this is a test]]></Content>");
// sb.append("<MsgId>1234567890123456</MsgId>");
// sb.append("</xml>");
// response.getWriter().write(message);
} else if (MessageType.EVENT.equals(msgType)) {
String event = param.get("Event");
if (MessageType.SUBSCRIBE.equals(event)) {
message = MessageUtil.initText(MessageUtil.menuText(), createTime, fromUserName, toUserName, msgId);
} else if (MessageType.CLICK.equals(event)) {
message = MessageUtil.initText(MessageUtil.menuText(), createTime, fromUserName, toUserName, msgId);
} else if (MessageType.VIEW.equals(event)) {
message = MessageUtil.initText(param.get("EventKey"), createTime, fromUserName, toUserName, msgId);
} else if (MessageType.SCANCODE.equals(event)) {
message = MessageUtil.initText(param.get("EventKey"), createTime, fromUserName, toUserName, msgId);
}
} else if (MessageType.LOCATION.equals(msgType)) {
message = MessageUtil.initText(param.get("Label"), createTime, fromUserName, toUserName, msgId);
}
return message;
}
}
Message types are mainly divided into
package org.ssm.maven.test1.util;
public class MessageType {
public static final String TEXT = "text";
public static final String NEWS = "news";
public static final String IMAGE = "image";
public static final String VOICE = "voice";
public static final String VIDEO = "video";
public static final String SHORTVIDEO = "shortvideo";
public static final String LINK = "link";
public static final String LOCATION = "location";
public static final String EVENT = "event";
public static final String SUBSCRIBE = "subscribe";//event
public static final String UNSUBSCRIBE = "unsubscribe";//event
public static final String CLICK = "CLICK";//event
public static final String VIEW = "VIEW";//event
public static final String SCANCODE = "scancode_push";//event
}
These categories are generally used, subscribe, unsubscribe, CLICK, VIEW, scancode_push under event.
Program entries follow the name of the receiving message interface between them.
Attached here is the code converted into xml and the code returned from the initialization message...
package org.ssm.maven.test1.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.ssm.maven.test1.controller.WechatController;
import org.ssm.maven.test1.model.TextMessage;
import org.ssm.maven.test1.model.WechatNews;
import org.ssm.maven.test1.model.WechatNewsMessage;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
public class MessageUtil {
protected static String PREFIX_CDATA = "<![CDATA[";
protected static String SUFFIX_CDATA = "]]>";
/**
* xml to map����
* @param request
* @return
*/
public static Map<String, String> xmlToMap(HttpServletRequest request){
Map<String, String> map = new HashMap<String, String>();
SAXReader reader = new SAXReader();
try {
InputStream ins = request.getInputStream();
Document doc = reader.read(ins);
Element root = doc.getRootElement();
List<Element> list = root.elements();
for (Element element : list) {
map.put(element.getName(), element.getText());
}
ins.close();
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
return map;
}
public static String textMessageToXml(TextMessage textMessage){
XStream xstream = new XStream();
xstream.alias("xml", textMessage.getClass());
return xstream.toXML(textMessage);
}
public static String newsMessageToXml(WechatNewsMessage wechatNewsMessage){
XStream xstream = new XStream();
xstream.alias("xml", wechatNewsMessage.getClass());
xstream.alias("item", new WechatNews().getClass());
return xstream.toXML(wechatNewsMessage);
}
/*Initialize text messages*/
public static String initText(String content, Long createTime, String fromUserName, String toUserName, Long msgId){
String message = "";
TextMessage text = new TextMessage();
text.setContent("the message is:"+content);
text.setCreateTime(createTime);
text.setToUserName(fromUserName);
text.setFromUserName(toUserName);
text.setMsgType(MessageType.TEXT);
text.setMsgId(msgId);
message = MessageUtil.textMessageToXml(text);
System.out.println("message--------->" + message);
return message;
}
/*Initialize graphic message*/
public static String initNewsMessage(String toUserName, String fromUserName){
String message = "";
WechatNewsMessage wechatNewsMessage = new WechatNewsMessage();
WechatNews wechatNews = new WechatNews();
WechatNews wechatNews1 = new WechatNews();
List<WechatNews> wechatNewss = new ArrayList<WechatNews>();
wechatNews.setTitle("ivy's description");
wechatNews.setPicUrl("http://ivytest.ngrok.cc/org.ssm.maven.test1/images/IMG_0151.JPG");
wechatNews.setUrl("http://ivytest.ngrok.cc/org.ssm.maven.test1/images/IMG_0151.JPG");
wechatNews.setDescription("i am ivy");
wechatNews1.setTitle("haha's description");
wechatNews1.setPicUrl("http://ivytest.ngrok.cc/org.ssm.maven.test1/images/IMG_0152.JPG");
wechatNews1.setUrl("http://ivytest.ngrok.cc/org.ssm.maven.test1/images/IMG_0152.JPG");
wechatNews1.setDescription("i am gaga");
wechatNewss.add(wechatNews);
wechatNewss.add(wechatNews1);
wechatNewsMessage.setArticleCount(wechatNewss.size());
wechatNewsMessage.setArticles(wechatNewss);
wechatNewsMessage.setFromUserName(toUserName);
wechatNewsMessage.setToUserName(fromUserName);
wechatNewsMessage.setCreateTime(new Date().getTime());
wechatNewsMessage.setMsgType(MessageType.NEWS);
message = newsMessageToXml(wechatNewsMessage);
return message;
}
public static String menuText(){
StringBuffer sb = new StringBuffer();
sb.append("Welcome here\n");
sb.append("1.text field\n");
sb.append("2.news field\n");
sb.append("enter ? for help\n");
return sb.toString();
}
public static String firstMenu(){
return "Hi,i am ivy";
}
public static String secondMenu(){
return "Bye,i am ivy";
}
}