美文网首页
Java-Spring Boot-微信公众号(三)给用户回复信息

Java-Spring Boot-微信公众号(三)给用户回复信息

作者: 唔哒喂 | 来源:发表于2021-10-07 23:00 被阅读0次

    基本上复制粘贴,稍加修改即可使用。

    接上一篇处理用户关注,当后台接收到关注信息后,应当给用户返回一条信息。
    除关注之外,用户发送信息,我们也需要做出相应的回复。

    获取用户发送的信息

    首先简单介绍一下,获取用户发送的信息。
    与关注一样,当用户输入信息后点击发送后,微信会Post数据到后台。
    接收方法也是一样,将XML数据存入Map。
    代码如下。

    所需Jar包(Maven)

            <dependency>
                <groupId>dom4j</groupId>
                <artifactId>dom4j</artifactId>
                <version>1.6.1</version>
            </dependency>
            <dependency>
                <groupId>com.thoughtworks.xstream</groupId>
                <artifactId>xstream</artifactId>
                <version>1.4.11.1</version>
            </dependency>
    

    代码-解析用户发送的数据

     req.setCharacterEncoding("UTF-8"); // 接收请求时的编码。
            resp.setCharacterEncoding("UTF-8"); // 响应给浏览器的编码。
    //        个人理解设置编码的原因是 由于 xml解析时编码要一致。
            SAXReader saxReader = new SAXReader();
            BasicInfo backInfo = null;//这个是我自定义的返回信息的超类。(可略)
    
            XStream xStream = new XStream();
            Map<String, String> map = new HashMap<>();
            Document read = saxReader.read(req.getInputStream());
                //得到根节点
            Element rootElement = read.getRootElement();
                //获得子节点
            List<Element> elements = rootElement.elements();
            for (Element e:
                    elements) {
                    //将数据存进map
                map.put(e.getName(), e.getStringValue());
            }
    

    执行完到这里已经在map中存了这些信息。【文本信息为例】
    其他类型见官方文档

    image.png

    判别发送类型及获得消息内容

    已知我们判别用户关注是根据这个关键字。

    if (map.containsKey("Event") && map.get("Event").equals("subscribe"))
    

    判别发送的是文字(text)、图片(image)、语音(voice)为的关键字为MsgType


    image.png
    else if (map.containsKey("MsgType") && map.get("MsgType").equals("text"))
    

    以文本为例,获取用户发送的消息为

    map.get("Content")
    

    至此已经得到了关键字、关注信息。

    回复消息

    前置准备

    由于可以给用户回复文本、图片、图文消息等。
    提取其中各类型回复所需的相同数据,设计为一个父类。
    建议加上无参构造器和所有属性的set-get方法。

    @XStreamAlias("xml")
    public class BasicInfo {
        private String ToUserName;
        private String FromUserName;
        private String CreateTime;
        private String MsgType;
    
        public BasicInfo(String toUserName, String fromUserName, String createTime, String msgType) {
            this.ToUserName = toUserName;
            FromUserName = fromUserName;
            CreateTime = createTime;
            MsgType = msgType;
        }
    //建议加上无参构造器和所有属性的set-get方法。
    }
    

    文本信息子类

    然后设计一个子类,用于存储回复文本信息所需的属性。
    建议加上无参构造器和所有属性的set-get方法。

    @XStreamAlias("xml")
    public class BackTextInfo extends BasicInfo{
        private String Content;
        public BackTextInfo(String ToUserName, String FromUserName, String CreateTime, String MsgType, String Content){
            super(ToUserName, FromUserName, CreateTime, MsgType);
            this.Content = Content;
        }
    //建议加上无参构造器和所有属性的set-get方法。
    }
    

    图文信息[需要两个类]

    继承基础信息的子类

    建议加上无参构造器和所有属性的set-get方法。

    public class BackArticlesInfo extends BasicInfo{
        private Integer ArticleCount;
        private List<ArticleItem> Articles;
    
        public BackArticlesInfo(String toUserName, String fromUserName, String createTime, String msgType, Integer articleCount, List<ArticleItem> articles) {
            super(toUserName, fromUserName, createTime, msgType);
            ArticleCount = articleCount;
            Articles = articles;
        }
    }
    

    ArticleItem类

    建议加上无参构造器和所有属性的set-get方法。

    public class ArticleItem{
        private String Title;
        private String Description;
        private String PicUrl;
        private String Url;
    
        public ArticleItem(String title, String description, String picUrl, String url) {
            Title = title;
            Description = description;
            PicUrl = picUrl;
            Url = url;
        }
    //建议加上无参构造器和所有属性的set-get方法。
    }
    

    其他类型类似

    回复文本

    比如说,我们接收到用户发送的信息中心包含 :"网站"两个字,就把网站链接返回给用户。

    //        返回网站信息
    
            else if (map.containsKey("Content") && map.get("Content").contains("网站")){
                System.out.println("wangzhan");
                backInfo = wxService.setWebInfo(map);//这里的代码见下
                xStream.alias("xml", BackTextInfo.class);
            }
    

    注意

    这里的FromUserName[公众号], ToUserName[用户]
    而map中存的是 FromUserName[用户], ToUserName[公众号]
    需要调转。
    还有,一定要设置这一句,xStream.alias("xml", BackTextInfo.class);
    第二个参数是你设计的类的Class对象。

    backInfo = wxService.setWebInfo(map);//这里的代码见下

    public BasicInfo setWebInfo(Map<String, String> map) {
            String Content = "www.baidu.com";
            return new BackTextInfo(map.get("FromUserName"), (String)map.get("ToUserName"),
                    System.currentTimeMillis() / 1000 + "", "text", Content);
        }
    

    将数据给用户

            String s = xStream.toXML(backInfo);
            System.out.println(s);
            PrintWriter writer = resp.getWriter();
            writer.write(s);
            writer.flush();
            writer.close();
    

    回复图文

    类似回复文本

     else if (map.containsKey("Content") && map.get("Content").equalsIgnoreCase("tuwen")){
                backInfo = wxService.setHelpInfo(map);
                xStream.alias("xml", BackArticlesInfo.class);
                xStream.alias("item", ArticleItem.class);
            }
    
    public BasicInfo setHelpInfo(Map<String, String> map) {
            String title1 = "【图文】";
            String description1 = "点我查看图文";
            String picUrl1 = "https://123.jpg";
            String url1 = "https://微信发布的图文链接";
            ArticleItem articleItem1 = new ArticleItem(title1, description1, picUrl1, url1);
    
            List<ArticleItem> articleItems = new ArrayList<>();
            articleItems.add(articleItem1);
    
    
            return new BackArticlesInfo(map.get("FromUserName"), map.get("ToUserName")
            ,System.currentTimeMillis() / 1000 + "", "news", 1, articleItems);
    
        }
    

    将数据给用户

            String s = xStream.toXML(backInfo);
            System.out.println(s);
            PrintWriter writer = resp.getWriter();
            writer.write(s);
            writer.flush();
            writer.close();
    

    完整代码

    Controller

    因为我做的只有图文和文本,所以对于MsgType没有判定。
    大家可以自己加。

    @PostMapping(value = "/connect")
        public void getXml(HttpServletRequest req, HttpServletResponse resp) throws IOException, DocumentException {
            req.setCharacterEncoding("UTF-8"); // 接收请求时的编码。
            resp.setCharacterEncoding("UTF-8"); // 响应给浏览器的编码。
    //        个人理解设置编码的原因是 由于 xml解析时编码要一致。
            SAXReader saxReader = new SAXReader();
            BasicInfo backInfo = null;//这个是我自定义的返回信息的超类。
    
            XStream xStream = new XStream();
            Map<String, String> map = new HashMap<>();
            Document read = saxReader.read(req.getInputStream());
                //得到根节点
            Element rootElement = read.getRootElement();
                //获得子节点
            List<Element> elements = rootElement.elements();
            for (Element e:
                    elements) {
                    //将数据存进map
                map.put(e.getName(), e.getStringValue());
            }
    //            判断用户是否为关注
            if (map.containsKey("Event") && map.get("Event").equals("subscribe")) {
    //            处理关注
                backInfo = wxService.setSubscribe(map);
                System.out.println("关注");
                xStream.alias("xml", BackArticlesInfo.class);
                xStream.alias("item", ArticleItem.class);
    
            }
    
    //        处理返回图文信息
            else if (map.containsKey("Content") && map.get("Content").equalsIgnoreCase("tuwen")){
                backInfo = wxService.setHelpInfo(map);
                xStream.alias("xml", BackArticlesInfo.class);
                xStream.alias("item", ArticleItem.class);
            }
    //        返回文本信息
    
            else if (map.containsKey("Content") && map.get("Content").contains("网站")){
                System.out.println("wangzhan");
                backInfo = wxService.setWebInfo(map);
                xStream.alias("xml", BackTextInfo.class);
            }
    
            String s = xStream.toXML(backInfo);
            System.out.println(s);
            PrintWriter writer = resp.getWriter();
            writer.write(s);
            writer.flush();
            writer.close();
    
        }
    

    Service

    @Service
    public class WxService {
    
    
        public BackArticlesInfo setSubscribe(Map<String, String> map) {
            String title1 = "【欢迎关注】";
            String description1 = "点我看图文。";
            String picUrl1 = "https://123.jpg";
            String url1 = "https://发布的图文";
    
            ArticleItem articleItem1 = new ArticleItem(title1, description1, picUrl1, url1);
    
            List<ArticleItem> articleItems = new ArrayList<>();
            articleItems.add(articleItem1);
    
    
            return new BackArticlesInfo(map.get("FromUserName"), map.get("ToUserName")
                    ,System.currentTimeMillis() / 1000 + "", "news", 1, articleItems);
        }
    
        public BasicInfo setHelpInfo(Map<String, String> map) {
            String title1 = "【图文】";
            String description1 = "点我查看图文";
            String picUrl1 = "https://123.jpg";
            String url1 = "https://发布的图文";
            ArticleItem articleItem1 = new ArticleItem(title1, description1, picUrl1, url1);
    
            List<ArticleItem> articleItems = new ArrayList<>();
            articleItems.add(articleItem1);
    
    
            return new BackArticlesInfo(map.get("FromUserName"), map.get("ToUserName")
            ,System.currentTimeMillis() / 1000 + "", "news", 1, articleItems);
    
        }
    
        public BasicInfo setWebInfo(Map<String, String> map) {
            String Content = "www.baidu.com";
            return new BackTextInfo(map.get("FromUserName"), (String)map.get("ToUserName"),
                    System.currentTimeMillis() / 1000 + "", "text", Content);
        }
    
    

    下面也是这个Service中的是连接数据库了。

    @Resource
       private BookMapper bookMapper;
    
       public BasicInfo getBook(Map<String, String> map) {
           PayLink payLink = ;
           String Content;
           if (payLink != null) {
               System.out.println(payLink);
               Content = "";
           }
           else {
               System.out.println("不存在");
               Content = "";
           }
           return new BackTextInfo(map.get("FromUserName"), map.get("ToUserName"), System.currentTimeMillis()/1000+"",
                   "text", Content);
    
       }
    
       public BasicInfo backError(Map<String, String> map) {
           String Content = "抱歉";
           return new BackTextInfo(map.get("FromUserName"), map.get("ToUserName"), System.currentTimeMillis()/1000+"",
                   "text", Content);
       }
    
       public BasicInfo search(String content, Map<String, String> map) {
    
           List<PayLink>payLinks =  bookMapper.searchBooks(content);
           if (payLinks.size() == 0){
               String Content = "[未找到输入的信息] ";
             
              return  new BackTextInfo(map.get("FromUserName"), map.get("ToUserName"), System.currentTimeMillis()/1000+"",
                   "text", Content);}
           StringBuilder sb = new StringBuilder();
           String head = content + "\n" +
                  "\n";
           sb.append(head);
           for (PayLink p:
                payLinks) {
                   sb.append("回复:").append(p.getRuleId()).append(",");
                   sb.append(p.getRuleKey()).append("\n");
           }
           return new BackTextInfo(map.get("FromUserName"), map.get("ToUserName"), System.currentTimeMillis()/1000+"",
                  "text", sb.toString());
       }
    }
    
    ```
    

    相关文章

      网友评论

          本文标题:Java-Spring Boot-微信公众号(三)给用户回复信息

          本文链接:https://www.haomeiwen.com/subject/rzwznltx.html