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

2021-10-07  本文已影响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());
   }
}

```
上一篇 下一篇

猜你喜欢

热点阅读