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

java web 微信认证订阅 获取openid

2016-05-19 12:03 435 查看
接手一个微信h5项目,对方提供一个已认证的微信订阅号,需要参与活动的用户必须为已关注该订阅号的会员。

已知:查询微信官方文档,订阅号是没有直接获取用户openid的接口,

解决方案:通过自定义菜单来获取用户openid,在点击自定义菜单时用户返回一个FromUserName,这个就是openid

1.接入微信公众号 ,在公众号启用开发者,修改配置,获取微信tocken

java :

@RequestMapping(value = "/autoToken", method = RequestMethod.GET)
public void autoToken(HttpServletResponse response) {
if (!WxApiUtil.accessing(request, response)) {
return;
}
String echostr = request.getParameter("echostr");
if (StringUtils.isNotEmpty(echostr)) {
try {
response.setContentType("text/html; charset=utf-8");
response.getWriter().print(echostr);
response.getWriter().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}

public static boolean accessing(HttpServletRequest request,
HttpServletResponse response) {
String Token = "weixin";
String signature = request.getParameter("signature");
String timestamp = request.getParameter("timestamp");
String nonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
if (StringUtils.isEmpty(signature) || StringUtils.isEmpty(timestamp)
|| StringUtils.isEmpty(nonce) || StringUtils.isEmpty(echostr)) {
return false;
}
String[] ArrTmp = { Token, timestamp, nonce };
Arrays.sort(ArrTmp);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < ArrTmp.length; i++) {
sb.append(ArrTmp[i]);
}
String pwd = Encrypt(sb.toString());

LOG.info("signature:" + signature + "timestamp:" + timestamp + "nonce:"
+ nonce + "pwd:" + pwd + "echostr:" + echostr);
if (StringUtils.trim(pwd).equals(StringUtils.trim(signature))) {
return true;
} else {
return false;
}
}

private static String Encrypt(String strSrc) {
MessageDigest md = null;
String strDes = null;

byte[] bt = strSrc.getBytes();
try {
md = MessageDigest.getInstance("SHA-1");
md.update(bt);
strDes = bytes2Hex(md.digest()); // to HexString
} catch (NoSuchAlgorithmException e) {
System.out.println("Invalid algorithm.");
return null;
}
return strDes;
}
public static String bytes2Hex(byte[] bts) {
String des = "";
String tmp = null;
for (int i = 0; i < bts.length; i++) {
tmp = (Integer.toHexString(bts[i] & 0xFF));
if (tmp.length() == 1) {
des += "0";
}
des += tmp;
}
return des;
}


2.接入成功后,写一个post接口,接收微信服务器推送的消息,与公众号上填写的连接一致,不过接入时使用get接口,接收信息时使用post接口,

@RequestMapping(value = "/autoToken", method = RequestMethod.POST)
public void autoToken2(HttpServletResponse response) {
try {
BufferedReader br = new BufferedReader(
new InputStreamReader((ServletInputStream) request.getInputStream()));
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line);
}
String xml = sb.toString();
manageMessage(xml, request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
private void manageMessage(String xml, HttpServletRequest request, HttpServletResponse response) throws Exception {
String responseStr = "";
try {
LOG.info(xml);
Map<String, String> map = WxApiUtil.getMapFromXML(xml);
String event = map.get("Event");
String msgtype = map.get("MsgType");
String eventkey = map.get("EventKey");
String openid = map.get("FromUserName");
if ("CLICK".equals(event) && "event".equals(msgtype)) { // 菜单click事件
switch (eventkey) {
case "111":
map.put("Content", "<a href=\"http://www.xxxx.com/actvity1/index.html?openid=" + openid
+ "\">活动连接</a>");
responseStr = WxApiUtil.creatRevertText(map);// 创建XML
break;
default:
map.put("Content",
"Hello,欢迎关注我们");
responseStr = WxApiUtil.creatRevertText(map);// 创建XML
break;
}
}
if (StringUtils.isEmpty(responseStr)) {
map.put("Content",
"Hello,欢迎关注我们");
responseStr = WxApiUtil.creatRevertText(map);// 创建XML
}
LOG.info(responseStr);
response.setContentType("text/html; charset=utf-8");
response.getWriter().write(responseStr);
response.getWriter().flush();
} catch (Exception e) {
e.printStackTrace();
}
}

public static String creatRevertText(Map<String, String> map) {
StringBuffer revert = new StringBuffer();
revert.append("<xml>");
revert.append("<ToUserName><![CDATA[" + map.get("FromUserName")
+ "]]></ToUserName>");
revert.append("<FromUserName><![CDATA[" + map.get("ToUserName")
+ "]]></FromUserName>");
revert.append("<CreateTime>" + map.get("CreateTime") + "</CreateTime>");
revert.append("<MsgType><![CDATA[text]]></MsgType>");
revert.append("<Content><![CDATA[" + map.get("Content")
+ "]]></Content>");
revert.append("</xml>");
return revert.toString();
}


3.创建自定义菜单,

String body = "{\"button\":[{\"type\":\"click\",\"name\":\"test\",\"key\":\"111\"}]}";
String jsonStr = WxApiUtil.createMenu(request, wxEntity, body);
public static String createMenu(HttpServletRequest request, WxEntity wx,
String body) {
String json = "";
try {
String key1 = "accessToken" + wx.getId();
ServletContext context = request.getSession().getServletContext();
String accessToken = (String) context.getAttribute(key1);
if (StringUtils.isEmpty(accessToken)) {
accessToken = getAccessToken(wx);
context.setAttribute(key1, accessToken);
System.out.println(DateUtils.format(new Date(),
DateUtils.DATETIME_FORMAT)
+ "-------"
+ key1
+ " 超时,重新获取--------" + accessToken);
}
String url = menucreateUrl.replace("ACCESS_TOKEN1", accessToken);
json = EHttpUtil.getPostContent(url, body);
} catch (Exception e) {
e.printStackTrace();
}
return json;
}


结束。

注意点:接入微信和创建菜单都是一步就过,没什么需要注意的,在接收微信消息并返回时注意调换 FromUserName 和 ToUserName,点击自定义菜单可以返回的消息类型不局限于文本,还可以是其他类型,通常回复图文消息,方法如下:

public static String creatRevertNews(Map<String, String> map) {
StringBuffer revert = new StringBuffer();
revert.append("<xml>");
revert.append("<ToUserName><![CDATA[" + map.get("FromUserName")
+ "]]></ToUserName>");
revert.append("<FromUserName><![CDATA[" + map.get("ToUserName")
+ "]]></FromUserName>");
revert.append("<CreateTime>" + map.get("CreateTime") + "</CreateTime>");
revert.append("<MsgType><![CDATA[news]]></MsgType><ArticleCount>1</ArticleCount>");
revert.append("<Articles>");
revert.append("<item>");
revert.append("<Title><![CDATA[" + map.get("Title")
+ "]]></Title>");
revert.append("<Description><![CDATA[" + map.get("Description")
+ "]]></Description>");
revert.append("<PicUrl><![CDATA[" + map.get("PicUrl")
+ "]]></PicUrl>");
revert.append("<Url><![CDATA[" + map.get("Url")
+ "]]></Url>");
revert.append("</item>");
revert.append("</Articles>");
revert.append("</xml>");
return revert.toString();
}


记录开发过程中的点滴!

代码code片断为什么不能用了,而且格式都没了!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: