您的位置:首页 > 编程语言 > Java开发

[置顶] 基于springboot+mybatis的微信公众号开发第四篇-自定义菜单的查询、创建、删除及菜单事件响应

2016-12-15 19:13 906 查看
菜单这部分相对来说是简单的,所以做起来很快。

一、看公众号的文档可知有些接口调用可能要https请求,所以这里我们在util包中创建一个书信任管理器类

package com.util;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

/**
* 证书信任管理器(用于https请求)
*
*/
public class MyX509TrustManager implements X509TrustManager {

public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}

public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}

public X509Certificate[] getAcceptedIssuers() {
return null;
}
}


**二、我们在同个包下的WeixinUtil类,加入用于通用的https请求方法

这里罗列整个类的代码(加上了获取AccessToken的固定方法)**

package com.util;

import com.model.AccessToken;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Created by Administrator on 2016/11/7.
*/
public class WeixinUtil {
private static Logger log = LoggerFactory.getLogger(WeixinUtil.class);

/**
* 发起https请求并获取结果
*
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
try {
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();

URL url = new URL(requestUrl);
HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
httpUrlConn.setSSLSocketFactory(ssf);

httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
// 设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);

if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();

// 当有数据需要提交时
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}

// 将返回的输入流转换成字符串
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
log.error("Weixin server connection timed out.");
} catch (Exception e) {
log.error("https request error:{}", e);
}
return jsonObject;
}

// 获取access_token的接口地址(GET) 限200(次/天)
public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";

/**
* 获取access_token
*
* @param appid 凭证
* @param appsecret 密钥
* @return
*/
public static AccessToken getAccessToken(String appid, String appsecret) {
AccessToken accessToken = null;

String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
// 如果请求成功
if (null != jsonObject) {
try {
accessToken = new AccessToken();
accessToken.setToken(jsonObject.getString("access_token"));
accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
} catch (JSONException e) {
accessToken = null;
// 获取token失败
log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
}
}
return accessToken;
}

}


三、接下来要写实体类了

1、写个AccessToken的实体类吧,以后要用到。

package com.model;

/**
* 微信通用接口凭证
*
*/
public class AccessToken {
// 获取到的凭证
private String token;
// 凭证有效时间,单位:秒
private int expiresIn;

public String getToken() {
return token;
}

public void setToken(String token) {
this.token = token;
}

public int getExpiresIn() {
return expiresIn;
}

public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}
}


2、然后是菜单的实体类。在model包下创建一个menu包,包下创建Menu类(主要是为了好看)

package com.model.menu;

import java.sql.Timestamp;

public class Menu {

private String id;

private String accountId;

private String parentId;

private String parentName;

private String name;

private String type;

private String key;

private String url;

private Integer sort;

private String createdBy;

private Timestamp createdTime;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getAccountId() {
return accountId;
}

public void setAccountId(String accountId) {
this.accountId = accountId;
}

public String getParentId() {
return parentId;
}

public void setParentId(String parentId) {
this.parentId = parentId;
}

public String getParentName() {
return parentName;
}

public void setParentName(String parentName) {
this.parentName = parentName;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public Integer getSort() {
return sort;
}

public void setSort(Integer sort) {
this.sort = sort;
}

public String getCreatedBy() {
return createdBy;
}

public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}

public Timestamp getCreatedTime() {
return createdTime;
}

public void setCreatedTime(Timestamp createdTime) {
this.createdTime = createdTime;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}
}


四、写菜单的逻辑层

1、在service包创建menu包,并在下面创建MenuService

package com.service.menu;

import net.sf.json.JSONObject;
import java.util.Map;

public interface MenuService {
public JSONObject getMenu(String accessToken);
public int createMenu(Map<String, Object> menu, String accessToken);
public int deleteMenu(String accessToken);

}


然后再创建实现类MenuServiceImpl

package com.service.menu;

import com.model.menu.Menu;
import com.util.WeixinUtil;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* 对订阅号的菜单的操作
*/
@SuppressWarnings("SpringJavaAutowiringInspection")
@Service("menuService")
public class MenuSeviceImpl implements MenuService {

private static Logger log = LoggerFactory.getLogger(MenuSeviceImpl.class);

// 菜单创建(POST) 限1000(次/天)
public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";

// 菜单查询(POST) 限10000(次/天)
public static String menu_get_url = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN";

// 菜单删除(POST) 限1000(次/天)
public static String menu_delete_url = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";

/**
* 查询菜单
*
* @param accessToken 有效的access_token
* @return
*/
public JSONObject getMenu(String accessToken) {

// 拼装创建菜单的url
String url = menu_get_url.replace("ACCESS_TOKEN", accessToken);
// 调用接口查询菜单
JSONObject jsonObject = WeixinUtil.httpRequest(url, "GET", null);

return jsonObject;
}
/**
* 创建菜单(替换旧菜单)
*
* @param accessToken 有效的access_token
* @return 0表示成功,其他值表示失败
*/
public int createMenu(Map<String, Object> menu,String accessToken) {
int result = 0;

// 拼装创建菜单的url
String url = menu_create_url.replace("ACCESS_TOKEN", accessToken);
// 将菜单对象转换成json字符串
String jsonMenu = JSONObject.fromObject(menu).toString();
// 调用接口创建菜单
JSONObject jsonObject = WeixinUtil.httpRequest(url, "POST", jsonMenu);

if (null != jsonObject) {
if (0 != jsonObject.getInt("errcode")) {
result = jsonObject.getInt("errcode");
log.error("创建菜单失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
log.error("****"+jsonMenu+"****");
}
}
return result;
}

/**
* 删除菜单
*
* @param accessToken 有效的access_token
* @return 0表示成功,其他值表示失败
*/
public int deleteMenu(String accessToken) {
int result = 0;

// 拼装创建菜单的url
String url = menu_delete_url.replace("ACCESS_TOKEN", accessToken);

// 调用接口创建菜单
JSONObject jsonObject = WeixinUtil.httpRequest(url, "POST", null);

if (null != jsonObject) {
if (0 != jsonObject.getInt("errcode")) {
result = jsonObject.getInt("errcode");
log.error("删除菜单失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
}
}
return result;
}
}


五、在com包下创建一个thread包,再创建AccessTokenThread类,用来定时获取access_token

1、首先在启动类中加入注解@EnableScheduling

package com;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling // 这里,启用定时任务
public class WeixinMpApplication {

public static void main(String[] args) {
SpringApplication.run(WeixinMpApplication.class, args);
}
}


2、在AccessTokenThread类中加入

package com.thread;

import com.model.accesstoken.AccessToken;
import com.util.WeixinUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
* 定时获取微信access_token的线程
*在WechatMpDemoApplication中注解@EnableScheduling,在程序启动时就开启定时任务。
* 每7200秒执行一次
*/
@Component
public class AccessTokenThread {
private static Logger log = LoggerFactory.getLogger(AccessTokenThread.class);

// 第三方用户唯一凭证
public static String appid = "wx1dd7aa8ed2be67e7";

// 第三方用户唯一凭证密钥
public static String appsecret = "ae9d55c58f0d87208f63eb229eb74926";
// 第三方用户唯一凭证
public static AccessToken accessToken = null;

@Scheduled(fixedDelay = 2*3600*1000)
//7200秒执行一次
public void gettoken(){
accessToken= WeixinUtil.getAccessToken(appid,appsecret);
if(null!=accessToken){
log.info("获取成功,accessToken:"+accessToken.getToken());
}else {
log.error("获取token失败");
}
}
}


六、在controller包下创建MenuController类,这里是直接组装固定菜单。

package com.controller;

import com.model.menu.Menu;
import com.service.menu.MenuService;
import com.thread.AccessTokenThread;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
*
* 对订阅号的菜单的操作
*
*/
@RestController
@RequestMapping("/menu")

public class MenuController {
@Autowired
private MenuService menuService;

private static Logger log = LoggerFactory.getLogger(MenuController.class);

//查询全部菜单
@RequestMapping(value = "/get",method = RequestMethod.GET)
public String getMenu() {
// 调用接口获取access_token
String at = AccessTokenThread.accessToken.getToken();
JSONObject jsonObject =null;
if (at != null) {
// 调用接口查询菜单
jsonObject = menuService.getMenu(at);
// 判断菜单创建结果
return String.valueOf(jsonObject);
}
log.info("token为"+at);
return "无数据";
}

//创建菜单
@RequestMapping(value = "/create",method = RequestMethod.POST)
public int createMenu() {
// 调用接口获取access_token
String at = AccessTokenThread.accessToken.getToken();
int result=0;
if (at != null) {

// 调用接口创建菜单
result = menuService.createMenu(getFirstMenu(),at);
// 判断菜单创建结果
if (0 == result) {
log.info("菜单创建成功!");
} else {
log.info("菜单创建失败,错误码:" + result);
}
}
return result ;
}

//删除菜单
@RequestMapping(value = "/delete",method = RequestMethod.POST)
public int deleteMenu() {
// 调用接口获取access_token
String at = AccessTokenThread.accessToken.getToken();
int result=0;
if (at != null) {
// 删除菜单
result = menuService.deleteMenu(at);
// 判断菜单删除结果
if (0 == result) {
log.info("菜单删除成功!");
} else {
log.info("菜单删除失败,错误码:" + result);
}
}
return  result;
}

/**
* 组装菜单数据
*/
public static Map<String, Object> getFirstMenu(){
//第一栏菜单
Menu menu1=new Menu();
menu1.setId("1");
menu1.setName("第一栏");
menu1.setType("click");
menu1.setKey("1");

Menu menu11=new Menu();
menu11.setId("11");
menu11.setName("第一栏的第一个v3");
menu11.setType("click");
menu11.setKey("11");

Menu menu12=new Menu();
menu12.setId("12");
menu12.setName("第一栏的第二个");
menu12.setType("click");
menu12.setKey("12");

//第二栏
Menu menu2=new Menu();
menu2.setId("2");
menu2.setName("第二栏");
menu2.setType("click");
menu2.setKey("2");

Menu menu21=new Menu();
menu21.setId("21");
menu21.setName("第二栏的第一个");
menu21.setType("click");
menu21.setKey("21");

Menu menu3=new Menu();
menu3.setId("3");
menu3.setName("第三栏");
menu3.setType("view");
menu3.setUrl("http://www.baidu.com");

//最外一层大括号
Map<String, Object> wechatMenuMap = new HashMap<String, Object>();

//包装button的List
List<Map<String, Object>> wechatMenuMapList = new ArrayList<Map<String, Object>>();

//包装第一栏
Map<String, Object> menuMap1 = new HashMap<String, Object>();
Map<String, Object> menuMap11 = new HashMap<String, Object>();
Map<String, Object> menuMap12 = new HashMap<String, Object>();
List<Map<String, Object>> subMenuMapList1 = new ArrayList<Map<String, Object>>();

//第一栏第一个
menuMap11.put("name",menu11.getName());
menuMap11.put("type",menu11.getType());
menuMap11.put("key",menu11.getKey());
subMenuMapList1.add(menuMap11);

//第二栏第二个
menuMap12.put("name",menu12.getName());
menuMap12.put("type",menu12.getType());
menuMap12.put("key",menu12.getKey());
subMenuMapList1.add(menuMap12);

menuMap1.put("name",menu1.getName());
menuMap1.put("sub_button",subMenuMapList1);

//包装第二栏
Map<String, Object> menuMap2 = new HashMap<String, Object>();
Map<String, Object> menuMap21 = new HashMap<String, Object>();
List<Map<String, Object>> subMenuMapList2 = new ArrayList<Map<String, Object>>();

//第二栏第一个
menuMap21.put("name",menu21.getName());
menuMap21.put("type",menu21.getType());
menuMap21.put("key",menu21.getKey());
subMenuMapList2.add(menuMap21);

menuMap2.put("name",menu2.getName());
menuMap2.put("sub_button",subMenuMapList2);

//包装第三栏
Map<String, Object> menuMap3 = new HashMap<String, Object>();
List<Map<String, Object>> subMenuMapList3 = new ArrayList<Map<String, Object>>();

menuMap3.put("name",menu3.getName());
menuMap3.put("type",menu3.getType());
menuMap3.put("url",menu3.getUrl());
menuMap3.put("sub_button",subMenuMapList3);

wechatMenuMapList.add(menuMap1);
wechatMenuMapList.add(menuMap2);
wechatMenuMapList.add(menuMap3);
wechatMenuMap.put("button",wechatMenuMapList);
return  wechatMenuMap;
}
}


六、点击菜单响应事件

因为点击菜单属于事件推送,所以要在CoreServiceImpl类中相应位置新加入对事件推送的处理方法:

1、在接收文本消息前新增菜单id属性

//点击菜单id
String EventKey =requestMap.get("EventKey");
// 接收文本消息内容
String content = requestMap.get("Content");


2、在音频消息后面加入事件推送的处理

// 事件推送
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
// 事件类型
String eventType =requestMap.get("Event");
// 自定义菜单点击事件
if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {
switch (EventKey){
case "11":{
respContent = "这是第一栏第一个";
break;
}
case "12":{
respContent = "这是第一栏第一个";
break;
}
case "21":{
respContent = "这是第二栏第一个";
break;
}

default:{
log.error("开发者反馈:EventKey值没找到,它是:"+EventKey);
respContent= "很抱歉,此按键功能正在升级无法使用";
}
}
textMessage.setContent(respContent);
// 将文本消息对象转换成xml字符串
respMessage = MessageUtil.textMessageToXml(textMessage);
}
else if(eventType.equals(MessageUtil.EVENT_TYPE_VIEW)){
// 对于点击菜单转网页暂时不做推送
}

}


3、后面我加入了对订阅消息的推送处理。

// 订阅
else if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
//测试单图文回复
Article article = new Article();
article.setTitle("谢谢您的关注!");
// 图文消息中可以使用QQ表情、符号表情
article.setDescription("点击图文可以跳转到百度首页");
// 将图片置为空
article.setPicUrl("http://www.sinaimg.cn/dy/slidenews/31_img/2016_38/28380_733695_698372.jpg");
article.setUrl("http://www.baidu.com");
articleList.add(article);
newsMessage.setArticleCount(articleList.size());
newsMessage.setArticles(articleList);
respMessage = MessageUtil.newsMessageToXml(newsMessage);
}
else if(eventType.equals(MessageUtil.EVENT_TYPE_SCAN)){
//测试单图文回复
Article article = new Article();
article.setTitle("这是已关注用户扫描二维码弹到的界面");
// 图文消息中可以使用QQ表情、符号表情
article.setDescription("点击图文可以跳转到百度首页");
// 将图片置为空
article.setPicUrl("http://www.sinaimg.cn/dy/slidenews/31_img/2016_38/28380_733695_698372.jpg");
article.setUrl("http://www.baidu.com");
articleList.add(article);
newsMessage.setArticleCount(articleList.size());
newsMessage.setArticles(articleList);
respMessage = MessageUtil.newsMessageToXml(newsMessage);
}
// 取消订阅
else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {
// TODO 取消订阅后用户再收不到公众号发送的消息,因此不需要回复消息
}


4、这里给出完整的CoreServiceImpl类

package com.service.core;

import com.model.message.response.Article;
import com.model.message.response.NewsMessage;
import com.model.message.response.TextMessage;
import com.util.MessageUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* 核心服务类
*/
@Service("coreService")
public class CoreServiceImpl implements CoreService {

private static Logger log = LoggerFactory.getLogger(CoreServiceImpl.class);

/**
* 处理微信发来的请求(包括事件的推送)
*
* @param request
* @return
*/
public String processRequest(HttpServletRequest request) {

String respMessage = null;
try {
// 默认返回的文本消息内容
String respContent = "请求处理异常,请稍候尝试!";
// 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");
// 回复文本消息
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);

// 创建图文消息
NewsMessage newsMessage = new NewsMessage();
newsMessage.setToUserName(fromUserName);
newsMessage.setFromUserName(toUserName);
newsMessage.setCreateTime(new Date().getTime());
newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
newsMessage.setFuncFlag(0);

List<Article> articleList = new ArrayList<Article>();

//点击菜单id
String EventKey =requestMap.get("EventKey");
// 接收文本消息内容
String content = requestMap.get("Content");
// 自动回复文本消息
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {

//如果用户发送表情,则回复同样表情。
if (isQqFace(content)) {
respContent = content;
textMessage.setContent(respContent);
// 将文本消息对象转换成xml字符串
respMessage = MessageUtil.textMessageToXml(textMessage);
} else {
//回复固定消息
switch (content) {

case "1": {
StringBuffer buffer = new StringBuffer();
buffer.append("您好,我是小8,请回复数字选择服务:").append("\n\n");
buffer.append("11 可查看测试单图文").append("\n");
buffer.append("12 可测试多图文发送").append("\n");
buffer.append("13 可测试网址").append("\n");

buffer.append("或者您可以尝试发送表情").append("\n\n");
buffer.append("回复“1”显示此帮助菜单").append("\n");
respContent = String.valueOf(buffer);
textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);
break;
}
case "11": {
//测试单图文回复
Article article = new Article();
article.setTitle("微信公众帐号开发教程Java版");
// 图文消息中可以使用QQ表情、符号表情
article.setDescription("这是测试有没有换行\n\n如果有空行就代表换行成功\n\n点击图文可以跳转到百度首页");
// 将图片置为空
article.setPicUrl("http://www.sinaimg.cn/dy/slidenews/31_img/2016_38/28380_733695_698372.jpg");
article.setUrl("http://www.baidu.com");
articleList.add(article);
newsMessage.setArticleCount(articleList.size());
newsMessage.setArticles(articleList);
respMessage = MessageUtil.newsMessageToXml(newsMessage);
break;
}
case "12": {
//多图文发送
Article article1 = new Article();
article1.setTitle("紧急通知,不要捡这种钱!湛江都已经传疯了!\n");
article1.setDescription("");
article1.setPicUrl("http://www.sinaimg.cn/dy/slidenews/31_img/2016_38/28380_733695_698372.jpg");
article1.setUrl("http://mp.weixin.qq.com/s?__biz=MjM5Njc2OTI4NQ==&mid=2650924309&idx=1&sn=8bb6ae54d6396c1faa9182a96f30b225&chksm=bd117e7f8a66f769dc886d38ca2d4e4e675c55e6a5e01e768b383f5859e09384e485da7bed98&scene=4#wechat_redirect");

Article article2 = new Article();
article2.setTitle("湛江谁有这种女儿,请给我来一打!");
article2.setDescription("");
article2.setPicUrl("http://www.sinaimg.cn/dy/slidenews/31_img/2016_38/28380_733695_698372.jpg");
article2.setUrl("http://mp.weixin.qq.com/s?__biz=MjM5Njc2OTI4NQ==&mid=2650924309&idx=2&sn=d7ffc840c7e6d91b0a1c886b16797ee9&chksm=bd117e7f8a66f7698d094c2771a1114853b97dab9c172897c3f9f982eacb6619fba5e6675ea3&scene=4#wechat_redirect");

Article article3 = new Article();
article3.setTitle("以上图片我就随意放了");
article3.setDescription("");
article3.setPicUrl("http://www.sinaimg.cn/dy/slidenews/31_img/2016_38/28380_733695_698372.jpg");
article3.setUrl("http://mp.weixin.qq.com/s?__biz=MjM5Njc2OTI4NQ==&mid=2650924309&idx=3&sn=63e13fe558ff0d564c0da313b7bdfce0&chksm=bd117e7f8a66f7693a26853dc65c3e9ef9495235ef6ed6c7796f1b63abf1df599aaf9b33aafa&scene=4#wechat_redirect");

articleList.add(article1);
articleList.add(article2);
articleList.add(article3);
newsMessage.setArticleCount(articleList.size());
newsMessage.setArticles(articleList);
respMessage = MessageUtil.newsMessageToXml(newsMessage);
break;
}

case "13": {
//测试网址回复
respContent = "<a href=\"http://www.baidu.com\">百度主页</a>";
textMessage.setContent(respContent);
// 将文本消息对象转换成xml字符串
respMessage = MessageUtil.textMessageToXml(textMessage);
break;
}

default: {
respContent = "(这是里面的)很抱歉,现在小8暂时无法提供此功能给您使用。\n\n回复“1”显示帮助信息";
textMessage.setContent(respContent);
// 将文本消息对象转换成xml字符串
respMessage = MessageUtil.textMessageToXml(textMessage);
}
}
}
}
// 图片消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {
respContent = "您发送的是图片消息!";
textMessage.setContent(respContent);
// 将文本消息对象转换成xml字符串
respMessage = MessageUtil.textMessageToXml(textMessage);
}
// 地理位置消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {
respContent = "您发送的是地理位置消息!";
textMessage.setContent(respContent);
// 将文本消息对象转换成xml字符串
respMessage = MessageUtil.textMessageToXml(textMessage);
}
// 链接消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {
respContent = "您发送的是链接消息!";textMessage.setContent(respContent);
// 将文本消息对象转换成xml字符串
respMessage = MessageUtil.textMessageToXml(textMessage);

}
// 音频消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {
respContent = "您发送的是音频消息!";
textMessage.setContent(respContent);
// 将文本消息对象转换成xml字符串
respMessage = MessageUtil.textMessageToXml(textMessage);
}

// 事件推送
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
// 事件类型
String eventType =requestMap.get("Event");
// 自定义菜单点击事件
if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {
switch (EventKey){
case "11":{
respContent = "这是第一栏第一个";
break;
}
case "12":{
respContent = "这是第一栏第一个";
break;
}
case "21":{
respContent = "这是第二栏第一个";
break;
}

default:{
log.error("开发者反馈:EventKey值没找到,它是:"+EventKey);
respContent= "很抱歉,此按键功能正在升级无法使用";
}
}
textMessage.setContent(respContent);
// 将文本消息对象转换成xml字符串
respMessage = MessageUtil.textMessageToXml(textMessage);
}
else if(eventType.equals(MessageUtil.EVENT_TYPE_VIEW)){
// 对于点击菜单转网页暂时不做推送
}

// 订阅 else if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) { //测试单图文回复 Article article = new Article(); article.setTitle("谢谢您的关注!"); // 图文消息中可以使用QQ表情、符号表情 article.setDescription("点击图文可以跳转到百度首页"); // 将图片置为空 article.setPicUrl("http://www.sinaimg.cn/dy/slidenews/31_img/2016_38/28380_733695_698372.jpg"); article.setUrl("http://www.baidu.com"); articleList.add(article); newsMessage.setArticleCount(articleList.size()); newsMessage.setArticles(articleList); respMessage = MessageUtil.newsMessageToXml(newsMessage); } else if(eventType.equals(MessageUtil.EVENT_TYPE_SCAN)){ //测试单图文回复 Article article = new Article(); article.setTitle("这是已关注用户扫描二维码弹到的界面"); // 图文消息中可以使用QQ表情、符号表情 article.setDescription("点击图文可以跳转到百度首页"); // 将图片置为空 article.setPicUrl("http://www.sinaimg.cn/dy/slidenews/31_img/2016_38/28380_733695_698372.jpg"); article.setUrl("http://www.baidu.com"); articleList.add(article); newsMessage.setArticleCount(articleList.size()); newsMessage.setArticles(articleList); respMessage = MessageUtil.newsMessageToXml(newsMessage); } // 取消订阅 else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) { // TODO 取消订阅后用户再收不到公众号发送的消息,因此不需要回复消息 }

}
} catch (Exception e) {
e.printStackTrace();
}

return respMessage;
}
/**
* 判断是否是QQ表情
*
* @param content
* @return
*/
public static boolean isQqFace(String content) {
boolean result = false;

// 判断QQ表情的正则表达式
String qqfaceRegex = "/::\\)|/::~|/::B|/::\\||/:8-\\)|/::<|/::$|/::X|/::Z|/::'\\(|/::-\\||/::@|/::P|/::D|/::O|/::\\(|/::\\+|/:--b|/::Q|/::T|/:,@P|/:,@-D|/::d|/:,@o|/::g|/:\\|-\\)|/::!|/::L|/::>|/::,@|/:,@f|/::-S|/:\\?|/:,@x|/:,@@|/::8|/:,@!|/:!!!|/:xx|/:bye|/:wipe|/:dig|/:handclap|/:&-\\(|/:B-\\)|/:<@|/:@>|/::-O|/:>-\\||/:P-\\(|/::'\\||/:X-\\)|/::\\*|/:@x|/:8\\*|/:pd|/:<W>|/:beer|/:basketb|/:oo|/:coffee|/:eat|/:pig|/:rose|/:fade|/:showlove|/:heart|/:break|/:cake|/:li|/:bome|/:kn|/:footb|/:ladybug|/:shit|/:moon|/:sun|/:gift|/:hug|/:strong|/:weak|/:share|/:v|/:@\\)|/:jj|/:@@|/:bad|/:lvu|/:no|/:ok|/:love|/:<L>|/:jump|/:shake|/:<O>|/:circle|/:kotow|/:turn|/:skip|/:oY|/:#-0|/:hiphot|/:kiss|/:<&|/:&>";
Pattern p = Pattern.compile(qqfaceRegex);
Matcher m = p.matcher(content);
if (m.matches()) {
result = true;
}
return result;
}
}


七、如果在仿写过程中出现什么问题或者遗漏什么包,在评论区说下即可。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐