Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装
在前面几篇文章我们讲了微信公众号环境的配置 和微信公众号服务的接入,接下来我们来说一下微信服务器请求消息,响应消息以及事件消息的相关内容,首先我们来分析一下消息类型和返回xml格式及实体类的封装。
(一)封装请求信息
首先打开微信提供的开发者文档:http://mp.weixin.qq.com/wiki/home/ ,点击左侧的“消息管理”----“接收普通消息”,在右侧我们可以看到微信普通消息类型大致有:文本消息、图片消息、语音消息、视频消息、小视频消息、地理位置消息、链接消息;通过查看开发者文档,我们可以发现消息类型的格式为xml,以文本消息为例:
<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>
当我们接收消息的时候,微信将向我们发送Post请求,并以XML的格式发送与接收数据。那么此时我们就需要一个工具类来处理XML格式的文件:MessageType.parseXml()
package com.webchat.util.weixin; import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;
import com.webchat.entity.PageData; public class MessageType {
/*
* 文本消息
*/
public static final String TEXT_MESSAGE = "text";
/*
* 图片消息
*/
public static final String IMAGE_MESSAGE = "image";
/*
* 语音消息
*/
public static final String VOICE_MESSAGE = "voice";
/*
* 视频消息
*/
public static final String VIDEO_MESSAGE = "video";
/*
* 小视频消息消息
*/
public static final String SHORTVIDEO_MESSAGE = "shortvideo";
/*
* 地理位置消息
*/
public static final String POSOTION_MESSAGE = "location";
/*
* 链接消息
*/
public static final String LINK_MESSAGE = "link";
/*
* 音乐消息
*/
public static final String MUSIC_MESSAGE = "music";
/*
* 图文消息
*/
public static final String IMAGE_TEXT_MESSAGE = "news";
/*
* 请求消息类型:事件推送
*/
public static final String REQ_MESSAGE_TYPE_EVENT = "event";
/*
* 事件类型:subscribe(订阅)
*/
public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
/*
* 事件类型:unsubscribe(取消订阅)
*/
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"; /*
* 响应消息类型:文本
*/
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_VIDEO = "video";
/*
* 响应消息类型:音乐
*/
public static final String RESP_MESSAGE_TYPE_MUSIC = "music";
/*
* 响应消息类型:图文
*/
public static final String RESP_MESSAGE_TYPE_NEWS = "news"; /**
* @Title parseXml
* @Description 将用户的xml消息提取成map key value 类型
* @param request
* @param response
* @return
* @throws Exception
*/
public static Map<String, String> parseXml(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 将解析结果存储在HashMap中
Map<String, String> map = new HashMap<String, String>();
// 从request中取得输入流
InputStream inputStream = request.getInputStream();
// 读取输入流
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
// 得到xml根元素
Element root = document.getRootElement();
// 得到根元素的所有子节点
List<Element> elementList = root.elements();
// 遍历所有子节点
for (Element e : elementList) {
map.put(e.getName(), e.getText());
}
// 释放资源
inputStream.close();
inputStream = null;
return map;
}
}
通过对开发文档的分析我们可以发现这些消息类型中,都会传回来这些公共的字段如:
ToUserName(开发者微信号);
FromUserName(发送方帐 号,OPEN_ID);
CreateTime(消息的创建时间);
MsgType(消息类型);
MsgId(消息ID)。
我们把这些封装成一个基类,然后 不同的部分,分别封装为各自的类然后继承这个基类,提高代码的重用性。
(一)消息实体基础类 -- BaseMessage
package com.webchat.entity.message; /**
* 请求消息的公共字段类
*
* @author Administrator
*
*/
public abstract class BaseMessage {
// 开发者微信号
private String ToUserName;
// 发送方帐号(一个OpenID)
private String FromUserName;
// 消息创建时间 (整型)
private long CreateTime;
// 消息id,64位整型
private long MsgId;
/**
* 获取 消息类型
*
* @return 消息类型
*/
public abstract String getMsgType(); 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 long getMsgId() {
return MsgId;
} public void setMsgId(long msgId) {
MsgId = msgId;
}
}
(二)普通消息类
1,文本消息
package com.webchat.entity.message; import com.webchat.util.weixin.MessageType; /**
* 文本消息
* @author Administrator
*
*/
public class TextMessage extends BaseMessage {
//文本消息内容
private String Content; public String getContent() {
return Content;
} public void setContent(String content) {
Content = content;
} @Override
public String getMsgType() {
return MessageType.TEXT_MESSAGE.toString();
} }
2,图片消息
package com.webchat.entity.message; import com.webchat.util.weixin.MessageType;
/**
* 图片消息
* @author Administrator
*
*/
public class ImageMessage extends BaseMessage{
// 图片链接
private String PicUrl;
//图片消息媒体id,可以调用多媒体文件下载接口拉取数据。
private String MediaId; public String getPicUrl() {
return PicUrl;
} public void setPicUrl(String picUrl) {
PicUrl = picUrl;
} public String getMediaId() {
return MediaId;
} public void setMediaId(String mediaId) {
MediaId = mediaId;
} @Override
public String getMsgType() {
return MessageType.IMAGE_MESSAGE.toString();
} }
3,语音消息
package com.webchat.entity.message; import com.webchat.util.weixin.MessageType; /**
* 语音消息
*
* @author Administrator
*
*/
public class VoiceMessage extends BaseMessage {
// 语音消息媒体id,可以调用多媒体文件下载接口拉取数据。
private String MediaId;
// 语音格式,如amr,speex等
private String Format;
// 语音识别结果,使用UTF8编码
private String Recognition; public String getMediaId() {
return MediaId;
} public void setMediaId(String mediaId) {
MediaId = mediaId;
} public String getFormat() {
return Format;
} public void setFormat(String format) {
Format = format;
} public String getRecognition() {
return Recognition;
} public void setRecognition(String recognition) {
Recognition = recognition;
} @Override
public String getMsgType() {
return MessageType.VOICE_MESSAGE.toString();
} }
4,视频消息
package com.webchat.entity.message; import com.webchat.util.weixin.MessageType;
/**
* 视频消息
* @author Administrator
*
*/
public class VideoMessage extends BaseMessage {
// 视频消息媒体id,可以调用多媒体文件下载接口拉取数据。
private String MediaId;
// 视频消息 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
private String ThumbMediaId; public String getMediaId() {
return MediaId;
} public void setMediaId(String mediaId) {
MediaId = mediaId;
} public String getThumbMediaId() {
return ThumbMediaId;
} public void setThumbMediaId(String thumbMediaId) {
ThumbMediaId = thumbMediaId;
} @Override
public String getMsgType() {
return MessageType.VIDEO_MESSAGE.toString();
} }
5,小视频消息
package com.webchat.entity.message; import com.webchat.util.weixin.MessageType;
/**
* 小视频消息
* @author Administrator
*
*/
public class ShortVideoInputMessage extends BaseMessage {
// 视频消息媒体id,可以调用多媒体文件下载接口拉取数据。
private String MediaId;
// 视频消息 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
private String ThumbMediaId; public String getMediaId() {
return MediaId;
} public void setMediaId(String mediaId) {
MediaId = mediaId;
} public String getThumbMediaId() {
return ThumbMediaId;
} public void setThumbMediaId(String thumbMediaId) {
ThumbMediaId = thumbMediaId;
} @Override
public String getMsgType() {
return MessageType.SHORTVIDEO_MESSAGE.toString();
}
}
6,地理位置消息
package com.webchat.entity.message; import com.webchat.util.weixin.MessageType; /**
* 地理位置消息
*
* @author Administrator
*
*/
public class LocationMessage extends BaseMessage {
// 地理位置维度
private String Location_X;
// 地理位置经度
private String Location_Y;
// 地图缩放大小
private Long Scale;
// 地理位置信息
private String Label; public String getLocation_X() {
return Location_X;
} public void setLocation_X(String location_X) {
Location_X = location_X;
} public String getLocation_Y() {
return Location_Y;
} public void setLocation_Y(String location_Y) {
Location_Y = location_Y;
} public Long getScale() {
return Scale;
} public void setScale(Long scale) {
Scale = scale;
} public String getLabel() {
return Label;
} public void setLabel(String label) {
Label = label;
} @Override
public String getMsgType() {
return MessageType.POSOTION_MESSAGE.toString();
} }
7,链接消息
package com.webchat.entity.message; import com.webchat.util.weixin.MessageType; /**
* 链接消息
*
* @author Administrator
*
*/
public class LinkMessage extends BaseMessage {
// 消息标题
private String Title;
// 消息描述
private String Description;
// 消息链接
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 getUrl() {
return Url;
} public void setUrl(String url) {
Url = url;
} @Override
public String getMsgType() {
return MessageType.LINK_MESSAGE.toString();
} }
(二)封装事件
点击左侧的“消息管理”----“接收事件推送”,在右侧我们可以看到微信接收事件推送的目录:关注/取消关注事件、扫描带参数二维码事件、上报地理位置事件、自定义菜单事件、点击菜单拉取消息时的事件推送、点击菜单跳转链接时的事件推送;推送XML数据包 和消息文本的类似,详情参考开发者文档
提取公共字段创建基础类
package com.webchat.entity.event; /**
* 事件消息
*
* @author Administrator
*
*/
public abstract class BaseEvent {
// 开发者微信号
private String ToUserName;
// 发送方帐号(一个OpenID)
private String FromUserName;
// 消息创建时间 (整型)
private long CreateTime;
// 消息类型
private String MsgType;
// 事件类型
private String Event; public String getEvent() {
return Event;
} public void setEvent(String event) {
Event = event;
} 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;
}
}
事件封装
1,关注/取消事件
package com.webchat.entity.event;
/**
* 关注取消事件
* @author Administrator
*
*/
public class SubscribeEvent extends BaseEvent{ }
2,扫描参数带二维码事件
package com.webchat.entity.event; /**
* 扫描带参数二维码事件
*
* @author Administrator
*
*/
public class QRCodeEvent extends BaseEvent {
// 事件KEY值
private String EventKey;
// 用于换取二维码图片
private String Ticket; public String getEventKey() {
return EventKey;
} public void setEventKey(String eventKey) {
EventKey = eventKey;
} public String getTicket() {
return Ticket;
} public void setTicket(String ticket) {
Ticket = ticket;
} }
3,上报地理位置事件
package com.webchat.entity.event; /**
* 上报地理位置事件
*
* @author Administrator
*
*/
public class LocationEvent extends BaseEvent {
// 地理位置纬度
private String Latitude;
// 地理位置经度
private String Longitude;
// 地理位置精度
private String Precision; public String getLatitude() {
return Latitude;
} public void setLatitude(String latitude) {
Latitude = latitude;
} public String getLongitude() {
return Longitude;
} public void setLongitude(String longitude) {
Longitude = longitude;
} public String getPrecision() {
return Precision;
} public void setPrecision(String precision) {
Precision = precision;
} }
4,自定义菜单事件
package com.webchat.entity.event; /**
* 自定义菜单事件
* @author Administrator
*
*/
public class MenuEvent extends BaseEvent {
// 事件KEY值,与自定义菜单接口中KEY值对应
private String EventKey; public String getEventKey() {
return EventKey;
} public void setEventKey(String eventKey) {
EventKey = eventKey;
} }
(三)回复消息的分类及实体的封装
点击左侧的“消息管理”----“被动回复用户消息”,当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。严格来说,发送被动响应消息其实并不是一种接口,而是对微信服务器发过来消息的一次回复。
微信服务器在将用户的消息发给公众号的开发者服务器地址(开发者中心处配置)后,微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次,如果在调试中,发现用户无法收到响应的消息,可以检查是否消息处理超时。关于重试的消息排重,有msgid的消息推荐使用msgid排重。事件类型消息推荐使用FromUserName + CreateTime 排重。详情请查看开发者文档
同样,把消息回复中定义的所有消息都有的字段提取出来,封装成一个公共类,
响应消息的基类BaseOutMessage
package com.webchat.entity.output; /**
* 回复消息的公共字段类
*
* @author Administrator
*
*/
public abstract class BaseOutMessage {
// 接收方帐号(收到的OpenID)
private String ToUserName;
// 开发者微信号
private String FromUserName;
// 消息创建时间 (整型)
private long CreateTime; // 获取消息类型
public abstract String getMsgType(); 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;
} }
普通消息回复实体实现
1,回复文本消息
package com.webchat.entity.output; import com.webchat.util.weixin.MessageType; /**
* 文本回复消息
*
* @author Administrator
*
*/
public class TextMessage extends BaseOutMessage {
// 文本消息
private String Content; public String getContent() {
return Content;
} public void setContent(String content) {
Content = content;
} @Override
public String getMsgType() {
return MessageType.RESP_MESSAGE_TYPE_TEXT.toString();
}
}
2,回复图片消息
package com.webchat.entity.output; /**
* 图片回复消息
* @author Administrator
*
*/
public class Image{
//通过上传多媒体文件,得到的id
private String MediaId; public String getMediaId() {
return MediaId;
} public void setMediaId(String mediaId) {
MediaId = mediaId;
}
}
package com.webchat.entity.output; import com.webchat.util.weixin.MessageType;
/**
* 图片输出内容
* @author Administrator
*
*/
public class ImageOutputMessage extends BaseOutMessage{
private Image Image;
public Image getImage() {
return Image;
}
public void setImage(Image image) {
Image = image;
}
@Override
public String getMsgType() {
return MessageType.RESP_MESSAGE_TYPE_IMAGE.toString();
}
}
3,回复语音消息
package com.webchat.entity.output;
/**
* 语音model
* @author Administrator
*
*/
public class Voice {
// 媒体文件id
private String MediaId; public String getMediaId() {
return MediaId;
} public void setMediaId(String mediaId) {
MediaId = mediaId;
} }
package com.webchat.entity.output; import com.webchat.util.weixin.MessageType;
/**
* 语音回复消息
* @author Administrator
*
*/
public class VoiceOutputMessage extends BaseOutMessage{
private Voice voice; public Voice getVoice() {
return voice;
} public void setVoice(Voice voice) {
this.voice = voice;
} @Override
public String getMsgType() {
return MessageType.RESP_MESSAGE_TYPE_VOICE.toString();
}
}
4,回复视频消息
package com.webchat.entity.output;
/**
* 视频model
* @author Administrator
*
*/
public class Video {
// 媒体文件id
private String MediaId;
// 缩略图的媒体id
private String ThumbMediaId;
//视频消息的标题
private String Title;
//视频消息的描述
private String Description;
public String getMediaId() {
return MediaId;
} public void setMediaId(String mediaId) {
MediaId = mediaId;
} public String getThumbMediaId() {
return ThumbMediaId;
} public void setThumbMediaId(String thumbMediaId) {
ThumbMediaId = 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;
} }
package com.webchat.entity.output; import com.webchat.util.weixin.MessageType; /**
* 回复视频消息
*
* @author Administrator
*
*/
public class VideoOutPutMessage extends BaseOutMessage {
private Video Video; public Video getVideo() {
return Video;
} public void setVideo(Video video) {
Video = video;
} @Override
public String getMsgType() {
return MessageType.RESP_MESSAGE_TYPE_VIDEO.toString();
}
}
5,回复音乐消息
package com.webchat.entity.output;
/**
* 回复音乐消息中的音乐对象
* @author Administrator
*
*/
public class Music {
// 音乐标题
private String Title;
// 音乐描述
private String Description;
// 音乐链接
private String MusicUrl;
// 高质量音乐链接,WIFI环境优先使用该链接播放音乐
private String HQMusicUrl;
// 缩略图的媒体id,通过上传多媒体文件得到的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) {
HQMusicUrl = hQMusicUrl;
} public String getThumbMediaId() {
return ThumbMediaId;
} public void setThumbMediaId(String thumbMediaId) {
ThumbMediaId = thumbMediaId;
} }
package com.webchat.entity.output; import com.webchat.util.weixin.MessageType;
/**
* 回复音乐消息
* @author Administrator
*
*/
public class MusicOutputMessage extends BaseOutMessage {
private Music Music; public Music getMusic() {
return Music;
} public void setMusic(Music music) {
Music = music;
} @Override
public String getMsgType() {
return MessageType.RESP_MESSAGE_TYPE_MUSIC.toString();
}
}
6,回复图文消息
package com.webchat.entity.output;
/**
* 图文消息实体类对象
* @author Administrator
*
*/
public class Articles {
private String Title;
// 图文消息描述
private String Description;
// 图片链接,支持JPG、PNG格式,较好的效果为大图640*320,小图80*80
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.webchat.entity.output; import java.util.List;
import com.webchat.util.weixin.MessageType; /**
* 提供了获取多条图文消息信息
*
* @author Administrator
*
*/
public class NewsOutputMessage extends BaseOutMessage {
// 图文消息个数,限制为10条以内
private int ArticleCount;
// 多条图文消息信息,默认第一个item为大图
private List<Articles> Articles; public int getArticleCount() {
return ArticleCount;
} public void setArticleCount(int articleCount) {
ArticleCount = articleCount;
} public List<Articles> getArticles() {
return Articles;
} public void setArticles(List<Articles> articles) {
Articles = articles;
} @Override
public String getMsgType() {
return MessageType.RESP_MESSAGE_TYPE_NEWS.toString();
}
}
至此,我们所有的内容已经封装完成
接下来会更新:微信服务器 post 消息体的接收及消息处理的内容
如果在操作过程中有问题,欢迎随时讨论^.^
百度云链接:https://pan.baidu.com/s/1xQIAl14_9JKJi1BsFe7yvw 密码:ybnv
备注:我的是maven项目,此链接只为分享封装的实体类,如果项目中出现错误,可不用理会,只拿自己想要的东西即可
其他文章关联
(一)Java开发微信公众号(一)---初识微信公众号以及环境搭建
(二)Java开发微信公众号(二)---开启开发者模式,接入微信公众平台开发
(三)Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装
(四)Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理
Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装的更多相关文章
- JAVA版开源微信管家—JeeWx捷微3.2版本发布,支持微信公众号,微信企业号,支付窗、小程序
JeeWx捷微3.2微信企业号升级版本发布^_^ JeeWx捷微V3.2——多触点管理平台(支持微信公众号,微信企业号,支付窗.小程序) JeeWx捷微V3.2.0版本引入了更多新特性,支持微信公 ...
- JeeWx捷微3.1小程序版本发布,支持微信公众号,微信企业号,支付窗——JAVA版开源微信管家
支持小程序,JeeWx捷微3.1小程序版本发布^_^ JeeWx捷微V3.1——多触点小程序版本管理平台(支持微信公众号,微信企业号,支付窗) JeeWx捷微V3.1.0版本紧跟微信小程序更新,在 ...
- JAVA版开源微信管家—JeeWx捷微3.1小程序版本发布,支持微信公众号,微信企业号,支付窗
支持小程序,JeeWx捷微3.1小程序版本发布^_^ JeeWx捷微V3.1--多触点小程序版本管理平台(支持微信公众号,微信企业号,支付窗) JeeWx捷微V3.1.0版本紧跟微信小程序更新,在原有 ...
- JAVA开源微信管家平台——JeeWx捷微V3.3版本发布(支持微信公众号,微信企业号,支付窗)
JeeWx捷微V3.3版本紧跟微信小程序更新,在原有多触点版本基础上,引入了更多的新亮点:支持微信公众号.微信企业号.支付宝服务窗等多触点开发:采用微服务框架实现,可插拔可集成,轻量级开发:对小程序的 ...
- 微信公众号支付|微信H5支付|微信扫码支付|小程序支付|APP微信支付解决方案总结
最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付.APP微信支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存. 先说注意 ...
- C#版微信公众号支付|微信H5支付|微信扫码支付问题汇总及解决方案总结
最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存.代码在文章结尾处,有需要的 ...
- CabloyJS的微信API对接模块:当前支持微信公众号和微信小程序
Cabloy-微信是什么 Cabloy-微信是基于CabloyJS全栈业务开发框架开发的微信接口模块,当前整合了微信公众号和微信小程序的接口,达到开箱即用的使用效果.在Cabloy-微信的基础上,可以 ...
- 使用 nodeJs 开发微信公众号(配置服务器)
流程如下: 1. 申请微信公众号:企业号.服务号.订阅号(前两个要钱) 2. 配置微信公众号后台 选择基本配置,获得 AppId 和 AppSecret ,点击服务器配置 URL:你服务器地址,不能是 ...
- Node.js+Koa开发微信公众号个人笔记(二)响应事件
微信公众号中的事件有订阅事件/扫码事件/点击事件/跳转链接事件等等,具体可以查阅文档. 这里来实现一下订阅事件,其他的事件的实现过程也都类似. 当有人订阅了公众号后,微信服务器会向我们的服务器推送一个 ...
- TP3.2校验微信公众号||小程序 服务器地址
1.在TP3.2里面,写一个控制器,用来校验微信公众号||小程序的服务器地址 <?php namespace Home\Controller; use Think\Controller; hea ...
随机推荐
- jQuery_2_常规选择器-简单选择器
JQuery最核心的组成部分就是:选择器引擎.它继承了css的语法,可以对DOM元素的标签名.属性名.状态等进行快速准确的选择. jQuery选择器的写法与CSS 选择器十分类似,只不过他们的功能不同 ...
- String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getSer
这其实就是 获得应用的根url,比如说你的应用的根路径是 http://localhost:8080,那么你列出的代码就是为basePath赋值为 http://localhost:8080.具体点: ...
- 【洛谷2522】[HAOI2011] Problem b(莫比乌斯反演)
点此看题面 大致题意: 求\(\sum_{x=a}^b\sum_{y=c}^d[gcd(x,y)==k]\). 关于另一道题目 在看这篇博客之前,如果你做过一道叫做[BZOJ1101][POI2007 ...
- tmux 用z关闭之后的恢复
ctrl+b 然后z是全屏 但是如果是ctrl+z就是关闭窗口了 tmux ls看所有窗口 然后 tmux attach -t 2或者3就恢复
- 前端异常日志监控 - 使用Sentry
背景 现在的前端项目越来越复杂,在不同的客户端会产生各种在开发人员机器上不会出现的问题.当用户报告一个问题给开发人员的时候,开发人员无法直接定位问题.在此前,听过一次鹅厂的前端人员,他们对QQ里面的网 ...
- JavaScript 遍历对象查找指定的值并返回路径
问:JavaScript 如何查找对象中某个 value 并返回路径上所有的 key? let obj = { key1: 'str1', key2: { key3: 'str3' }, key4: ...
- Spring+ ApplicationListener
有时候 需要在容器初始化完成后,加载些 代码字典或不常变的信息 放入缓存之类的,这里使用spring 初始化bean,并实例化 1.创建一个ApplicationListener类 import o ...
- XML字符串解析
不多说,直接上代码: import java.io.StringReader; import org.dom4j.Document; import org.dom4j.DocumentExceptio ...
- Shell脚本使用汇总整理——达梦数据库备份脚本
Shell脚本使用汇总整理——达梦数据库备份脚本 Shell脚本使用的基本知识点汇总详情见连接: https://www.cnblogs.com/lsy-blogs/p/9223477.html 脚本 ...
- phpstudy配置SSL证书的步骤(Apache环境)以及一些注意事项
准备工具(我自己的): 腾讯云的域名和云主机,还有SSL证书,以及phpstudy 首先要下载自己的SSL证书,会得到一个压缩包,解压以后会得到四个文件夹和一个csr文件, Apache文件夹内三个文 ...