微信公众号开发大体步骤如下:
- 申请公众号
- 购买阿里云ESC 实例
- 配置公众号开发者工具
- 搭建本地服务框架SSM
- 编码
- 部署阿里云服务器
- 测试
申请公众号
事物的发展顶峰必然由盛转衰、是公众号已经火了很久了,至于什么时候死,拭目以待吧。
微信申请公众号分为服务号与订阅号、*机关、企业属于服务号、个人或其他组织属于订阅号,服务号一般需要相关材料证明,并且申请费300RMB /年,订阅号一般不要什么材料(只需要个人身份证正反面照片)、也不用交费,当然订阅号功能比服务号功能少!这里我暂且申请订阅号。
申请完后就可以直接登陆进入后台管理页面
点击右上角公众号名称如图:
可以看到公众号基本详情。
购买阿里云ESC 实例
为什么 购买阿里云?因为微信公众号回调接口连接的是公网、普通用户ip 基本都是私网、故申请域名,服务器!这里说明一下、目前国内服务器供应商相对较好是阿里云、国外亚马逊、二者区别:国内网速相对国内用户比较好、加个也相对贵点、国外的价格便宜、但对于大陆用户网速较慢。我个人买的是阿里云服务器:
最重要的是购买域名、然后备案、备案这个比较麻烦,不出意外的话一个月时间就能备案成功、这里我的域名备案已经成功。
配置公众号开发者工具
点击左立列表菜单 找到“开发者工具”点击去配置公众号开发选项:
这里Appid 、AppSecret 在代码里配置,服务器配置是微信公众号服务器回调你本地服务器接口、其中url 是你服务器提供回调接口、token 令牌随便写、同时在代码里也是保持一样,EncodingAESKey 消息加密密钥、随机生成、代码里也需要配置一样,消息加解密方式,有三种:明文、兼容、私密模式、这里是兼容模式。
公众号这已经设置好后、保存并启动配置。
搭建本地服务框架SSM
- 开发工具:
MyEclipse 2015 state 2.0 + Tomcat 8.0 + MYSQL 5.7 + JDK 1.7
搭建Spring + Spring MVC + MyBatis 项目
- 初始化公众号配置信息 web.xml:
- Servlet class 如下:
package com.cn.hnust.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.cn.hnust.biz.TokenThread;
import com.cn.hnust.biz.TokenThread.AccessTokenCallBack;
import com.cn.hnust.resp.AccessToken;
import com.cn.hnust.util.FileUtil;
import com.cn.hnust.util.L;
@WebServlet(name = "AccessTokenServlet")
public class AccessTokenServlet extends HttpServlet implements AccessTokenCallBack{
private static final long serialVersionUID = -7811255688733771828L;
public AccessTokenServlet() {
}
@Override
public void init() throws ServletException {
//获取servlet初始参数appid和appsecret
TokenThread.appId = getInitParameter("appid");
TokenThread.appSecret = getInitParameter("appsecret");
new Thread(new TokenThread(this)).start(); //启动进程
// new Thread(new MenuThread()).start();
super.init();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
L.i("doGet", "is running");
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
L.i("doPost", "is running");
super.doPost(req, resp);
}
@Override
public void callBack(AccessToken accessToken) {
FileUtil.writerLog(FileUtil.PATH,accessToken.getAccessToken());
}
}
- TokenThread class 如下:
package com.cn.hnust.biz;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cn.hnust.resp.AccessToken;
import com.cn.hnust.util.Config;
import com.cn.hnust.util.L;
public class TokenThread implements Runnable {
public static String appId = "";
public static String appSecret = "";
public static AccessToken accessToken = null;
private AccessTokenCallBack callback;
public TokenThread(AccessTokenCallBack callback) {
this.callback = callback;
}
@Override
public void run() {
while (true) {
accessToken = this.getAccessToken();
if (null != accessToken) {
L.i("token", accessToken.getAccessToken());
L.i("time", accessToken.getExpiresin()+"");
callback.callBack(accessToken);
try {
Thread.sleep(7000 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}// 获取到access_token 休眠7000秒
}else{
try {
Thread.sleep(1000*3);
} catch (InterruptedException e) {
e.printStackTrace();
} //获取的access_token为空 休眠3秒
}
}
}
private AccessToken getAccessToken() {
NetWorkHelper workHelper = new NetWorkHelper();
String Url = String.format(Config.access_token_url,this.appId,this.appSecret);
String result = workHelper.getHttpsResponse(Url, "");
JSONObject json = JSON.parseObject(result);
AccessToken token = new AccessToken();
token.setAccessToken(json.getString("access_token"));
token.setExpiresin(json.getInteger("expires_in"));
return token;
}
public interface AccessTokenCallBack {
public void callBack(AccessToken accessToken);
}
}
- NetWorkHelper class 如下:
package com.cn.hnust.biz;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class NetWorkHelper {
public NetWorkHelper() {
// TODO Auto-generated constructor stub
}
public String getMessage(String ur) {
try {
URL url = new URL(ur);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
InputStream inStream = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "GBK"));
String line = "";
StringBuffer buffer = new StringBuffer();
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
//System.out.println("result=" + buffer.toString());
conn.disconnect();
return buffer.toString();
} catch (Exception e) {
e.printStackTrace();
return "error";
}
}
public void postMessage(String sender, String content, String ur) {
// String path = "http://192.168.1.106:8009/messageApi";
try {
Map<String, String> requestParams = new HashMap<String, String>();
requestParams.put("sender", "12");
//requestParams.put("content", "中国");
StringBuilder params = new StringBuilder();
for (Map.Entry<String, String> entry : requestParams.entrySet()) {
params.append(entry.getKey());
params.append("=");
params.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
params.append("&");
}
if (params.length() > 0)
params.deleteCharAt(params.length() - 1);
byte[] data = params.toString().getBytes();
URL url = new URL(ur);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length",
String.valueOf(data.length));
// POST方式,其实就是浏览器把数据写给服务器
conn.setDoOutput(true); // 设置可输出流
// OutputStream os = conn.getOutputStream(); // 获取输出流
DataOutputStream outStream = new DataOutputStream(
conn.getOutputStream());
outStream.write(data); // 将数据写给服务器
int code = conn.getResponseCode();
if (code == 200) {
InputStream is = conn.getInputStream();
// return StreamTools.streamToString(is);
} else {
// return "网络访问失败";
}
} catch (Exception e) {
e.printStackTrace();
// return 网络访问失败;
}
}
public String getURLResponse(String urlString) {
HttpURLConnection conn = null; //连接对象
InputStream is = null;
String resultData = "";
try {
URL url = new URL(urlString); //URL对象
conn = (HttpURLConnection) url.openConnection(); //使用URL打开一个链接
conn.setDoInput(true); //允许输入流,即允许下载
//在android中必须将此项设置为false
conn.setDoOutput(false); //允许输出流,即允许上传
conn.setUseCaches(false); //不使用缓冲
conn.setRequestMethod("GET"); //使用get请求
is = conn.getInputStream(); //获取输入流,此时才真正建立链接
InputStreamReader isr = new InputStreamReader(is);
BufferedReader bufferReader = new BufferedReader(isr);
String inputLine = "";
while ((inputLine = bufferReader.readLine()) != null) {
resultData += inputLine + "\n";
}
System.out.println(resultData);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("MalformedURLException:" + e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("IOException:" + e.getMessage());
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (conn != null) {
conn.disconnect();
}
}
return resultData;
}
/** * 下载文件 * @param hsUrl * @return */
public String DownLoadHttpsFile(String hsUrl,String fileName,String ur) {
URL url;
InputStream is = null;
String filePath = ur+fileName;
try {
url = new URL(hsUrl);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
TrustManager[] tm = {xtm};
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tm, null);
con.setSSLSocketFactory(ctx.getSocketFactory());
con.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
con.setDoInput(true); //允许输入流,即允许下载
//在android中必须将此项设置为false
con.setDoOutput(false); //允许输出流,即允许上传
con.setUseCaches(false); //不使用缓冲
con.setRequestMethod("GET"); //使用get请求
is = con.getInputStream(); //获取输入流,此时才真正建立链接
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while( (len=is.read(buffer)) != -1 ){
outStream.write(buffer, 0, len);
}
is.close();
byte[] fileBytes = outStream.toByteArray();
File file = new File(filePath);
FileOutputStream fops = new FileOutputStream(file);
fops.write(fileBytes);
fops.flush();
fops.close();
/* Certificate[] certs = con.getServerCertificates(); for (Certificate cert : certs) { X509Certificate xcert = (X509Certificate) cert; }*/
} catch (Exception e) {
e.printStackTrace();
}
return filePath;
}
/** * HTTPS协议的POST请求 * @param hsUrl 请求地址 * @param json 请求数据 * @return */
public String postHttpsResponse(String hsUrl,String json) {
URL url;
InputStream is = null;
String resultData = "";
try {
url = new URL(hsUrl);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
TrustManager[] tm = {xtm};
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tm, null);
con.setSSLSocketFactory(ctx.getSocketFactory());
con.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
con.setDoInput(true); //允许输入流,即允许下载
//在android中必须将此项设置为false
con.setDoOutput(true); //允许输出流,即允许上传
con.setUseCaches(false); //不使用缓冲
con.setRequestMethod("POST"); //使用post请求
//表单数据
if (null != json) {
OutputStream outputStream = con.getOutputStream();
outputStream.write(json.getBytes("UTF-8"));
outputStream.close();
}
is = con.getInputStream(); //获取输入流,此时才真正建立链接
InputStreamReader isr = new InputStreamReader(is);
BufferedReader bufferReader = new BufferedReader(isr);
String inputLine = "";
while ((inputLine = bufferReader.readLine()) != null) {
resultData += inputLine + "\n";
}
System.out.println(resultData);
Certificate[] certs = con.getServerCertificates();
for (Certificate cert : certs) {
X509Certificate xcert = (X509Certificate) cert;
}
} catch (Exception e) {
e.printStackTrace();
}
return resultData;
}
public String getHttpsResponse(String hsUrl, String requestMethod) {
URL url;
InputStream is = null;
String resultData = "";
try {
url = new URL(hsUrl);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
TrustManager[] tm = { xtm };
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tm, null);
con.setSSLSocketFactory(ctx.getSocketFactory());
con.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
con.setDoInput(true); // 允许输入流,即允许下载
// 在android中必须将此项设置为false
con.setDoOutput(false); // 允许输出流,即允许上传
con.setUseCaches(false); // 不使用缓冲
if (null != requestMethod && !requestMethod.equals("")) {
con.setRequestMethod(requestMethod); // 使用指定的方式
} else {
con.setRequestMethod("GET"); // 使用get请求
}
is = con.getInputStream(); // 获取输入流,此时才真正建立链接
InputStreamReader isr = new InputStreamReader(is);
BufferedReader bufferReader = new BufferedReader(isr);
String inputLine = "";
while ((inputLine = bufferReader.readLine()) != null) {
resultData += inputLine + "\n";
}
Certificate[] certs = con.getServerCertificates();
int certNum = 1;
for (Certificate cert : certs) {
X509Certificate xcert = (X509Certificate) cert;
}
} catch (Exception e) {
e.printStackTrace();
}
return resultData;
}
private X509TrustManager xtm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
};
}
- 微信公众号服务器回调接口类如下:
package com.cn.hnust.controller;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.cn.hnust.biz.MessageHandler;
import com.cn.hnust.biz.ProcessReqest;
import com.cn.hnust.pojo.WxMessage;
import com.cn.hnust.service.IWechatService;
import com.cn.hnust.service.IWxService;
import com.cn.hnust.util.L;
import com.cn.hnust.util.SignUtil;
@Controller
@RequestMapping("/wx")
public class WechatController extends BaseController{
private static final String TIMESTAMP = "timestamp";
private static final String ECHOSTR = "echostr";
private static final String NONCE = "nonce";
private static final String SIGNATURE = "signature";
@Resource
private IWechatService wechatService;
@Resource
private IWxService<WxMessage> messageService;
@RequestMapping("/req")
public void registerWxAPI(HttpServletRequest request,HttpServletResponse response) {
String reqMethod = request.getMethod();
if (reqMethod.equals("GET")) {
// 微信加密签名
String signature = request.getParameter(SIGNATURE);
// 时间戳
String timestamp = request.getParameter(TIMESTAMP);
// 随机数
String nonce = request.getParameter(NONCE);
// 随机字符串
String echostr = request.getParameter(ECHOSTR);
logger.info("===============微信公众号对接开始===============!");
boolean valid = wechatService.checkcalidata(signature, timestamp,
nonce);
if (valid) {
PrintWriter out = null;
try {
out = response.getWriter();
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
out.print(echostr);
out.flush();
logger.info("微信公众号对接成功!");
}
} catch (IOException e) {
e.printStackTrace();
logger.info("微信公众号对接出现异常!");
} finally {
out.close();
out = null;
}
}
} else if (reqMethod.equals("POST")) {
response.setContentType("text/html;charset=utf-8"); //设置输出编码格式
String result = "";
Map map;
try {
map = MessageHandler.parseXml(request);
System.out.println("开始构造消息");
result = MessageHandler.buildXml(map,messageService);
if (result.equals(""))
result = "未正确响应";
} catch (Exception e) {
e.printStackTrace();
L.i("发生异常:", e.getMessage());
}
try {
response.getWriter().println(result);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@RequestMapping("chat")
public void chat(HttpServletRequest request, HttpServletResponse response) {
// 微信加密签名
String signature = request.getParameter(SIGNATURE);
// 时间戳
String timestamp = request.getParameter(TIMESTAMP);
// 随机数
String nonce = request.getParameter(NONCE);
logger.info("===============微信公众号应答开始===============!");
boolean valid = wechatService.checkcalidata(signature, timestamp,nonce);
if (valid) {
PrintWriter out = null;
try {
out = response.getWriter();
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
// 调用核心业务类接收消息、处理消息
String respMessage = null;
try {
respMessage = ProcessReqest.process(request, response);
} catch (Exception e) {
e.printStackTrace();
}
out.print(respMessage);
out.flush();
logger.info("微信公众号对接成功!");
}
} catch (IOException e) {
e.printStackTrace();
logger.info("微信公众号对接出现异常!");
} finally {
out.close();
out = null;
}
}
}
}
- SignUtil class 如下:
package com.cn.hnust.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class SignUtil {
// 与接口配置信息中的Token要一致
private static final String token = "xxxxxxxx";
private static final String EncodingAESKey = "xxxxxxxxxxxxxxxxxxxxxxxx";
public static boolean checkSignature(String signature, String timestamp,String nonce) {
// 从请求中(也就是微信服务器传过来的)拿到的token, timestamp, nonce
String[] arr = new String[] { token, timestamp, nonce };
// 将token、timestamp、nonce三个参数进行字典序排序
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对比,标识该请求来源于微信
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
}
// 用于字典排序
public static void sort(String a[]) {
for (int i = 0; i < a.length - 1; i++) {
for (int j = i + 1; j < a.length; j++) {
if (a[j].compareTo(a[i]) < 0) {
String temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
// 将加密后的字节数组变成字符串
private static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
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;
}
}
- 业务处理类 MessageHandler 如下:
package com.cn.hnust.biz;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.cn.hnust.pojo.EventType;
import com.cn.hnust.pojo.GeneralMessage;
import com.cn.hnust.pojo.MessageType;
import com.cn.hnust.pojo.MusicMessage;
import com.cn.hnust.pojo.NewsItem;
import com.cn.hnust.pojo.PictureMessage;
import com.cn.hnust.pojo.WxMessage;
import com.cn.hnust.service.IWxService;
import com.cn.hnust.util.L;
public class MessageHandler {
public static Map parseXml(HttpServletRequest request) throws Exception {
// 将解析结果存储在HashMap中
Map map = new HashMap();
// 从request中取得输入流
InputStream inputStream = request.getInputStream();
/* * 读取request的body内容 此方法会导致流读取问题 Premature end of file. Nested exception: * Premature end of file String requestBody = * inputStream2String(inputStream); System.out.println(requestBody); */
// 读取输入流
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
// 得到xml根元素
Element root = document.getRootElement();
// 得到根元素的所有子节点
List<Element> elementList = root.elements();
// 遍历所有子节点
for (Element e : elementList) {
L.i(e.getName(), e.getText());
map.put(e.getName(), e.getText());
}
// 释放资源
inputStream.close();
inputStream = null;
return map;
}
private static String inputStream2String(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i = -1;
while ((i = is.read()) != -1) {
baos.write(i);
}
return baos.toString();
}
// 根据消息类型 构造返回消息
public static String buildXml(Map map,IWxService<WxMessage> messageService) {
String result = "";
String msgType = map.get("MsgType").toString();
MessageType messageEnumType = MessageType.valueOf(MessageType.class,
msgType.toUpperCase());
switch (messageEnumType) {
case TEXT:
result = handleTextMessage(map,messageService);
break;
case IMAGE:
result = handleImageMessage(map,messageService);
break;
case VOICE:
result = handleVoiceMessage(map,messageService);
break;
case VIDEO:
result = handleVideoMessage(map,messageService);
break;
case SHORTVIDEO:
result = handleSmallVideoMessage(map,messageService);
break;
case LOCATION:
result = handleLocationMessage(map,messageService);
break;
case LINK:
result = handleLinkMessage(map,messageService);
break;
case EVENT:
String eventType = map.get("Event").toString();
System.out.println("eventType:" + eventType);
EventType eventEnumType = EventType.valueOf(EventType.class, eventType.toUpperCase());
switch(eventEnumType){
case CLICK:
result = handleGetMessageEvent(map,messageService);
break;
case VIEW:
result = handleLinkEvent();
break;
case SCANCODE_PUSH:
result = handleScanPushEvent();
break;
case SCANCODE_WAITMSG:
result = handleScanWaitMsgEvent();
break;
case PIC_SYSPHOTO:
result = handlePicSystemEvent();
break;
case PIC_PHOTO_OR_ALBUM:
result = handlePicPhotoAlbumEvent();
break;
case PIC_WEIXIN:
result = handlePicWeiXinEvent();
break;
case LOCATION_SELECT:
result = handleLocationSelectionEvent();
break;
default:
break;
}
break;
default:
break;
}
return result;
}
private static String handleLocationSelectionEvent() {
// TODO Auto-generated method stub
return null;
}
private static String handlePicWeiXinEvent() {
// TODO Auto-generated method stub
return null;
}
private static String handlePicPhotoAlbumEvent() {
// TODO Auto-generated method stub
return null;
}
private static String handlePicSystemEvent() {
// TODO Auto-generated method stub
return null;
}
private static String handleScanWaitMsgEvent() {
// TODO Auto-generated method stub
return null;
}
private static String handleScanPushEvent() {
// TODO Auto-generated method stub
return null;
}
private static String handleLinkEvent() {
// TODO Auto-generated method stub
return null;
}
private static String handleGetMessageEvent(Map map, IWxService<WxMessage> messageService) {
String xml = "";
xml = buildTextMessage(map,messageService, "你点击了天气预报");
return xml;
}
private static String handleTextMessage(Map map, IWxService<WxMessage> messageService) {
String xml = "";
String fromUserName = map.get("FromUserName").toString();
// 开发者微信号
String toUserName = map.get("ToUserName").toString();
// 消息内容
String content = map.get("Content").toString();
GeneralMessage msg = new GeneralMessage();
msg.Sender = toUserName;
msg.Receiver = fromUserName;
msg.CreateTime = getUtcTime();
switch (content) {
case "文本":
xml = buildTextMessage(map,messageService, "这是一条文本消息");
break;
case "图片":
xml = buildPicture(map,messageService);
break;
case "音乐":
xml = buildMusic(map,messageService);
break;
case "图文":
xml = buildNewsMessage(map,messageService);
break;
default:
xml = String
.format("<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>",
msg.Receiver, msg.Sender, msg.CreateTime,
"请回复如下关键词:\n文本\n图片\n语音\n视频\n音乐\n图文");
break;
}
return xml;
}
private static String getUtcTime() {
Date dt = new Date();// 如果不需要格式,可直接用dt,dt就是当前系统时间
DateFormat df = new SimpleDateFormat("yyyyMMddhhmm");// 设置显示格式
String nowTime = "";
nowTime = df.format(dt);
long dd = (long) 0;
try {
dd = df.parse(nowTime).getTime();
} catch (Exception e) {
}
return String.valueOf(dd);
}
/** * 构造文本消息 * * @param map * @param messageService * @param content * @return */
private static String buildTextMessage(Map map, IWxService<WxMessage> messageService, String content) {
String fromUserName = map.get("FromUserName").toString();
// 开发者微信号
String toUserName = map.get("ToUserName").toString();
WxMessage wm = new WxMessage();
wm.setMsgid(new Date().getTime());
wm.setContent(content);
wm.setCreatetime(getUtcTime());
wm.setTousername(toUserName);
wm.setFromusername(fromUserName);
wm.setMsgtype("text");
messageService.save(wm);
return String.format("<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>",
fromUserName, toUserName, getUtcTime(), content);
}
/** * 构造图片消息 * * @param map * @param messageService * @return */
private static String buildPicture(Map map, IWxService<WxMessage> messageService) {
String fromUserName = map.get("FromUserName").toString();
String toUserName = map.get("ToUserName").toString();
String tempMediaId = "58fFYMRjJv0V94qZJ1EeGSKRQB4CbboVBC7FAILlxxZ2AzMnVVUeiOOenxgkzv9g";
WxMessage wm = new WxMessage();
wm.setMsgid(new Date().getTime());
wm.setFromusername(fromUserName);
wm.setTousername(toUserName);
wm.setMediaid(tempMediaId);
wm.setMsgtype("image");
wm.setCreatetime(getUtcTime());
messageService.save(wm);
return String.format("<xml>\n" +
"<ToUserName><![CDATA[%s]]></ToUserName>\n" +
"<FromUserName><![CDATA[%s]]></FromUserName>\n" +
"<CreateTime>%s</CreateTime>\n" +
"<MsgType><![CDATA[image]]></MsgType>\n" +
"<Image>\n" +
"<MediaId><![CDATA[%s]]></MediaId>\n" +
"</Image>\n" +
"</xml>", fromUserName, toUserName, getUtcTime(), tempMediaId);
}
/** * 构造音乐消息 * * @param map * @param messageService * @return */
private static String buildMusic(Map map, IWxService<WxMessage> messageService) {
MusicMessage msg = new MusicMessage();
String fromUserName = map.get("FromUserName").toString();
String toUserName = map.get("ToUserName").toString();
msg.Sender = toUserName;
msg.Receiver = fromUserName;
msg.CreateTime = getUtcTime();
msg.Title = "蓝莲花";
msg.Description = "蓝莲花-许巍";
msg.MusicURL = "http://7te94m.com1.z0.glb.clouddn.com/lanlianhua.mp3";
msg.HQMusicUrl = "http://7te94m.com1.z0.glb.clouddn.com/lanlianhua.mp3";
msg.ThumbMediaId = "kpNqTAk7tZ6NHhlHlEBhgUhfxjPBADbK79EfwF1RlOKAFcuKYC0eenD-ja-nTHg9";
WxMessage wm = new WxMessage();
wm.setMsgid(new Date().getTime());
wm.setFromusername(fromUserName);
wm.setTousername(toUserName);
wm.setCreatetime(getUtcTime());
wm.setDescription(msg.Description);
wm.setTitle(msg.Title);
wm.setThumbmediaid(msg.ThumbMediaId);
wm.setUrl(msg.HQMusicUrl);
wm.setMsgtype("music");
messageService.save(wm);
return String
.format("<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[music]]></MsgType><Music><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><MusicUrl><![CDATA[%s]]></MusicUrl><HQMusicUrl><![CDATA[%s]]></HQMusicUrl><ThumbMediaId><![CDATA[%s]]></ThumbMediaId></Music></xml>",
msg.Receiver, msg.Sender, getUtcTime(), msg.Title,
msg.Description, msg.MusicURL, msg.HQMusicUrl,
msg.ThumbMediaId);
}
/** * 构造图文消息 * * @param map * @param messageService * @return */
private static String buildNewsMessage(Map map, IWxService<WxMessage> messageService) {
String fromUserName = map.get("FromUserName").toString();
String toUserName = map.get("ToUserName").toString();
NewsItem item = new NewsItem();
item.Title = "iOS 9.1现2大故障 iPhone基本功能遭殃";
item.Description = "凤凰科技讯 11月9日消息,据中关村在线报道,iOS 9.1 是个颇为稳定的版本,至少初初推出时的印象是这样,现在推出接近两星期,一些颇为严重的问题开始浮现。其中两大问题,正在困扰为数不少的用户。";
item.PicUrl = "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png";
item.Url = "http://tech.ifeng.com/a/20151109/41503466_0.shtml";
String itemContent1 = buildSingleItem(item);
NewsItem item2 = new NewsItem();
item2.Title = "刚毕业就月薪过万的程序员 创业大街上的得意与迷茫";
item2.Description = "DoNews11月9日消息(编辑 陈艳曲)第一次见到刚毕业的程序员小李时,正逢他在创业大街上谋到了一份工作,五位数的薪资让他更加坚信,毕业前在技术学校报一个ios开发培训班是一个多么正确的决定";
item2.PicUrl = "http://photocdn.sohu.com/20151108/mp40396008_1446997429715_4_th_fv23.jpeg";
item2.Url = "http://tech.hexun.com/2015-11-09/180434346.html";
String itemContent2 = buildSingleItem(item2);
WxMessage wm = new WxMessage();
wm.setMsgid(new Date().getTime());
wm.setFromusername(fromUserName);
wm.setTousername(toUserName);
wm.setTitle(item.Title);
wm.setCreatetime(getUtcTime());
wm.setDescription(item.Description);
wm.setPicurl(item.PicUrl);
wm.setUrl(item.Url);
wm.setMsgtype("news");
messageService.save(wm);
String content = String.format("<xml>\n" +
"<ToUserName><![CDATA[%s]]></ToUserName>\n" +
"<FromUserName><![CDATA[%s]]></FromUserName>\n" +
"<CreateTime>%s</CreateTime>\n" +
"<MsgType><![CDATA[news]]></MsgType>\n" +
"<ArticleCount>%s</ArticleCount>\n" +
"<Articles>\n" + "%s" +
"</Articles>\n" +
"</xml> ", fromUserName, toUserName, getUtcTime(), 2, itemContent1 + itemContent2);
return content;
}
/** * 生成图文消息的一条记录 * * @param item * @return */
private static String buildSingleItem(NewsItem item) {
String itemContent = String.format("<item>\n" +
"<Title><![CDATA[%s]]></Title> \n" +
"<Description><![CDATA[%s]]></Description>\n" +
"<PicUrl><![CDATA[%s]]></PicUrl>\n" +
"<Url><![CDATA[%s]]></Url>\n" +
"</item>", item.Title, item.Description, item.PicUrl, item.Url);
return itemContent;
}
/** * 接收到图片消息后处理 * * @param map * @param messageService * @return */
private static String handleImageMessage(Map map, IWxService<WxMessage> messageService) {
String picUrl = map.get("PicUrl").toString();
String mediaId = map.get("MediaId").toString();
System.out.print("picUrl:"+picUrl);
System.out.print("mediaId:" + mediaId);
String result = String.format("已收到您发来的图片,图片Url为:%s\n图片素材Id为:%s",picUrl,mediaId);
return buildTextMessage(map,messageService,result);
}
private static String handleVoiceMessage(Map map, IWxService<WxMessage> messageService){
String format = map.get("Format").toString();
String mediaId = map.get("MediaId").toString();
System.out.print("format:"+format);
System.out.print("mediaId:" + mediaId);
String result = String.format("已收到您发来的语音,语音格式为:%s\n语音素材Id为:%s",format,mediaId);
return buildTextMessage(map,messageService,result);
}
private static String handleVideoMessage(Map map, IWxService<WxMessage> messageService){
String thumbMediaId = map.get("ThumbMediaId").toString();
String mediaId = map.get("MediaId").toString();
System.out.print("thumbMediaId:"+thumbMediaId);
System.out.print("mediaId:" + mediaId);
String result = String.format("已收到您发来的视频,视频中的素材ID为:%s\n视频Id为:%s",thumbMediaId,mediaId);
return buildTextMessage(map,messageService,result);
}
private static String handleSmallVideoMessage(Map map, IWxService<WxMessage> messageService){
String thumbMediaId = map.get("ThumbMediaId").toString();
String mediaId = map.get("MediaId").toString();
System.out.print("thumbMediaId:"+thumbMediaId);
System.out.print("mediaId:" + mediaId);
String result = String.format("已收到您发来的小视频,小视频中素材ID为:%s,\n小视频Id为:%s",thumbMediaId,mediaId);
return buildTextMessage(map,messageService,result);
}
private static String handleLocationMessage(Map map, IWxService<WxMessage> messageService){
String latitude = map.get("Location_X").toString(); //纬度
String longitude = map.get("Location_Y").toString(); //经度
String label = map.get("Label").toString(); //地理位置精度
String result = String.format("纬度:%s\n经度:%s\n地理位置:%s",latitude,longitude,label);
return buildTextMessage(map,messageService,result);
}
private static String handleLinkMessage(Map map, IWxService<WxMessage> messageService){
String title = map.get("Title").toString();
String description = map.get("Description").toString();
String url = map.get("Url").toString();
String result = String.format("已收到您发来的链接,链接标题为:%s,\n描述为:%s\n,链接地址为:%s",title,description,url);
return buildTextMessage(map,messageService,result);
}
}
至此,基本代码完成。
部署阿里云服务器
主要是把tomcat web app 目录下storm 部署阿里云服务器上,重启tomcat 即可!
测试
关注公众号,随便输入如图:
进入微信后台:
进入我自己写的页面:
至此 ,公众号讲解到此为止。