java微信公眾號(hào)開發(fā)案例
微信公眾號(hào)開發(fā)一般是針對(duì)企業(yè)和組織的,個(gè)人一般只能申請(qǐng)訂閱號(hào),并且調(diào)用的接口有限,下面我們就來簡(jiǎn)單的描述下接入公眾號(hào)的步驟:
1、首先你需要一個(gè)郵箱在微信公眾號(hào)平臺(tái)進(jìn)行注冊(cè);
注冊(cè)的方式有訂閱號(hào)、公眾號(hào)、小程序和企業(yè)號(hào),個(gè)人我們這里只能選擇訂閱號(hào)
2、注冊(cè)完后,我們登錄到公眾號(hào)平臺(tái)--->開發(fā)--->基本配置,這里需要填寫URL和token,URL就是我們使用服務(wù)器的接口;
3、Java Web服務(wù)器程序編譯好且在服務(wù)器上部署可以運(yùn)行的話,可在微信公眾號(hào)進(jìn)行在線接口調(diào)試:
1)、選擇合適的接口
2)、系統(tǒng)會(huì)生成該接口的參數(shù)表,您可以直接在文本框內(nèi)填入對(duì)應(yīng)的參數(shù)值(紅色星號(hào)表示該字段必填)
3)、點(diǎn)擊檢查問題按鈕,即可得到相應(yīng)的調(diào)試信息
eg:獲取access_token的步驟:
1)、接口類型:基礎(chǔ)支持
2)、接口列表:獲取access_token接口/token
3)、填寫相應(yīng)的參數(shù):grant_type、appid、secret
4)、點(diǎn)擊檢查問題
5)、驗(yàn)證成功會(huì)返回結(jié)果和提示,結(jié)果為:200 ok,提示:Request successful即表示驗(yàn)證成功
我們這里驗(yàn)證比較多的是消息接口調(diào)試:文本消息、圖片消息、語音消息、視頻消息、etc
4、接口有不理解的地方,可進(jìn)入開發(fā)-->開發(fā)者工具-->開發(fā)者文檔進(jìn)行查詢
5、接口權(quán)限:訂閱號(hào)主要有基礎(chǔ)支持、接收消息及網(wǎng)頁服務(wù)里面的一些接口
下面我們主要講訂閱號(hào)怎么樣接收消息的案例:
1、需要申請(qǐng)一個(gè)個(gè)人微信訂閱號(hào)
2、url服務(wù)器和服務(wù)器端代碼部署(可以用騰訊云or阿里云服務(wù)器)
1)、AccountsServlet.java類,驗(yàn)證來自微信服務(wù)器和微信服務(wù)器的消息處理
package cn.jon.wechat.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.jon.wechat.service.AccountsService;
import cn.jon.wechat.utils.SignUtil;
public class AccountsServlet extends HttpServlet {
public AccountsServlet() {
super();
}
public void destroy() {
super.destroy();
// Put your code here
}
/**
* 確認(rèn)請(qǐng)求來自于微信服務(wù)器
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("接口測(cè)試開始?。?!");
//微信加密簽名
String signature = request.getParameter("signature");
//時(shí)間戳
String timestamp = request.getParameter("timestamp");
//隨機(jī)數(shù)
String nonce = request.getParameter("nonce");
//隨機(jī)字符串
String echostr = request.getParameter("echostr");
PrintWriter out = response.getWriter();
//通過校驗(yàn)signature對(duì)請(qǐng)求進(jìn)行校驗(yàn),若校驗(yàn)成功則原樣返回echostr,表示接入成功,否則接入失敗
if(SignUtil.checkSignature(signature,timestamp,nonce)){
out.print(echostr);
}
out.close();
out = null;
// response.encodeRedirectURL("success.jsp");
}
/**
* 處理微信服務(wù)器發(fā)來的消息
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//消息的接受、處理、響應(yīng)
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
//調(diào)用核心業(yè)務(wù)類型接受消息、處理消息
String respMessage = AccountsService.processRequest(request);
//響應(yīng)消息
PrintWriter out = response.getWriter();
out.print(respMessage);
out.close();
}
public void init() throws ServletException {
// Put your code here
}
}
2)、SignUtil.java類,請(qǐng)求校驗(yàn)工具類,token需要和微信中填寫的token一致
package cn.jon.wechat.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* 請(qǐng)求校驗(yàn)工具類
* @author jon
*/
public class SignUtil {
//與微信配置中的的Token一致
private static String token = "";
public static boolean checkSignature(String signature, String timestamp,
String nonce) {
String[] arra = new String[]{token,timestamp,nonce};
//將signature,timestamp,nonce組成數(shù)組進(jìn)行字典排序
Arrays.sort(arra);
StringBuilder sb = new StringBuilder();
for(int i=0;i<arra.length;i++){
sb.append(arra[i]);
}
MessageDigest md = null;
String stnStr = null;
try {
md = MessageDigest.getInstance("SHA-1");
byte[] digest = md.digest(sb.toString().getBytes());
stnStr = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//釋放內(nèi)存
sb = null;
//將sha1加密后的字符串與signature對(duì)比,標(biāo)識(shí)該請(qǐng)求來源于微信
return stnStr!=null?stnStr.equals(signature.toUpperCase()):false;
}
/**
* 將字節(jié)數(shù)組轉(zhuǎn)換成十六進(jìn)制字符串
* @param digestArra
* @return
*/
private static String byteToStr(byte[] digestArra) {
// TODO Auto-generated method stub
String digestStr = "";
for(int i=0;i<digestArra.length;i++){
digestStr += byteToHexStr(digestArra[i]);
}
return digestStr;
}
/**
* 將字節(jié)轉(zhuǎn)換成為十六進(jìn)制字符串
*/
private static String byteToHexStr(byte dByte) {
// TODO Auto-generated method stub
char[] Digit = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] tmpArr = new char[2];
tmpArr[0] = Digit[(dByte>>>4)&0X0F];
tmpArr[1] = Digit[dByte&0X0F];
String s = new String(tmpArr);
return s;
}
public static void main(String[] args) {
/*byte dByte = 'A';
System.out.println(byteToHexStr(dByte));*/
Map<String,String> map = new ConcurrentHashMap<String, String>();
map.put("4", "zhangsan");
map.put("100", "lisi");
Set set = map.keySet();
Iterator iter = set.iterator();
while(iter.hasNext()){
// String keyV = (String) iter.next();
String key =(String)iter.next();
System.out.println(map.get(key));
// System.out.println(map.get(iter.next()));
}
/*for(int i=0;i<map.size();i++){
}*/
}
}
3)、AccountsService.java服務(wù)類,主要是消息的請(qǐng)求和響應(yīng)處理,并且當(dāng)用戶關(guān)注你的公眾號(hào)的時(shí)候,可以設(shè)置默認(rèn)推送消息
package cn.jon.wechat.service;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import cn.jon.wechat.message.req.ImageMessage;
import cn.jon.wechat.message.req.LinkMessage;
import cn.jon.wechat.message.req.LocationMessage;
import cn.jon.wechat.message.req.VideoMessage;
import cn.jon.wechat.message.req.VoiceMessage;
import cn.jon.wechat.message.resp.TextMessage;
import cn.jon.wechat.utils.MessageUtil;
/**
* 解耦,使控制層與業(yè)務(wù)邏輯層分離開來,主要處理請(qǐng)求,響應(yīng)
* @author jon
*/
public class AccountsService {
public static String processRequest(HttpServletRequest request) {
String respMessage = null;
//默認(rèn)返回的文本消息內(nèi)容
String respContent = "請(qǐng)求處理異常,請(qǐng)稍后嘗試!";
try {
//xml請(qǐng)求解析
Map<String,String> requestMap = MessageUtil.pareXml(request);
//發(fā)送方賬號(hào)(open_id)
String fromUserName = requestMap.get("FromUserName");
//公眾賬號(hào)
String toUserName = requestMap.get("ToUserName");
//消息類型
String msgType = requestMap.get("MsgType");
//默認(rèn)回復(fù)此文本消息
TextMessage defaultTextMessage = new TextMessage();
defaultTextMessage.setToUserName(fromUserName);
defaultTextMessage.setFromUserName(toUserName);
defaultTextMessage.setCreateTime(new Date().getTime());
defaultTextMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_TEXT);
defaultTextMessage.setFuncFlag(0);
// 由于href屬性值必須用雙引號(hào)引起,這與字符串本身的雙引號(hào)沖突,所以要轉(zhuǎn)義
defaultTextMessage.setContent("歡迎訪問<a href=\"http://blog.csdn.net/j086924\">jon的博客</a>!");
// defaultTextMessage.setContent(getMainMenu());
// 將文本消息對(duì)象轉(zhuǎn)換成xml字符串
respMessage = MessageUtil.textMessageToXml(defaultTextMessage);
//文本消息
if(msgType.equals(MessageUtil.MESSSAGE_TYPE_TEXT)){
//respContent = "Hi,您發(fā)送的是文本消息!";
//回復(fù)文本消息
TextMessage textMessage = new TextMessage();
// textMessage.setToUserName(toUserName);
// textMessage.setFromUserName(fromUserName);
//這里需要注意,否則無法回復(fù)消息給用戶了
textMessage.setToUserName(fromUserName);
textMessage.setFromUserName(toUserName);
textMessage.setCreateTime(new Date().getTime());
textMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_TEXT);
textMessage.setFuncFlag(0);
respContent = "Hi,你發(fā)的消息是:"+requestMap.get("Content");
textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);
}
//圖片消息
else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_IMAGE)){
ImageMessage imageMessage=new ImageMessage();
imageMessage.setToUserName(fromUserName);
imageMessage.setFromUserName(toUserName);
imageMessage.setCreateTime(new Date().getTime());
imageMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_IMAGE);
//respContent=requestMap.get("PicUrl");
imageMessage.setPicUrl("http://img24.pplive.cn//2013//07//24//12103112092_230X306.jpg");
respMessage = MessageUtil.imageMessageToXml(imageMessage);
}
//地理位置
else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_LOCATION)){
LocationMessage locationMessage=new LocationMessage();
locationMessage.setToUserName(fromUserName);
locationMessage.setFromUserName(toUserName);
locationMessage.setCreateTime(new Date().getTime());
locationMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_LOCATION);
locationMessage.setLocation_X(requestMap.get("Location_X"));
locationMessage.setLocation_Y(requestMap.get("Location_Y"));
locationMessage.setScale(requestMap.get("Scale"));
locationMessage.setLabel(requestMap.get("Label"));
respMessage = MessageUtil.locationMessageToXml(locationMessage);
}
//視頻消息
else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_VIDEO)){
VideoMessage videoMessage=new VideoMessage();
videoMessage.setToUserName(fromUserName);
videoMessage.setFromUserName(toUserName);
videoMessage.setCreateTime(new Date().getTime());
videoMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_VIDEO);
videoMessage.setMediaId(requestMap.get("MediaId"));
videoMessage.setThumbMediaId(requestMap.get("ThumbMediaId"));
respMessage = MessageUtil.videoMessageToXml(videoMessage);
}
//鏈接消息
else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_LINK)){
LinkMessage linkMessage=new LinkMessage();
linkMessage.setToUserName(fromUserName);
linkMessage.setFromUserName(toUserName);
linkMessage.setCreateTime(new Date().getTime());
linkMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_LINK);
linkMessage.setTitle(requestMap.get("Title"));
linkMessage.setDescription(requestMap.get("Description"));
linkMessage.setUrl(requestMap.get("Url"));
respMessage = MessageUtil.linkMessageToXml(linkMessage);
}
//語音消息
else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_VOICE)){
VoiceMessage voiceMessage=new VoiceMessage();
voiceMessage.setToUserName(fromUserName);
voiceMessage.setFromUserName(toUserName);
voiceMessage.setCreateTime(new Date().getTime());
voiceMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_VOICE);
voiceMessage.setMediaId(requestMap.get("MediaId"));
voiceMessage.setFormat(requestMap.get("Format"));
respMessage = MessageUtil.voiceMessageToXml(voiceMessage);
}
//事件推送
else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_EVENT)){
//事件類型
String eventType = requestMap.get("Event");
//訂閱
if(eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)){
respContent = "謝謝關(guān)注!";
}
//取消訂閱
else if(eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)){
//
System.out.println("取消訂閱");
}
else if(eventType.equals(MessageUtil.EVENT_TYPE_CLICK)){
//自定義菜單消息處理
System.out.println("自定義菜單消息處理");
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return respMessage;
}
public static String getMainMenu()
{
StringBuffer buffer =new StringBuffer();
buffer.append("您好,我是jon,請(qǐng)回復(fù)數(shù)字選擇服務(wù):").append("\n");
buffer.append("1、我的博客").append("\n");
buffer.append("2、 歌曲點(diǎn)播").append("\n");
buffer.append("3、 經(jīng)典游戲").append("\n");
buffer.append("4 、聊天打牌").append("\n\n");
buffer.append("回復(fù)"+"0"+"顯示幫助菜單");
return buffer.toString();
}
}
4)、MessageUtil.java幫助類,包括常量的定義和xml消息轉(zhuǎn)換和處理
package cn.jon.wechat.utils;
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 org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import cn.jon.wechat.message.req.ImageMessage;
import cn.jon.wechat.message.req.LinkMessage;
import cn.jon.wechat.message.req.LocationMessage;
import cn.jon.wechat.message.req.VideoMessage;
import cn.jon.wechat.message.req.VoiceMessage;
import cn.jon.wechat.message.resp.Article;
import cn.jon.wechat.message.resp.MusicMessage;
import cn.jon.wechat.message.resp.NewsMessage;
import cn.jon.wechat.message.resp.TextMessage;
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;
/**
* 各種消息的處理類
* @author jon
*/
public class MessageUtil {
/**
* 文本類型
*/
public static final String MESSSAGE_TYPE_TEXT = "text";
/**
* 音樂類型
*/
public static final String MESSSAGE_TYPE_MUSIC = "music";
/**
* 圖文類型
*/
public static final String MESSSAGE_TYPE_NEWS = "news";
/**
* 視頻類型
*/
public static final String MESSSAGE_TYPE_VIDEO = "video";
/**
* 圖片類型
*/
public static final String MESSSAGE_TYPE_IMAGE = "image";
/**
* 鏈接類型
*/
public static final String MESSSAGE_TYPE_LINK = "link";
/**
* 地理位置類型
*/
public static final String MESSSAGE_TYPE_LOCATION = "location";
/**
* 音頻類型
*/
public static final String MESSSAGE_TYPE_VOICE = "voice";
/**
* 推送類型
*/
public static final String MESSSAGE_TYPE_EVENT = "event";
/**
* 事件類型:subscribe(訂閱)
*/
public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
/**
* 事件類型:unsubscribe(取消訂閱)
*/
public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
/**
* 事件類型:click(自定義菜單點(diǎn)擊事件)
*/
public static final String EVENT_TYPE_CLICK= "CLICK";
/**
* 解析微信發(fā)來的請(qǐng)求 XML
*/
@SuppressWarnings("unchecked")
public static Map<String,String> pareXml(HttpServletRequest request) throws Exception {
//將解析的結(jié)果存儲(chǔ)在HashMap中
Map<String,String> reqMap = new HashMap<String, String>();
//從request中取得輸入流
InputStream inputStream = request.getInputStream();
//讀取輸入流
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
//得到xml根元素
Element root = document.getRootElement();
//得到根元素的所有子節(jié)點(diǎn)
List<Element> elementList = root.elements();
//遍歷所有的子節(jié)點(diǎn)取得信息類容
for(Element elem:elementList){
reqMap.put(elem.getName(),elem.getText());
}
//釋放資源
inputStream.close();
inputStream = null;
return reqMap;
}
/**
* 響應(yīng)消息轉(zhuǎn)換成xml返回
* 文本對(duì)象轉(zhuǎn)換成xml
*/
public static String textMessageToXml(TextMessage textMessage) {
xstream.alias("xml", textMessage.getClass());
return xstream.toXML(textMessage);
}
/**
* 語音對(duì)象的轉(zhuǎn)換成xml
*
*/
public static String voiceMessageToXml(VoiceMessage voiceMessage) {
xstream.alias("xml", voiceMessage.getClass());
return xstream.toXML(voiceMessage);
}
/**
* 視頻對(duì)象的轉(zhuǎn)換成xml
*
*/
public static String videoMessageToXml(VideoMessage videoMessage) {
xstream.alias("xml", videoMessage.getClass());
return xstream.toXML(videoMessage);
}
/**
* 音樂對(duì)象的轉(zhuǎn)換成xml
*
*/
public static String musicMessageToXml(MusicMessage musicMessage) {
xstream.alias("xml", musicMessage.getClass());
return xstream.toXML(musicMessage);
}
/**
* 圖文對(duì)象轉(zhuǎn)換成xml
*
*/
public static String newsMessageToXml(NewsMessage newsMessage) {
xstream.alias("xml", newsMessage.getClass());
xstream.alias("item", new Article().getClass());
return xstream.toXML(newsMessage);
}
/**
* 圖片對(duì)象轉(zhuǎn)換成xml
*
*/
public static String imageMessageToXml(ImageMessage imageMessage)
{
xstream.alias("xml",imageMessage.getClass());
return xstream.toXML(imageMessage);
}
/**
* 鏈接對(duì)象轉(zhuǎn)換成xml
*
*/
public static String linkMessageToXml(LinkMessage linkMessage)
{
xstream.alias("xml",linkMessage.getClass());
return xstream.toXML(linkMessage);
}
/**
* 地理位置對(duì)象轉(zhuǎn)換成xml
*
*/
public static String locationMessageToXml(LocationMessage locationMessage)
{
xstream.alias("xml",locationMessage.getClass());
return xstream.toXML(locationMessage);
}
/**
* 拓展xstream,使得支持CDATA塊
*
*/
private static XStream xstream = new XStream(new XppDriver(){
public HierarchicalStreamWriter createWriter(Writer out){
return new PrettyPrintWriter(out){
//對(duì)所有的xml節(jié)點(diǎn)的轉(zhuǎn)換都增加CDATA標(biāo)記
boolean cdata = true;
@SuppressWarnings("unchecked")
public void startNode(String name,Class clazz){
super.startNode(name,clazz);
}
protected void writeText(QuickWriter writer,String text){
if(cdata){
writer.write("<![CDATA[");
writer.write(text);
writer.write("]]>");
}else{
writer.write(text);
}
}
};
}
});
}
5)、BaseMessage.java消息基類(包括:開發(fā)者微信號(hào)、用戶賬戶、創(chuàng)建時(shí)間、消息類型、消息ID變量),文本、視頻、圖片消息都會(huì)繼承此基類,在此基礎(chǔ)上擴(kuò)展自己的變量,可根據(jù)開發(fā)者文檔中的各種消息屬性進(jìn)行定義
package cn.jon.wechat.message.req;
/**
* 消息基類 (普通用戶-公眾號(hào))
* @author jon
*/
public class BaseMessage {
//開發(fā)者微信號(hào)
private String ToUserName;
//發(fā)送方賬號(hào)(一個(gè)openId)
private String FromUserName;
//消息創(chuàng)建時(shí)間(整型)
private long CreateTime;
//消息類型(text/image/location/link...)
private String MsgType;
//消息id 64位整型
private String MsgId;
public BaseMessage() {
super();
// TODO Auto-generated constructor stub
}
public BaseMessage(String toUserName, String fromUserName, long createTime,
String msgType, String msgId) {
super();
ToUserName = toUserName;
FromUserName = fromUserName;
CreateTime = createTime;
MsgType = msgType;
MsgId = msgId;
}
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;
}
public String getMsgId() {
return MsgId;
}
public void setMsgId(String msgId) {
MsgId = msgId;
}
}
6)、TextMessage.java文本消息,繼承自5中基類,擴(kuò)展內(nèi)容屬性
package cn.jon.wechat.message.req;
/**
* 文本消息
* @author jon
*/
public class TextMessage extends BaseMessage{
//消息內(nèi)容
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
7)、ImageMessage.java圖片消息
package cn.jon.wechat.message.req;
/**
* 圖片消息
* @author jon
*/
public class ImageMessage extends BaseMessage{
//圖片鏈接
private String PicUrl;
public String getPicUrl() {
return PicUrl;
}
public void setPicUrl(String picUrl) {
PicUrl = picUrl;
}
}
8)、VideoMessage.java視頻消息
package cn.jon.wechat.message.req;
public class VideoMessage extends BaseMessage {
private String mediaId;
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;
}
}
其他消息類可根據(jù)開發(fā)者文檔自行進(jìn)行完成,另外,開發(fā)者也可以申請(qǐng)公眾平臺(tái)測(cè)試賬號(hào),對(duì)開發(fā)的相關(guān)內(nèi)容進(jìn)行測(cè)試。
本文已被整理到了《Android微信開發(fā)教程匯總》,《java微信開發(fā)教程匯總》歡迎大家學(xué)習(xí)閱讀。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- java微信公眾號(hào)企業(yè)付款開發(fā)
- Java版微信公眾號(hào)支付開發(fā)全過程
- 微信公眾號(hào)開發(fā)之設(shè)置自定義菜單實(shí)例代碼【java版】
- java微信公眾號(hào)支付開發(fā)之現(xiàn)金紅包
- 微信公眾號(hào)開發(fā)之回復(fù)圖文消息java代碼
- Java微信公眾號(hào)開發(fā)之通過微信公眾號(hào)獲取用戶信息
- 用Java設(shè)計(jì)模式中的觀察者模式開發(fā)微信公眾號(hào)的例子
- java微信公眾號(hào)開發(fā)第一步 公眾號(hào)接入和access_token管理
- Java開發(fā)微信公眾號(hào)接收和被動(dòng)回復(fù)普通消息
- java微信公眾號(hào)開發(fā)(搭建本地測(cè)試環(huán)境)
- java開發(fā)微信公眾號(hào)支付
- Java 微信公眾號(hào)開發(fā)相關(guān)總結(jié)
相關(guān)文章
mybatis sum(參數(shù)) 列名作為參數(shù)的問題
這篇文章主要介紹了mybatis sum(參數(shù)) 列名作為參數(shù)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
Java.try catch finally 的執(zhí)行順序說明
這篇文章主要介紹了Java.try catch finally 的執(zhí)行順序說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-10-10
MyBatisPlus條件構(gòu)造器圖文實(shí)例詳解
這篇文章主要介紹了MyBatisPlus條件構(gòu)造器,了解內(nèi)部原理是為了幫助我們做擴(kuò)展,同時(shí)也是驗(yàn)證了一個(gè)人的學(xué)習(xí)能力,如果你想讓自己的職業(yè)道路更上一層樓,這些底層的東西你是必須要會(huì)的2023-01-01
Jenkins+Git+Maven自動(dòng)化部署配置詳解
本文主要介紹了Jenkins+Git+Maven自動(dòng)化部署配置詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01
詳解Java中的迭代迭代器Iterator與枚舉器Enumeration
Iterator與Enumeration分別是實(shí)現(xiàn)迭代器和枚舉器類的接口,下面就帶大家來詳解Java中的迭代迭代器Iterator與枚舉器Enumeration,以及它們之間的區(qū)別.2016-05-05
SpringBoot整合mybatis使用Druid做連接池的方式
這篇文章主要介紹了SpringBoot整合mybatis使用Druid做連接池的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08

