微信公众号开发——接收用户消息(图文、语言、上报位置、关注、取消关注)及自动回复

news2024/11/19 16:25:34
😊 @ 作者: 一恍过去
💖 @ 主页: https://blog.csdn.net/zhuocailing3390
🎊 @ 社区: Java技术栈交流
🎉 @ 主题: 微信公众号开发——接收用户消息(图文、语言、上报位置、关注、取消关注)及自动回复
⏱️ @ 创作时间: 2022年12月12日

目录

  • 准备工作
  • 1、定义消息转换工具类
  • 2、消息类型常量定义
  • 3、接收及回复消息说明
    • 3.1 消息接收及回复基础实体类定义
    • 3.2 接收及回复文本信息
    • 3.4 接收及回复图文信息
    • 3.5 接收及回复语音信息
    • 3.6 接收及回复视频/小视频信息
    • 3.7 接收链接信息
    • 3.8 接收位置信息
  • 4、完整示例代码

准备工作

1、调用微信公众号接口,需要实现获取AccessToken,参考《获取AccessToken接口调用凭据》
2、在本地进行联调时,为让微信端能够访问到本地服务,需要进行内网穿透,参考《本地服务器内网穿透实现(NATAPP)》
3、配置微信接口配置信息,用于告诉微信接收消息的回调地址
在这里插入图片描述

1、定义消息转换工具类

WeixinMessageUtil

@Component
public class WeixinMessageUtil {
    /**
     * 将二进制数据转换为16进制字符串
     *
     * @param src
     * @return
     */
    public static String byte2HexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (byte b : src) {
            String hv = Integer.toHexString(b & 0xFF);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * 对字符串进行sha1加签
     *
     * @param context
     * @return
     * @throws Exception
     */
    public static String sha1(String context) throws Exception {
        // 获取sha1算法封装类
        MessageDigest sha1Digest = MessageDigest.getInstance("SHA-1");
        // 进行加密
        byte[] digestResult = sha1Digest.digest(context.getBytes("UTF-8"));
        // 转换为16进制字符串
        return WeixinMessageUtil.byte2HexString(digestResult);
    }

    /**
     * 将输入流使用指定编码转化为字符串 获取xml
     *
     * @param request
     * @return
     * @throws Exception
     */
    public static String inputStream2String(HttpServletRequest request) throws Exception {
        InputStream io = request.getInputStream();
        // 建立输入流读取类
        InputStreamReader reader = new InputStreamReader(io, "UTF-8");
        // 设定每次读取字符个数
        char[] data = new char[512];
        int dataSize = 0;
        // 循环读取
        StringBuilder stringBuilder = new StringBuilder();
        while ((dataSize = reader.read(data)) != -1) {
            stringBuilder.append(data, 0, dataSize);
        }
        return stringBuilder.toString();
    }

    public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException {
        Map<String, String> map = new HashMap<>();
        SAXReader reader = new SAXReader();
        InputStream io = request.getInputStream();
        Document document = (Document) reader.read(io);
        Element root = document.getRootElement();
        List<Element> elements = root.elements();
        for (Element element : elements) {
            map.put(element.getName(), element.getText());
        }
        io.close();
        return map;
    }

    /**
     * 将对象转化为xml字符串。 rootName 为根节点名称
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static String obj2Xml(Object obj) {
        XStream xstream = new XStream();
        xstream.alias("xml", obj.getClass());
        return xstream.toXML(obj);
    }
}

2、消息类型常量定义

MessageType:

public class MessageType {
    /**
     * 请求消息类型:文本
     */
    public static final String REQ_MESSAGE_TYPE_TEXT = "text";

    /**
     * 请求消息类型:图片
     */
    public static final String REQ_MESSAGE_TYPE_IMAGE = "image";

    /**
     * 请求消息类型:语音
     */
    public static final String REQ_MESSAGE_TYPE_VOICE = "voice";

    /**
     * 请求消息类型:视频
     */
    public static final String REQ_MESSAGE_TYPE_VIDEO = "video";

    /**
     * 请求消息类型:链接
     */
    public static final String REQ_MESSAGE_TYPE_LINK = "link";

    /**
     * 请求消息类型:地理位置
     */
    public static final String REQ_MESSAGE_TYPE_LOCATION = "location";

    /**
     * 请求消息类型:小视频
     */
    public static final String REQ_MESSAGE_TYPE_SHORTVIDEO = "shortvideo";

    /**
     * 请求消息类型:事件推送
     */
    public static final String REQ_MESSAGE_TYPE_EVENT = "event";

    /**
     * 返回消息类型:文本
     */
    public static final String RESP_MESSAGE_TYPE_TEXT = "text";

    /**
     * 消息返回类型:图片
     */
    public static final String RESP_MESSAGE_TYPE_IMAGE = "image";

    /**
     * 消息返回类型:语音
     */
    public static final String RESP_MESSAGE_TYPE_VOICE = "voice";

    /**
     * 消息返回类型:音乐
     */
    public static final String RESP_MESSAGE_TYPE_MUSIC = "music";

    /**
     * 消息返回类型:图文
     */
    public static final String RESP_MESSAGE_TYPE_NEWS = "news";

    /**
     * 消息返回类型:视频
     */
    public static final String RESP_MESSAGE_TYPE_VIDEO = "video";

    /**
     * 事件类型:订阅
     */
    public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";

    /**
     * 事件类型:取消订阅
     */
    public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";

    /**
     * 事件类型:scan(关注用户扫描带参二维码)
     */
    public static final String EVENT_TYPE_SCAN = "SCAN";

    /**
     * 事件类型:location(上报地理位置)
     */
    public static final String EVENT_TYPE_LOCATION = "LOCATION";

    /**
     * 事件类型:CLICK(点击菜单拉取消息)
     */
    public static final String EVENT_TYPE_CLICK = "CLICK";

    /**
     * 事件类型:VIEW(自定义菜单URl视图)
     */
    public static final String EVENT_TYPE_VIEW = "VIEW";
}

3、接收及回复消息说明

3.1 消息接收及回复基础实体类定义

接收基础实体类:BaseInfo:

@Data
public class BaseInfo {
    /**
     * 开发者微信号
     */
    private String ToUserName;
    /**
     * 发送方帐号(一个OpenID)
     */
    private String FromUserName;
    /**
     * 文本 图片 语音 视频 小视频 地理位置 链接 事件
     */
    private String MsgType;
    /**
     * 消息创建时间 (整型)
     */
    private long CreateTime;
    /**
     * 消息id
     */
    private String MsgId;
}

回复基础实体类:BaseResult:

@Data
public class BaseResult {
    /**
     * 接收方帐号(收到的OpenID)
     */
    private String ToUserName;
    /**
     * 开发者微信号
     */
    private String FromUserName;
    /**
     * 消息创建时间 (整型)
     */
    private Long CreateTime;
    /**
     * 消息类型(text/music/news)
     */
    private String MsgType;
}

回复多媒体实体类:MultimediaResult:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class MultimediaResult {
    /**
     * 通过素材管理中的接口上传多媒体文件或者接收用户的多媒体消息,得到的id
     */
    private String MediaId;

    /**
     * 视频/音频消息的标题
     */
    private String Title;

    /**
     * 视频/音频消息的描述
     */
    private String Description;

    /**
     * 图文消息:图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200
     */
    private String PicUrl;

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

3.2 接收及回复文本信息

定义接收文本消息实体类:TextMessage

@EqualsAndHashCode(callSuper = true)
@Data
public class TextMessage extends BaseInfo {
    /**
     * 接收用户发送的文字消息
     */
    private String Content;
}

定义回复文本消息实体类:TextResult

@EqualsAndHashCode(callSuper = true)
@Data
public class TextResult extends BaseResult {
    /**
     * 回复的消息内容
     */
    private String Content;
}

接收消息示例:

@Service
@Slf4j
public class MessageService {
    public String receiveAndResponseMessage(HttpServletRequest request) {
            // 调用消息工具类MessageUtil解析微信发来的xml格式的消息,解析的结果放在HashMap里;
            Map<String, String> map = WeixinMessageUtil.xmlToMap(request);
            String jsonString = JSON.toJSONString(map);
            TextMessage message = JSON.parseObject(jsonString, TextMessage.class);
            log.info("接收的文本信息:{}", message.getContent());
            // 返回消息
            return BuildResponseMessageUtil.buildTextMessage(toUserName, fromUserName, "这是一个普通消息"); 
    }
}

回复消息示例:

public class BuildResponseMessageUtil {
    /**
     * 文本消息
     *
     * @param fromUserName
     * @param toUserName
     * @param content
     * @return
     */
    public static String buildTextMessage(String fromUserName, String toUserName, String content) {
        BaseResult baseResult = getBaseResult(fromUserName, toUserName, MessageType.RESP_MESSAGE_TYPE_TEXT);
        TextResult resultMessage = new TextResult();
        BeanUtils.copyProperties(baseResult, resultMessage);
        resultMessage.setContent(content);
        return WeixinMessageUtil.obj2Xml(resultMessage);
    }
}

3.4 接收及回复图文信息

定义接收图片消息实体类:ImageMessage

@EqualsAndHashCode(callSuper = true)
@Data
public class ImageMessage extends BaseInfo {
    /**
     * 图片链接
     */
    private String PicUrl;

    /**
     * 图片消息媒体id,可以调用获取临时素材接口拉取数据。
     */
    private String MediaId;
}

定义回复图片消息实体类:ImageResult

@EqualsAndHashCode(callSuper = true)
@Data
public class ImageResult extends BaseResult {
    /**
     * 回复的图片
     */
    private MultimediaResult Image;

    public void setMediaId(String MediaId) {
        Image = new MultimediaResult(MediaId, null, null,null,null);
    }
}

定义回复图文消息实体类:ImageNewsResult、ImageNewsArticles

@Data
public class ImageNewsArticles {
    /**
     * 回复的图文
     */
    private MultimediaResult item;

    public void setMediaId(String Title, String Description, String PicUrl, String Url) {
        item = new MultimediaResult(null, Title, Description, PicUrl, Url);
    }
}
@EqualsAndHashCode(callSuper = true)
@Data
public class ImageNewsResult extends BaseResult {

    ImageNewsArticles Articles;

    String ArticleCount;
}

接收消息示例:

@Service
@Slf4j
public class MessageService {
    public String receiveAndResponseMessage(HttpServletRequest request) {
            // 调用消息工具类MessageUtil解析微信发来的xml格式的消息,解析的结果放在HashMap里;
            Map<String, String> map = WeixinMessageUtil.xmlToMap(request);
            String jsonString = JSON.toJSONString(map);
            ImageMessage message = JSON.parseObject(jsonString, ImageMessage.class);
            log.info("接收的图片信息:{}", message.getPicUrl());
            // 回复图片
			return BuildResponseMessageUtil.buildImageMessage(toUserName, fromUserName, message.getMediaId());
            // 回复图文
            // return BuildResponseMessageUtil.buildNewsMessage(toUserName, fromUserName, "图片标题", "图片描述", message.getPicUrl(), "http://www.baidu.com");
    }
}

回复消息示例:

public class BuildResponseMessageUtil {
    /**
     * 图片消息
     *
     * @param fromUserName
     * @param toUserName
     * @param mediaId
     * @return
     */
    public static String buildImageMessage(String fromUserName, String toUserName, String mediaId) {
        BaseResult baseResult = getBaseResult(fromUserName, toUserName, MessageType.RESP_MESSAGE_TYPE_IMAGE);
        ImageResult resultMessage = new ImageResult();
        BeanUtils.copyProperties(baseResult, resultMessage);
        resultMessage.setMediaId(mediaId);
        return WeixinMessageUtil.obj2Xml(resultMessage);
    }

    /**
     * 图文消息
     *
     * @param fromUserName
     * @param toUserName
     * @param Title
     * @param Description
     * @param PicUrl
     * @param Url
     * @return
     */
    public static String buildNewsMessage(String fromUserName, String toUserName, String Title, String Description, String PicUrl, String Url) {
        BaseResult baseResult = getBaseResult(fromUserName, toUserName, MessageType.RESP_MESSAGE_TYPE_NEWS);
        ImageNewsArticles articles = new ImageNewsArticles();
        ImageNewsResult resultMessage = new ImageNewsResult();
        BeanUtils.copyProperties(baseResult, resultMessage);
        articles.setMediaId(Title, Description, PicUrl, Url);
        resultMessage.setArticleCount("1");
        resultMessage.setArticles(articles);
        return WeixinMessageUtil.obj2Xml(resultMessage);
    }
}

3.5 接收及回复语音信息

定义接收语音消息实体类:VoiceMessage

@EqualsAndHashCode(callSuper = true)
@Data
public class VoiceMessage extends BaseInfo {
    /**
     * 语音格式,如amr,speex等
     */
    private String Format;

    /**
     * 图片消息媒体id,可以调用获取临时素材接口拉取数据。
     */
    private String MediaId;

    /**
     * 语言识别结果
     */
    private String Recognition;
}

定义回复语音消息实体类:VoiceResult

@EqualsAndHashCode(callSuper = true)
@Data
public class VoiceResult extends BaseResult {
    /**
     * 语音
     */
    private MultimediaResult Voice;

    public void setMediaId(String MediaId) {
        Voice = new MultimediaResult(MediaId, null, null, null, null);
    }
}

接收消息示例:

@Service
@Slf4j
public class MessageService {
    public String receiveAndResponseMessage(HttpServletRequest request) {
            // 调用消息工具类MessageUtil解析微信发来的xml格式的消息,解析的结果放在HashMap里;
            Map<String, String> map = WeixinMessageUtil.xmlToMap(request);
            String jsonString = JSON.toJSONString(map);
            VoiceMessage message = JSON.parseObject(jsonString, VoiceMessage.class);
            log.info("接收的语音信息:{}", message.getMediaId());
            // 返回消息
            return BuildResponseMessageUtil.buildVoiceMessage(toUserName, fromUserName, message.getMediaId());
    }
}

回复消息示例:

public class BuildResponseMessageUtil {
    /**
     * 语音消息
     *
     * @param fromUserName
     * @param toUserName
     * @param mediaId
     * @return
     */
    public static String buildVoiceMessage(String fromUserName, String toUserName, String mediaId) {
        BaseResult baseResult = getBaseResult(fromUserName, toUserName, MessageType.RESP_MESSAGE_TYPE_VOICE);
        VoiceResult resultMessage = new VoiceResult();
        BeanUtils.copyProperties(baseResult, resultMessage);
        resultMessage.setMediaId(mediaId);
        return WeixinMessageUtil.obj2Xml(resultMessage);
    }
}

3.6 接收及回复视频/小视频信息

定义接收视频/小视频消息实体类:VideoMessage

@EqualsAndHashCode(callSuper = true)
@Data
public class VideoMessage extends BaseInfo {
    /**
     * 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
     */
    private String ThumbMediaId;

    /**
     * 视频消息媒体id,可以调用获取临时素材接口拉取数据。
     */
    private String MediaId;
}

定义回复视频/小视频消息实体类:VideoResult

@EqualsAndHashCode(callSuper = true)
@Data
public class VideoResult extends BaseResult {
    /**
     * 回复视频
     */
    private MultimediaResult Video;

    public void setMediaId(String MediaId, String Title, String Description) {
        Video = new MultimediaResult(MediaId, Title, Description, null, null);
    }
}

接收消息示例:

@Service
@Slf4j
public class MessageService {
    public String receiveAndResponseMessage(HttpServletRequest request) {
            // 调用消息工具类MessageUtil解析微信发来的xml格式的消息,解析的结果放在HashMap里;
            Map<String, String> map = WeixinMessageUtil.xmlToMap(request);
            String jsonString = JSON.toJSONString(map);
            VideoMessage message = JSON.parseObject(jsonString, VideoMessage.class);
            log.info("接收的视频信息:{}", message.getMediaId());
            // 返回消息
            return BuildResponseMessageUtil.buildVideoMessage(toUserName, fromUserName, message.getMediaId(), "视频标题", "视频描述");
    }
}

回复消息示例:

public class BuildResponseMessageUtil {
    /**
     * 视频消息
     *
     * @param fromUserName
     * @param toUserName
     * @param mediaId
     * @param title
     * @param description
     * @return
     */
    public static String buildVideoMessage(String fromUserName, String toUserName, String mediaId, String title, String description) {
        BaseResult baseResult = getBaseResult(fromUserName, toUserName, MessageType.RESP_MESSAGE_TYPE_VIDEO);
        VideoResult resultMessage = new VideoResult();
        BeanUtils.copyProperties(baseResult, resultMessage);
        resultMessage.setMediaId(mediaId, title, description);
        return WeixinMessageUtil.obj2Xml(resultMessage);
    }
}

3.7 接收链接信息

定义接收链接消息实体类:TextMessage

@EqualsAndHashCode(callSuper = true)
@Data
public class LinkMessage extends BaseInfo {
    /**
     * 消息标题
     */
    private String Title;

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

    /**
     * 消息链接
     */
    private String Url;
}

接收消息示例:

@Service
@Slf4j
public class MessageService {
    public String receiveAndResponseMessage(HttpServletRequest request) {
            // 调用消息工具类MessageUtil解析微信发来的xml格式的消息,解析的结果放在HashMap里;
            Map<String, String> map = WeixinMessageUtil.xmlToMap(request);
            String jsonString = JSON.toJSONString(map);
            LinkMessage message = JSON.parseObject(jsonString, LinkMessage.class);
            log.info("接收的链接信息:{}", message.getUrl());
    }
}

3.8 接收位置信息

定义接收位置消息实体类:LocationMessage

@EqualsAndHashCode(callSuper = true)
@Data
public class LocationMessage extends BaseInfo {
    /**
     * 地理位置维度
     */
    private String Location_X;

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

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

    /**
     * 地理位置信息(具体位置)
     */
    private String Label;
}

接收消息示例:

@Service
@Slf4j
public class MessageService {
    public String receiveAndResponseMessage(HttpServletRequest request) {
            // 调用消息工具类MessageUtil解析微信发来的xml格式的消息,解析的结果放在HashMap里;
            Map<String, String> map = WeixinMessageUtil.xmlToMap(request);
            String jsonString = JSON.toJSONString(map);
           LocationMessage message = JSON.parseObject(jsonString, LocationMessage.class);
		   log.info("接收的地理位置信息:{}", message.getLabel());
}

4、完整示例代码

Controller:

@Slf4j
@Controller
public class MessageController {
    /**
     * 接收微信消息(普通消息+事件消息)以及自动回复对应类型消息
     *
     * @param request
     * @param response
     * @throws Exception
     */
    @PostMapping(value = "/message")
    @ApiOperation(value = "接收微信消息(普通消息+事件消息)以及自动回复对应类型消息", notes = "接收微信消息(普通消息+事件消息)以及自动回复对应类型消息")
    public void receiveAndResponseMessage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        log.info("----------------开始处理微信发过来的消息------------------");
        // 微信服务器POST消息时用的是UTF-8编码,在接收时也要用同样的编码,否则中文会乱码;
        request.setCharacterEncoding("UTF-8");
        // 在响应消息(回复消息给用户)时,也将编码方式设置为UTF-8,原理同上;
        response.setCharacterEncoding("UTF-8");
        //如果有消息回复会返回消息的XML
        String message = messageService.receiveAndResponseMessage(request);
        responseMessage(message, response);
    }

    /**
     * 验证微信消息
     *
     * @param request
     * @param response
     * @throws Exception
     */
    @GetMapping(value = "/message")
    @ApiOperation(value = "验证微信消息", notes = "验证微信消息")
    public void getWeiXinMessage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        log.info("----------------验证微信发过来的消息------------------");
        // 签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串,返回给微信客户端
        String message = request.getParameter("echostr");
        log.info("##### 微信服务器签名 :{} #####", signature);
        log.info("##### 微信服务器随机串 :{} #####", nonce);

        responseMessage(message, response);
    }

    private void responseMessage(String message, HttpServletResponse response) {
        try (PrintWriter out = response.getWriter()) {
            if (message != null) {
                log.info("----------------自定义响应------------------");
                out.write(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Service:

@Service
@Slf4j
public class MessageService {
    public String receiveAndResponseMessage(HttpServletRequest request) {
        log.info("------------微信消息开始处理-------------");
        try {
            // 调用消息工具类MessageUtil解析微信发来的xml格式的消息,解析的结果放在HashMap里;
            Map<String, String> map = WeixinMessageUtil.xmlToMap(request);
            String jsonString = JSON.toJSONString(map);

            // 发送方账号(用户方)
            String fromUserName = map.get("FromUserName");
            // 接受方账号(公众号)	
            String toUserName = map.get("ToUserName");
            // 消息类型
            String msgType = map.get("MsgType");
            log.info("fromUserName is:" + fromUserName + " toUserName is:" + toUserName + " msgType is:" + msgType);

            //普通消息类型
            switch (msgType) {
                case MessageType.REQ_MESSAGE_TYPE_TEXT: {
                    TextMessage message = JSON.parseObject(jsonString, TextMessage.class);
                    log.info("接收的文本信息:{}", message.getContent());
                    // 返回消息
                    return BuildResponseMessageUtil.buildTextMessage(toUserName, fromUserName, "这是一个普通消息");
                }
                case MessageType.REQ_MESSAGE_TYPE_IMAGE: {
                    ImageMessage message = JSON.parseObject(jsonString, ImageMessage.class);
                    log.info("接收的图片信息:{}", message.getPicUrl());
                    // 返回消息
                    imageType++;
                    if (imageType % 2 == 0) {
                        return BuildResponseMessageUtil.buildImageMessage(toUserName, fromUserName, message.getMediaId());
                    } else {
                        return BuildResponseMessageUtil.buildNewsMessage(toUserName, fromUserName, "图片标题", "图片描述", message.getPicUrl(), "http://www.baidu.com");
                    }
                }
                case MessageType.REQ_MESSAGE_TYPE_VOICE: {
                    VoiceMessage message = JSON.parseObject(jsonString, VoiceMessage.class);
                    log.info("接收的语音信息:{}", message.getMediaId());
                    // 返回消息
                    return BuildResponseMessageUtil.buildVoiceMessage(toUserName, fromUserName, message.getMediaId());
                }
                case MessageType.REQ_MESSAGE_TYPE_VIDEO: {
                    VideoMessage message = JSON.parseObject(jsonString, VideoMessage.class);
                    log.info("接收的视频信息:{}", message.getMediaId());
                    // 返回消息
                    return BuildResponseMessageUtil.buildVideoMessage(toUserName, fromUserName, message.getMediaId(), "视频标题", "视频描述");
                }
                case MessageType.REQ_MESSAGE_TYPE_SHORTVIDEO: {
                    ShortVideoMessage message = JSON.parseObject(jsonString, ShortVideoMessage.class);
                    log.info("接收的小视频信息:{}", message.getMediaId());
                    // 返回消息
                    return BuildResponseMessageUtil.buildVideoMessage(toUserName, fromUserName, message.getMediaId(), "视频标题", "视频描述");
                }
                case MessageType.REQ_MESSAGE_TYPE_LINK: {
                    LinkMessage message = JSON.parseObject(jsonString, LinkMessage.class);
                    log.info("接收的链接信息:{}", message.getUrl());
                    // 返回消息
                    return BuildResponseMessageUtil.buildTextMessage(toUserName, fromUserName, "这是一个链接消息");
                }
                // 用户主动发送地理位置消息(根据地图位置)
                case MessageType.REQ_MESSAGE_TYPE_LOCATION: {
                    LocationMessage message = JSON.parseObject(jsonString, LocationMessage.class);

                    log.info("接收的地理位置信息:{}", message.getLabel());
                    // 返回消息
                    return BuildResponseMessageUtil.buildTextMessage(toUserName, fromUserName, "这是一个地理位置消息");
                }
                // 事件推送
                case MessageType.REQ_MESSAGE_TYPE_EVENT:
                    // 事件类型
                    String eventType = map.get("Event");
                    log.info("消息事件推送类型:" + eventType);
                    // 用户同意上报地理位置后,用户在关注后进入公众号会话时,会弹框让用户确认是否允许公众号使用其地理位置
                    // 弹框只在关注后出现一次,用户以后可以在公众号详情页面进行操作
                    // 每次进入公众号会话时,都会在进入时上报地理位置
                    // 在进入会话后每5秒上报一次地理位置,即使在公众号里面打开其他网页也会上报位置
                    if (eventType.equals(MessageType.EVENT_TYPE_LOCATION)) {
                        log.info("上报地理位置");
                        String lng = message.getLongitude();
                        String lat = message.getLatitude();
                        return null;
                    }
                    // 关注处理
                    else if (eventType.equals(MessageType.EVENT_TYPE_SUBSCRIBE)) {
                        BaseEvent message = JSON.parseObject(jsonString, BaseEvent.class);
                        log.info("关注成功 {}", message);
                    }
                    // 取消关注
                    else if (eventType.equals(MessageType.EVENT_TYPE_UNSUBSCRIBE)) {
                        BaseEvent message = JSON.parseObject(jsonString, BaseEvent.class);
                        log.info("取消关注,删除用户消息。{}", message.getFromUserName());
                    }
                default:
                    return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("系统出错");
            return null;
        }
    }
}

BuildResponseMessageUtil:

public class BuildResponseMessageUtil {

    private static BaseResult getBaseResult(String fromUserName, String toUserName, String msgType) {
        BaseResult baseResult = new BaseResult();
        baseResult.setCreateTime(System.currentTimeMillis());
        // 微信回复消息时,toUserName就是用户方(接收时的fromUserName),fromUserName为当前公众号账户(接收时的toUserName)
        baseResult.setToUserName(toUserName);
        baseResult.setFromUserName(fromUserName);
        baseResult.setMsgType(msgType);
        return baseResult;
    }

    /**
     * 文本消息
     *
     * @param fromUserName
     * @param toUserName
     * @param content
     * @return
     */
    public static String buildTextMessage(String fromUserName, String toUserName, String content) {
        BaseResult baseResult = getBaseResult(fromUserName, toUserName, MessageType.RESP_MESSAGE_TYPE_TEXT);
        TextResult resultMessage = new TextResult();
        BeanUtils.copyProperties(baseResult, resultMessage);
        resultMessage.setContent(content);
        return WeixinMessageUtil.obj2Xml(resultMessage);
    }

    /**
     * 图片消息
     *
     * @param fromUserName
     * @param toUserName
     * @param mediaId
     * @return
     */
    public static String buildImageMessage(String fromUserName, String toUserName, String mediaId) {
        BaseResult baseResult = getBaseResult(fromUserName, toUserName, MessageType.RESP_MESSAGE_TYPE_IMAGE);
        ImageResult resultMessage = new ImageResult();
        BeanUtils.copyProperties(baseResult, resultMessage);
        resultMessage.setMediaId(mediaId);
        return WeixinMessageUtil.obj2Xml(resultMessage);
    }

    /**
     * 图文消息
     *
     * @param fromUserName
     * @param toUserName
     * @param Title
     * @param Description
     * @param PicUrl
     * @param Url
     * @return
     */
    public static String buildNewsMessage(String fromUserName, String toUserName, String Title, String Description, String PicUrl, String Url) {
        BaseResult baseResult = getBaseResult(fromUserName, toUserName, MessageType.RESP_MESSAGE_TYPE_NEWS);
        ImageNewsArticles articles = new ImageNewsArticles();
        ImageNewsResult resultMessage = new ImageNewsResult();
        BeanUtils.copyProperties(baseResult, resultMessage);
        articles.setMediaId(Title, Description, PicUrl, Url);
        resultMessage.setArticleCount("1");
        resultMessage.setArticles(articles);
        return WeixinMessageUtil.obj2Xml(resultMessage);
    }

    /**
     * 语音消息
     *
     * @param fromUserName
     * @param toUserName
     * @param mediaId
     * @return
     */
    public static String buildVoiceMessage(String fromUserName, String toUserName, String mediaId) {
        BaseResult baseResult = getBaseResult(fromUserName, toUserName, MessageType.RESP_MESSAGE_TYPE_VOICE);
        VoiceResult resultMessage = new VoiceResult();
        BeanUtils.copyProperties(baseResult, resultMessage);
        resultMessage.setMediaId(mediaId);
        return WeixinMessageUtil.obj2Xml(resultMessage);
    }

    /**
     * 视频消息
     *
     * @param fromUserName
     * @param toUserName
     * @param mediaId
     * @param title
     * @param description
     * @return
     */
    public static String buildVideoMessage(String fromUserName, String toUserName, String mediaId, String title, String description) {
        BaseResult baseResult = getBaseResult(fromUserName, toUserName, MessageType.RESP_MESSAGE_TYPE_VIDEO);
        VideoResult resultMessage = new VideoResult();
        BeanUtils.copyProperties(baseResult, resultMessage);
        resultMessage.setMediaId(mediaId, title, description);
        return WeixinMessageUtil.obj2Xml(resultMessage);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/82117.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

推动MRO工业品数字化基建升级,数商云采购系统赋能企业采购数字化管理

MRO工业品是工业生产中的重要组成部分&#xff0c;经历了十余年的发展成长&#xff0c;市场规模持续增长&#xff0c;然而据数据显示&#xff0c;MRO工业品市场的线上渗透率仍停留在个位数&#xff0c;这意味着MRO工业品数字化采购仍有巨大的发展空间。 MRO工业品行业发展受困…

非零基础自学Golang 第1章 走进Go 1.1 Go编程语言概述 1.1.1 Go 的历史

非零基础自学Golang 文章目录非零基础自学Golang第1章 走进Go1.1 Go编程语言概述1.1.1 Go 的历史第1章 走进Go 1.1 Go编程语言概述 Go语言也叫Golang&#xff0c;是由谷歌&#xff08;Google&#xff09;公司在2007年推出的一款静态编译型语言。Go语言高效、简洁、容易上手&a…

上海诺基亚贝尔-S-010W-AV2B卡刷固件包

上海诺基亚贝尔-S-010W-AV2B卡刷固件包 固件特点&#xff1a; 1、修改dns&#xff0c;三网通用&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、无开机广告&#xff0c;无系统更新&#xff0c;不在被强制升级&#xff1b; 4、大量精简内置的没用的…

最新版Crack:MailBee.NET 2022最后版

MailBee.NET Items Package 包括 SMTP、POP3、IMAP、EWS、Security、Antispam、Outlook Converter、Address Validator、PDF 部件&#xff0c;以及作为免费功能的 BounceMail、HTML、MIME、ICalVCard 部件。MailBee.NET Objects是一组功能强大且功能丰富的 .NET 元素&#xff0…

基于nodejs如何爬取csdn上自己的文章

当你想把自己在csdn上写的文章转为hexo上可以发布的文章或是将文章写入自己的数据库时,可以用到 将所有博客数据写入数据库 获取你的文章的分页接口: 在浏览自己的所有文章时,我们不难发现,文章的数据是往下滑动到底时,才会刷新出新的数据, 那么此时肯定是发送了一个请求来获…

一篇文章教你实战Docker容器数据卷

在上一篇中&#xff0c;咱们对Docker中的容器数据卷做了介绍。已经知道了容器数据卷是什么&#xff1f;能干什么用。那么本篇咱们就来实战容器数据卷&#xff0c;Docker容器数据卷案例主要做以下三个案例 1&#xff1a;宿主机(也就是Docker所安装的机器)与容器之间的映射-让Do…

LeetCode 538. 把二叉搜索树转换为累加树(C++)

标签&#xff1a;二叉树搜索 深度优先遍历 二叉树 思路一&#xff1a;递归实现反向中序遍历&#xff0c;并累加递归过程中的根的值 思路二&#xff1a;使用迭代&#xff0c;给每个根节点添加一个反向中序遍历的前驱节点。 原题链接&#xff1a;https://leetcode.cn/problems/co…

数据分析业务场景 | CTR预估

一.概况 定义 是推荐中最核心的算法之一 对每次广告的点击情况做出预测&#xff0c;预测用户是点击还是不点击 就是预测点击与否的而分类算法&#xff0c;成功的关键之一就是样本的准确性 对于正样本&#xff0c;一般可发挥的空间不是很大&#xff0c;最多就是卡一个停留时…

LinkedList源码解析

LinkedList源码解析 简介 LinkedList 是一个双向链表&#xff08;内部是 Node 节点&#xff09;实现的 List&#xff0c;并且还实现了 Deque 接口&#xff0c;它除了作为 List 使用&#xff0c;还可以作为队列或者栈来使用。 这样看来&#xff0c;LinkedList 简直就是个全能…

【文字版】津津有味:感染新冠后没食欲,那咱也得吃饭啊!

点击文末“阅读原文”即可收听本期节目剪辑、音频 / 朱峰 编辑 / 姝琦 SandLiu监制 / 姝琦 文案 / 粒粒 产品统筹 / bobo你阳了吗&#xff1f;你嗓子疼吗&#xff1f;你的食欲还好吗&#xff1f;没有什么比好好吃饭更重要&#xff0c;生病的时候尤其是。营养对健康而言是预防…

浏览器上的Cookies有什么用?超级浏览器防关联如何实现?

Cookies是浏览器的指纹信息之一&#xff0c;它是一种文本文件&#xff0c;是网站为了辨别用户身份&#xff0c;对用户进行记录并由户客户端计算机进行暂时或永久保存的信息。一般情况下&#xff0c;网站对浏览器的指纹的记录主要是依靠Cookies来实现的。因为超级浏览器来可以生…

[附源码]JAVA毕业设计英语网站(系统+LW)

[附源码]JAVA毕业设计英语网站&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xf…

[附源码]Python计算机毕业设计大学生健康系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

c#和Python交互,完美解决Python调用OpenCV等第三方库以及分发时需配置python环境的问题

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、问题分析二、解决方案第一个问题第二个问题三、结果及源码四、总结前言 关于C#如何调用Python&#xff0c;网上提供了很多解决方案&#xff0c;有用ironPyt…

react组件深度解读

五、React 核心是组件 在 React 中&#xff0c;我们使用组件&#xff08;有状态、可组合、可重用&#xff09;来描述 UI 。 在任何编程语言中&#xff0c;你都可以将组件视为简单的函数。 React 组件也一样&#xff0c; 它的输入是 props&#xff0c;输出是关于 UI 的描述。我…

Win11 WSL Linux子系统安装与注销 配置conda环境 启动jupyter

1 前言 本篇博客讲解如何在Windows11系统中安装与注销Linux子系统&#xff0c;并配置conda环境、jupyter环境&#xff0c;实现在Local浏览器启动jupyter并运行项目。 2 安装Linux子系统&#xff08;参考文章[1]&#xff09; 1.1 WSL 在任务栏中的搜索功能中&#xff0c;搜索…

合并多文件后分组再结构化

【问题】 Heres the problem statement: In a folder in HDFS, therere a few csv files with each row being a record with the schema (ID, attribute1, attribute2, attribute3). Some of the columns (except ID) could be null or empty strings, and no 2 records wi…

汇编语言常用DOS功能调用示例

1.利用DOS功能调用输出响铃&#xff08;响铃的ASCII码为07H&#xff09;。建立源程序文件HELLO.ASM&#xff0c;通过汇编程序得到目标文件RING.OBJ以及列表文件RING.LST&#xff0c;通过连接程序得到可执行文件性文件 RING.EXE。对可执行性文件进行调试。 &#xff08;1&…

【数据结构】——栈和队列

目录 1.栈 1.1栈的概念及结构 1.2栈的实现 1.2.1具体实现 Stack.h 栈初始化 栈销毁 入栈 出栈 取栈顶数据 判空 栈中有效元素的个数 全部Stack.c的代码 测试Test.c代码 2.队列 2.1队列的概念及结构 2.2队列的实现 Queue.h 队列初始化 队列销毁 队尾入队列…

Tomcat8.0使用tomcat-redis-session-manager共享session【开源】,tomcat实现session共享

前言 【可跳过&#xff0c;比较简单】 由于以前的项目配置了多个tomcat服务使用了nginx代理&#xff0c;但是关闭某个tomcat的时候登录用户信息丢失&#xff0c;用户得重新登录&#xff0c;这就让人体验不好了&#xff1b;我们可以复制各个tomcat服务的session来实现的sessio…