微信公众号开发(二)------封装普通消息和事件

微信公众号开发(二)------封装普通消息和事件

前言

在上一篇博文中我们已经对微信公众号进行了接入,接入了公众号,我们的服务器就要处理很多来自己用户的请求,在这里,我们可以梳理一下公众号的逻辑:

  • 首先,用户向微信服务器发送消息
  • 微信服务器接受到用户的消息处理之后,通过我们配置的URL和Token来找到我们的服务器,并以xml的形式向第三方服务器发送消息.
  • 第三方服务器获取消息之后,解析消息,根绝用户的需求提供对应的服务,然后封装成xml数据,传回微信服务器
  • 微信服务器解析这些xml,并返回给用户对应的数据

在这里我们可以看到,用户的请求其实是被微信的服务器转换成xml的形式来和我们进行通信,因此,我们如果要使用java来开发公众号,就必须要对这些消息的类型创建对应的对象,且要使用方便的工具来提供xml和java对象的转换.

正文

一 消息的封装

通过官方文档,我们可以得知用户向微信发送的消息大概有以下几种:

  1. 文本消息
  2. 图片消息
  3. 语音消息
  4. 视频消息
  5. 小视频消息
  6. 地理位置消息
  7. 链接消息

这些消息的格式可以查看文档:消息格式

我们对比每种消息的参数,可以发现,有以下参数是相同的:

  • ToUserName 开发者微信号
  • FromUserName 发送方账号,一个OpendID
  • CreateTime 创建时间(秒)
  • MsgType 消息类型(text, image, voice, video, shortvideo, location, link)
  • MsgId 消息ID

将以上字段封装为一个基类的javaBean,其他的消息类型在此基础上扩展即可.

基类消息体(BaseMessage)
package com.xiaojian.bean.request;

/**
 * 请求消息的基类
 */
public class BaseMessage {

    /**
     * 开发者微信号
     */
    private String toUserName;

    /**
     * 发送方账号
     */
    private String fromUserName;

    /**
     * 消息创建时间
     */
    private long createTime;

    /**
     * 消息类型
     */
    private String msgType;

    /**
     * 消息id
     */
    private long msgId;

    public BaseMessage() {
    }

    public String getToUserName() {
        return toUserName;
    }

    public void setToUserName(String toUserName) {
        this.toUserName = toUserName;
    }

    public String getFromUserName() {
        return fromUserName;
    }

    public void setFromUserName(String fromUserName) {
        this.fromUserName = fromUserName;
    }

    public long getCreateTime() {
        return createTime;
    }

    public void setCreateTime(long createTime) {
        this.createTime = createTime;
    }

    public String getMsgType() {
        return msgType;
    }

    public void setMsgType(String msgType) {
        this.msgType = msgType;
    }

    public long getMsgId() {
        return msgId;
    }

    public void setMsgId(long msgId) {
        this.msgId = msgId;
    }
}

文本消息
package com.xiaojian.bean.request;

/**
 * 文本消息
 */
public class TextMessage extends BaseMessage {

    /**
     * 文本消息内容
     */
    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}
图片消息
package com.xiaojian.bean.request;

/**
 * 图片消息
 */
public class ImageMessage  extends BaseMessage{

    /**
     * 图片链接
     */
    private String picUrl;

    /**
     * 图片消息媒体ID
     */
    private String mediaId;

    public String getPicUrl() {
        return picUrl;
    }

    public void setPicUrl(String picUrl) {
        this.picUrl = picUrl;
    }

    public String getMediaId() {
        return mediaId;
    }

    public void setMediaId(String mediaId) {
        this.mediaId = mediaId;
    }
}
语音消息
package com.xiaojian.bean.request;

/**
 * 语音消息,未开通语音识别的请求体
 */
public class VoiceMessage extends BaseMessage {

    /**
     * 媒体ID
     */
    private String mediaId;

    /**
     * 语音格式
     */
    private String format;

    public String getMediaId() {
        return mediaId;
    }

    public void setMediaId(String mediaId) {
        this.mediaId = mediaId;
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }
}
视频消息
package com.xiaojian.bean.request;

/**
 * 视频消息(和小视频享用同一个实体)
 */
public class VideoMessage extends BaseMessage{

    /**
     * 媒体ID
     */
    private String mediaId;

    /**
     * 视频缩略图媒体Id
     */
    private String thumbMediaId;

    public String getMediaId() {
        return mediaId;
    }

    public void setMediaId(String mediaId) {
        this.mediaId = mediaId;
    }

    public String getThumbMediaId() {
        return thumbMediaId;
    }

    public void setThumbMediaId(String thumbMediaId) {
        this.thumbMediaId = thumbMediaId;
    }
}
地理位置消息
package com.xiaojian.bean.request;

/**
 * 地理位置消息
 */
public class LocationMessage extends BaseMessage {

    /**
     * 地理位置维度
     */
    private String location_X;

    /**
     * 地理位置经度
     */
    private String location_Y;

    /**
     * 地图缩放大小
     */
    private String scale;

    /**
     * 地理位置信息
     */
    private String label;

    public String getLocation_X() {
        return location_X;
    }

    public void setLocation_X(String location_X) {
        this.location_X = location_X;
    }

    public String getLocation_Y() {
        return location_Y;
    }

    public void setLocation_Y(String location_Y) {
        this.location_Y = location_Y;
    }

    public String getScale() {
        return scale;
    }

    public void setScale(String scale) {
        this.scale = scale;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }
}
链接消息
package com.xiaojian.bean.request;

/**
 * 链接消息
 */
public class LinkMessage extends BaseMessage{


    /**
     * 消息标题
     */
    private String title;

    /**
     * 消息描述
     */
    private String description;

    /**
     * 消息链接
     */
    private String url;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}
二 事件的封装

除了普通的消息,用户在和公众号交互的过程过,有些操作会以事件的方式通知到我们的服务器,总共有以下事件:

  • 关注/取消事件
  • 扫描带参数二维码事件
  • 上报地理位置事件
  • 自定义菜单事件
  • 点击菜单拉取消息时的事件推送
  • 点击菜单跳转链接时的事件推送

同样的,我们可以提取出基类的事件对象

基类事件
package com.xiaojian.bean.request.event;

/**
 * 基类事件
 */
public class BaseEvent {

    /**
     * 开发者微信号
     */
    private String toUserName;

    /**
     * 发送方账号
     */
    private String fromUserName;

    /**
     * 消息创建时间
     */
    private long createTime;

    /**
     * 消息类型
     */
    private String msgType;

    /**
     * 事件类型
     */
    private String event;

    public String getToUserName() {
        return toUserName;
    }

    public void setToUserName(String toUserName) {
        this.toUserName = toUserName;
    }

    public String getFromUserName() {
        return fromUserName;
    }

    public void setFromUserName(String fromUserName) {
        this.fromUserName = fromUserName;
    }

    public long getCreateTime() {
        return createTime;
    }

    public void setCreateTime(long createTime) {
        this.createTime = createTime;
    }

    public String getMsgType() {
        return msgType;
    }

    public void setMsgType(String msgType) {
        this.msgType = msgType;
    }

    public String getEvent() {
        return event;
    }

    public void setEvent(String event) {
        this.event = event;
    }
}
关注/取消事件
package com.xiaojian.bean.request.event;

/**
 * 取消/关注事件
 */
public class SubscribeEvent extends BaseEvent{



}

扫描带参数的二维码事件
package com.xiaojian.bean.request.event;

/**
 * 扫描带参数的二维码事件
 */
public class QRCodeEvent extends BaseEvent {


    /**
     * 事件KEY值,qrscene_为前缀,后面为二维码的参数值
     */
    private String eventKey;

    /**
     * ticket,用户换取二维码图片
     */
    private String ticket;

    public String getEventKey() {
        return eventKey;
    }

    public void setEventKey(String eventKey) {
        this.eventKey = eventKey;
    }

    public String getTicket() {
        return ticket;
    }

    public void setTicket(String ticket) {
        this.ticket = ticket;
    }
}
上报地理位置事件
package com.xiaojian.bean.request.event;

/**
 * 上报地理位置事件
 */
public class LocationEvent extends BaseEvent {

    /**
     * 地理位置维度
     */
    private String latitude;

    /**
     * 地理位置经度
     */
    private String longitude;

    /**
     * 地理位置精度
     */
    private String precision;

    public String getLatitude() {
        return latitude;
    }

    public void setLatitude(String latitude) {
        this.latitude = latitude;
    }

    public String getLongitude() {
        return longitude;
    }

    public void setLongitude(String longitude) {
        this.longitude = longitude;
    }

    public String getPrecision() {
        return precision;
    }

    public void setPrecision(String precision) {
        this.precision = precision;
    }
}
自定义菜单事件
package com.xiaojian.bean.request.event;

/**
 * 自定义菜单事件
 */
public class MenuEvent extends BaseEvent{

    /**
     * 事件KEY值
     */
    private String eventKey;

    public String getEventKey() {
        return eventKey;
    }

    public void setEventKey(String eventKey) {
        this.eventKey = eventKey;
    }
}

现在请求的各种数据都已经封装好了,下面来封装对应的响应消息.

三 封装响应消息

查看官方文档,当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐).

而微信官方也对响应的消息做了区分,分别有回复文本、图片、语音、视频、音乐、图文这六种,在官方文档也有对应的响应消息的xml格式:响应消息格式

我们同样的提取他们的公共属性来创建响应基类:

响应消息基类
package com.xiaojian.bean.response;

/**
 * 响应消息的基类
 */
public class BaseMessageResponse {

    /**
     * 开发者微信号
     */
    private String ToUserName;

    /**
     * 发送方账号
     */
    private String FromUserName;

    /**
     * 消息创建时间
     */
    private long CreateTime;

    /**
     * 消息类型
     */
    private String MsgType;

    public String getToUserName() {
        return ToUserName;
    }

    public void setToUserName(String toUserName) {
        ToUserName = toUserName;
    }

    public String getFromUserName() {
        return FromUserName;
    }

    public void setFromUserName(String fromUserName) {
        FromUserName = fromUserName;
    }

    public long getCreateTime() {
        return CreateTime;
    }

    public void setCreateTime(long createTime) {
        CreateTime = createTime;
    }

    public String getMsgType() {
        return MsgType;
    }

    public void setMsgType(String msgType) {
        MsgType = msgType;
    }
}
回复文本消息
package com.xiaojian.bean.response;

/**
 * 文本消息的回复对象
 */
public class TextMessageResponse extends BaseMessageResponse{

    /**
     * 回复的消息内容
     */
    private String Content;

    public String getContent() {
        return Content;
    }

    public void setContent(String content) {
        Content = content;
    }
}
回复图片消息
package com.xiaojian.bean.commons;

/**
 * 对应响应消息中的图片xml
 */
public class Image {

    private String MediaId;

    public String getMediaId() {
        return MediaId;
    }

    public void setMediaId(String mediaId) {
        this.MediaId = mediaId;
    }
}
package com.xiaojian.bean.response;

import com.xiaojian.bean.commons.Image;

/**
 * 图片消息的响应对象
 */
public class ImageMessageResponse extends BaseMessageResponse{

    /**
     * 图片
     */
    private Image Image;

    public com.xiaojian.bean.commons.Image getImage() {
        return Image;
    }

    public void setImage(com.xiaojian.bean.commons.Image image) {
        Image = image;
    }
}
回复语音消息
package com.xiaojian.bean.commons;

/**
 * 响应消息中对应的voice model
 */
public class Voice {

    /**
     * 媒体文件id
     */
    private String MediaId;

    public String getMediaId() {
        return MediaId;
    }

    public void setMediaId(String mediaId) {
        this.MediaId = mediaId;
    }
}
package com.xiaojian.bean.response;

import com.xiaojian.bean.commons.Voice;

/**
 * 语音消息响应体
 */
public class VoiceMessageResponse extends BaseMessageResponse{

    /**
     * 消息中包含的语音
     */
    private Voice Voice;

    public Voice getVoice() {
        return Voice;
    }

    public void setVoice(Voice voice) {
        this.Voice = voice;
    }
}
回复视频消息
package com.xiaojian.bean.commons;

/**
 * 响应中对应的视频model
 */
public class Video {

    /**
     * 媒体id
     */
    private String MediaId;

    /**
     * 视频标题
     */
    private String Title;

    /**
     * 视频描述
     *
     */
    private String Description;

    public String getMediaId() {
        return MediaId;
    }

    public void setMediaId(String mediaId) {
        MediaId = mediaId;
    }

    public String getTitle() {
        return Title;
    }

    public void setTitle(String title) {
        Title = title;
    }

    public String getDescription() {
        return Description;
    }

    public void setDescription(String description) {
        Description = description;
    }
}
package com.xiaojian.bean.response;

import com.xiaojian.bean.commons.Video;

/**
 * 响应视频消息的model
 */
public class VideoMessageResponse extends BaseMessageResponse{

    /**
     * 视频
     */
    private Video Video;

    public Video getVideo() {
        return Video;
    }

    public void setVideo(Video video) {
        this.Video = video;
    }
}
回复音乐消息
package com.xiaojian.bean.commons;

/**
 * 音乐
 */
public class Music {
    /**
     * 音乐标题
     */
    private String Title;

    /**
     * 音乐描述
     */
    private String Description;

    /**
     * 音乐链接
     */
    private String MusicURL;

    /**
     * 高质量音乐链接
     */
    private String HQMusicUrl;

    /**
     * 媒体id
     */
    private String ThumbMediaId;

    public String getTitle() {
        return Title;
    }

    public void setTitle(String title) {
        Title = title;
    }

    public String getDescription() {
        return Description;
    }

    public void setDescription(String description) {
        Description = description;
    }

    public String getMusicURL() {
        return MusicURL;
    }

    public void setMusicURL(String musicURL) {
        MusicURL = musicURL;
    }

    public String getHQMusicUrl() {
        return HQMusicUrl;
    }

    public void setHQMusicUrl(String HQMusicUrl) {
        this.HQMusicUrl = HQMusicUrl;
    }

    public String getThumbMediaId() {
        return ThumbMediaId;
    }

    public void setThumbMediaId(String thumbMediaId) {
        ThumbMediaId = thumbMediaId;
    }
}
package com.xiaojian.bean.response;


import com.xiaojian.bean.commons.Music;

/**
 * 响应音乐消息
 */
public class MusicMessageResponse extends BaseMessageResponse{

    /**
     * 音乐
     */
    private Music Music;

    public Music getMusic() {
        return Music;
    }

    public void setMusic(Music music) {
        Music = music;
    }
}
回复图文消息
package com.xiaojian.bean.commons;

/**
 * 图文消息model
 */
public class Article {

    /**
     * 图文消息标题
     */
    private String Title;

    /**
     *  图文消息描述
     */
    private String Description;

    /**
     * 图片链接
     */
    private String PicUrl;

    /**
     * 点击图文消息跳转链接
     */
    private String Url;

    public String getTitle() {
        return Title;
    }

    public void setTitle(String title) {
        Title = title;
    }

    public String getDescription() {
        return Description;
    }

    public void setDescription(String description) {
        Description = description;
    }

    public String getPicUrl() {
        return PicUrl;
    }

    public void setPicUrl(String picUrl) {
        PicUrl = picUrl;
    }

    public String getUrl() {
        return Url;
    }

    public void setUrl(String url) {
        Url = url;
    }
}
package com.xiaojian.bean.response;

import com.xiaojian.bean.commons.Article;

import java.util.List;

/**
 * 图文消息响应model
 */
public class ArticleMessageResponse extends BaseMessageResponse {

    /**
     * 图文消息个数
     */
    private int Articlecount;

    /**
     * 多条图文消息信息
     */
    private List<Article> Articles;

    public int getArticlecount() {
        return Articlecount;
    }

    public void setArticlecount(int articlecount) {
        Articlecount = articlecount;
    }

    public List<Article> getArticles() {
        return Articles;
    }

    public void setArticles(List<Article> articles) {
        Articles = articles;
    }
}

总结

至此,消息的封装就结束了,我们可以使用我们创建的各种javabean来封装请求和回复的消息.在下一篇博文中,我们将实现简单的消息识别和公众号回应.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值