网络知识 娱乐 java微信公众号接入(2)

java微信公众号接入(2)

上一篇文章写了接入,这篇文章写接收用户消息和根据用户消息推送图文消息

maven2个依赖:<dependency>  <groupId>org.dom4j</groupId>  <artifactId>dom4j</artifactId>  <version>2.1.1</version></dependency>

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

PART1

微信提供的官方文档已经写明了:

提供一个post请求、按照文本消息的格式返回给微信客户端就达到了消息推送的目的:

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>1348831860</CreateTime>
  <MsgType><![CDATA[text]]></MsgType>
  <Content><![CDATA[this is a test]]></Content>
  <MsgId>1234567890123456</MsgId>
</xml>

PART2

conllter类:这里边有个坑,@PostMapping和上一篇文章的@GetMapping路径必须一致

@ResponseBody    @PostMapping(value = "/msg")    public String msg(HttpServletResponse response, HttpServletRequest request) throws Exception {        //Map<String,String> map = WxService.parseRequest(response,request);        String xml = wxCoreService.weixinMessageHandelCoreService(request,response);        //String xml = "<xml><ToUserName>opSgm1sB8VlAfsdBnHwTAPJMAlfY</ToUserName>        // <FromUserName>gh_ba3ffb3b11c8</FromUserName>        // <CreateTime>1548574358</CreateTime>        // <MsgType>text</MsgType>        // <Content>我不能识别你发送的内容!</Content></xml>";        request.setCharacterEncoding("UTF-8");        // 在响应消息(回复消息给用户)时,也将编码方式设置为UTF-8,原理同上;        response.setCharacterEncoding("UTF-8");        //wxCoreService.g        if (!StringUtils.isEmpty(xml)){            log.info("返回微信消息成功!");            System.out.println(xml);            return xml;        }else {            log.info("微信消息处理失败!");            return "error";        }    }

向测试号发送一个信息

后台把消息封装成了map

流读取微信发送的文本,把文本转成map格式

public static Map<String,String> parseRequest(HttpServletResponse response, HttpServletRequest request) {        logger.info("开始处理微信消息");        Map<String,String> map = new HashMap<>();        SAXReader saxReader = new SAXReader();        try {            //读取输入流,获取文档对象            InputStream inputStream = request.getInputStream();            Document document = saxReader.read(inputStream);            //根据文档对象获取根节点            Element rootElement = document.getRootElement();            //获取根节点的所有子节点            List<Element> elements = rootElement.elements();            for (Element element : elements) {                map.put(element.getName(),element.getStringValue());            }            inputStream.close();        } catch (DocumentException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return map;
    }

PART3

拿到用户发送的消息,就可以开始做消息回复了,可以根据用户发送的内容,自定义回复内容,机器人也就是这个原理,有开源的微信机器人API,可以直接调用,这里不详细说明,感兴趣的可以自己百度

微信公众号回复图文消息的文本格式:

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>12345678</CreateTime>
  <MsgType><![CDATA[news]]></MsgType>
  <ArticleCount>1</ArticleCount>
  <Articles>
    <item>
      <Title><![CDATA[title1]]></Title>
      <Description><![CDATA[description1]]></Description>
      <PicUrl><![CDATA[picurl]]></PicUrl>
      <Url><![CDATA[url]]></Url>
    </item>
  </Articles>
</xml>

接下来处理用户消息内容,文本里有msgtype提供了消息类型,不同类型返回的文本格式是不一样的,具体参考微信公众号开发文档,这边拿消息文本做示例:

@Override    public String weixinMessageHandelCoreService(HttpServletRequest request, HttpServletResponse response) {        BaseMessage msg = null;        Map<String, String> map = WxMsgHandlerUtil.parseRequest(response, request);        System.out.println("接收到的消息:" + map);
        log.info("开始处理消息类型");        String msgType = map.get("MsgType");        switch(msgType){                //文本            case "text":                msg = WxMsgHandlerUtil.dealTextMessage(map);                break;                //图片            case "image":                break;        }
        //把消息对象处理为xml        System.out.println(msg);
        return msg != null?WxMsgHandlerUtil.beanToXml(msg):null;    }

这边把消息类型封装为Bean,此处省略getter、setter,方便转为XML格式以此适合微信消息文本格式

public class BaseMessage {
    @XStreamAlias("ToUserName")    private String toUserName;//开发者微信号
    @XStreamAlias("FromUserName")    private String fromUserName;//发送方帐号(一个OpenID)
    @XStreamAlias("CreateTime")    private Long createTime;//消息创建时间 (整型)
    @XStreamAlias("MsgType")    private String msgType;//消息类型}
@XStreamAlias("xml")public class NewsMessage extends BaseMessage {
    @XStreamAlias("ArticleCount")    private String articleCount;    @XStreamAlias("Articles")    private List<Articles> articles = new ArrayList<>();}
@XStreamAlias("item")public class Articles {
    @XStreamAlias("Title")    private String title;//标题
    @XStreamAlias("Description")    private String description;//描述

    @XStreamAlias("PicUrl")    private String picUrl;//图片链接
    @XStreamAlias("Url")    private String url;//点击图文消息跳转链接}

自定义消息回复、并转为XML格式,返回,注意:这边的图片URL必须是微信上的,怎么取呢,先给测试号发一张图片,后台输出来复制到就好了

 public static BaseMessage dealTextMessage(Map<String, String> map) {        //用户发来的消息        String content = map.get("Content");        //String msg = chatWithRobort(content);        List<Articles> articles = null;        if("1".equals(content)){            articles = new ArrayList<>();            String picUrl = "http://mmbiz.qpic.cn/mmbiz_jpg/V6sQHCpiblmCTG1LiaFuSgCJ3wicxTs1s2tBoveCvicZ" +                    "Q6LjGniajyCB6ItPxkjXgS3UopwnHGFvyj25RziacknAytrA/";            articles.add(new Articles("哪有那么多惊喜,惊吓就有!","赶紧点进去看看吧!记得收藏", picUrl, "https://www.leemus.cn"));            NewsMessage news = new NewsMessage(map,"1",articles);            System.out.println("news:" + news);            return news;        }else {            TextMessage tm = new TextMessage(map,"回复1有惊喜哦!");            System.out.println("text:" +tm);            return tm;        }
    }
 /**     * bean处理成xml     * @param msg     * @return     */    public static String beanToXml(BaseMessage msg) {        XStream stream = new XStream();        stream.processAnnotations(TextMessage.class);        stream.processAnnotations(ImageMessage.class);        stream.processAnnotations(VideoMessage.class);        stream.processAnnotations(VoiceMessage.class);        stream.processAnnotations(MusicMessage.class);        stream.processAnnotations(NewsMessage.class);        String s = stream.toXML(msg);        return s;    }

后面controller拿到解析好的xml返回给微信客户端就完成了消息推送!