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

来源:互联网 发布:淘宝店铺宣传单 编辑:程序博客网 时间:2024/05/09 15:01

菜单这部分相对来说是简单的,所以做起来很快。

一、看公众号的文档可知有些接口调用可能要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秒执行一次 */@Componentpublic 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;        }}

七、如果在仿写过程中出现什么问题或者遗漏什么包,在评论区说下即可。。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 格力空调保修期内坏了怎么办 国际联程航班第一程延误怎么办 大麦网演唱会的票售罄了怎么办 国内转机航班第一班延误了怎么办 联程机票下一程航班被取消怎么办 联程机票第一班航班取消怎么办 联程机票第二段航班被取消怎么办 联程航班第一程延误行李怎么办 联程航班未赶上第二程行李怎么办 高铁晚点赶不上下一趟动车怎么办? 动车晚点赶不上下一趟车怎么办 动车晚点导致没赶上下一趟怎么办 浙大三位一体选考分数报错了怎么办 报到证上时间到期了还没报到怎么办 不停的打嗝已经超过24小时怎么办 面对不给下属做主的领导怎么办 法院说退款受伤人去不了证明怎么办 e栈快递柜没收到短信怎么办 京东快递放门卫丢了怎么办 丰巢快递柜收不到取件码怎么办 丰巢快递柜手机号码填错了怎么办 e栈手机号换了取不出来怎么办 买高铁票起点一样终点不一样怎么办 定火车票把名字写错一个字怎么办 火车票坐完车票丢了报销怎么办 客户交给我的钱被骗了怎么办 要证明网络来源的可靠性该怎么办 魅族手机高德地图信号弱怎么办 t恤的印花粘粘的怎么办 从包图网下载的模板素材丢失怎么办 大屏导航的语音功能怎么办用 手机导航不走地图上面走时怎么办 行车撞到步行人死亡师机逃离怎么办 小天才平板电脑不显示了怎么办 高德地图导航不显示车速怎么办 桥梁梁片强度达不到设计要求怎么办 新车交车检验表客户没签字怎么办 中铁快运职工拒绝提货要怎么办 奇瑞a3暖风水箱爆了怎么办 别人挖鱼塘占了我的山土怎么办 自己的鱼塘让别人强行占住了怎么办