您的位置:首页 > 移动开发 > 微信开发

微信公众号开发--关注后自动回复(Java记录篇)

2017-09-20 21:07 453 查看
转载自 http://blog.csdn.net/lyq8479/article/details/8944988

文中所用到的jar dom4j XStream的jar包

扫描下方二维码可关注 你我杂志刊 关注或者 微信搜索公众号 你我杂志刊



开发者通过signature对请求进行校验,若确认此次校验来自微信服务器,请原样返回echostr参数内容,则接入成功,否则接入失败!

打开IDE,创建一个Java Web工程,并新建一个能够处理请求的Servlet,命名任意。

package com.zhenqi.servlet;

import com.zhenqi.util.CheckUtil;
import com.zhenqi.util.MessageUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
* Created by wuming on 2017/9/15.
*/
public class HandleWeiXinMessageServlet extends HttpServlet {

public static final Logger logger = LoggerFactory.getLogger(HandleWeiXinMessageServlet.class);
/**
* VersionUID
*/
private static final long serialVersionUID = 1L;

/*
* URL验证
* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

String signature = req.getParameter("signature");
String timestamp = req.getParameter("timestamp");
String nonce = req.getParameter("nonce");
String echostr = req.getParameter("echostr");
logger.info("echostr" + echostr);
PrintWriter out = resp.getWriter();
if(CheckUtil.checkSignature(signature, timestamp, nonce)){
out.write(echostr);
}
}


以上servlet doGet方法请求用到了校验signature的方法,以下是CheckUtil.java完整代码。

其中要注意Token要与微信相对应。



package com.zhenqi.util;

import java.security.MessageDigest;
import java.util.Arrays;

public class CheckUtil {
//与接口配置信息中的Token要一致
private static final String token="weixinStudy";

public static boolean checkSignature(String signature,String timestrap,
String nonce){

String[] arr=new String[]{token,timestrap,nonce};
// 将token、timestamp、nonce三个参数进行字典序排序
Arrays.sort(arr);

StringBuffer buf=new StringBuffer();
for(int i=0;i<arr.length;i++){
buf.append(arr[i]);
}

String temp=getSha1(buf.toString());
return temp.equals(signature);
}

public static String getSha1(String str){
if(null==str || str.length()==0){
return null;
}
char hexDigits[]={'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f'};
try{
MessageDigest mdTemp=MessageDigest.getInstance("SHA1");
mdTemp.update(str.getBytes("UTF-8"));

byte[] md=mdTemp.digest();
int j=md.length;
char[] buf=new char[j*2];
int k=0;
for(int i=0;i<j;i++){
byte byTemp=md[i];
buf[k++]=hexDigits[byTemp >>> 4 & 0xf];
buf[k++]=hexDigits[byTemp & 0xf];
}
return new String(buf);
}catch(Exception e){
return null;
}
}

}


而后再回到servlet请求类里,编写doPost方法。用户关注就是触发一个事件。

protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
PrintWriter out = resp.getWriter();
try {
Map<String,String> map = MessageUtil.xmlToMap(req);
String toUserName = map.get("ToUserName");
String fromUserName = map.get("FromUserName");
String msgType = map.get("MsgType");
String content = map.get("Content");
//判断请求是否事件类型 event
if(MessageUtil.MESSAGE_EVENT.equals(msgType)){
String eventType = map.get("Event");
//若是关注事件  subscribe
if(MessageUtil.EVENT_SUB.equals(eventType)){
String mycontent = MessageUtil.menuText();
message = MessageUtil.initText(toUserName, fromUserName, mycontent);

}
}
out.print(message);
} catch (Exception e) {
e.printStackTrace();
out.close();
}

}


MessageUtl.java类如下:

public class MessageUtil {
public static final String MESSAGE_TEXT = "text";
public static final String MESSAGE_IMAGE = "image";
public static final String MESSAGE_VOICE = "voice";
public static final String MESSAGE_VIDEO = "video";
public static final String MESSAGE_LINK = "link";
public static final String MESSAGE_LOCATION = "location";
public static final String MESSAGE_EVENT = "event";

public static final String EVENT_SUB = "subscribe";
public static final String EVENT_UNSUB = "unsubscribe";
public static final String EVENT_CLICK = "CLICK";
public static final String EVENT_VIEW = "VIEW";

/**
* xml转为map
* @param request
* @return
* @throws DocumentException
* @throws IOException
*/
public static Map<String, String> xmlToMap(HttpServletRequest request ) throws DocumentException, IOException
{
Map<String,String> map = new HashMap<String, String>();

SAXReader reader = new SAXReader();

InputStream ins = request.getInputStream();
Document doc = reader.read(ins);

Element root = doc.getRootElement();
List<Element> list = root.elements();
for (Element e : list) {
map.put(e.getName(), e.getText());
}
ins.close();
return map;
}

public static String textMessageToXml(TextMessage textMessage){
XStream xstream = new XStream();
xstream.alias("xml", textMessage.getClass());
return xstream.toXML(textMessage);

}
public static String initText(String toUserName, String fromUserName, String content){
TextMessage text = new TextMessage();
text.setFromUserName(toUserName);
text.setToUserName(fromUserName);
text.setMsgType(MESSAGE_TEXT);
text.setCreateTime(new Date().getTime());
text.setContent(content);
return textMessageToXml(text);
}

public static String menuText(){
StringBuffer sb = new StringBuffer();
sb.append("      你关注,\n");
sb.append("     或者不关注,\n");
sb.append("      【你我杂志刊】都在这里!\n");
sb.append("     不离,\n");
sb.append("      不弃!\n\n");
sb.append("该公众号已实现以下功能:\n");
sb.append("回复“天气”、“翻译” 将有该功能的介绍与使用,\n");
sb.append("如您在使用该公众有任何宝贵意见,欢迎反馈!\n\n");
sb.append("反馈邮箱:zhenqicai@sohu.com");
return sb.toString();
}
}


最终效果如下图



扫描下方二维码可关注 你我杂志刊 关注或者 微信搜索公众号 你我杂志刊

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息