java微信公眾號開發案例_java

來源:互聯網
上載者:User

微信公眾號開發一般是針對企業和組織的,個人一般只能申請訂閱號,並且調用的介面有限,下面我們就來簡單的描述下接入公眾號的步驟

1、首先你需要一個郵箱在微信公眾號平台進行註冊;
     註冊的方式有訂閱號、公眾號、小程式和企業號,個人我們這裡只能選擇訂閱號

2、註冊完後,我們登入到公眾號平台--->開發--->基本配置,這裡需要填寫URL和token,URL就是我們使用伺服器的介面;

3、Java Web伺服器程式編譯好且在伺服器上部署可以啟動並執行話,可在微信公眾號進行線上介面調試:

    1)、選擇合適的介面
    2)、系統會產生該介面的參數表,您可以直接在文字框內填入對應的參數值(紅色星號表示該欄位必填)
    3)、點擊檢查問題按鈕,即可得到相應的調試資訊

   eg:擷取access_token的步驟:

   1)、介面類型:基礎支援
   2)、介面列表:擷取access_token介面/token
   3)、填寫相應的參數:grant_type、appid、secret
   4)、點擊檢查問題
   5)、驗證成功會返回結果和提示,結果為:200 ok,提示:Request successful即表示驗證成功

   我們這裡驗證比較多的是訊息介面調試:簡訊、圖片訊息、語音訊息、影像訊息、etc

4、介面有不理解的地方,可進入開發-->開發人員工具-->開發人員文檔進行查詢

5、介面許可權:訂閱號主要有基礎支援、接收訊息及網頁服務裡面的一些介面

下面我們主要講訂閱號怎麼樣接收訊息的案例:

1、需要申請一個個人微信訂閱號
2、url伺服器和伺服器端代碼部署(可以用騰訊雲or阿里雲伺服器)

1)、AccountsServlet.java類,驗證來自微信伺服器和微信伺服器的訊息處理

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  }  /**  * 確認請求來自於微信伺服器  */   public void doGet(HttpServletRequest request, HttpServletResponse response)   throws ServletException, IOException {   System.out.println("介面測試開始!!!");   //微信加密簽名   String signature = request.getParameter("signature");   //時間戳記   String timestamp = request.getParameter("timestamp");   //隨機數   String nonce = request.getParameter("nonce");   //隨機字串   String echostr = request.getParameter("echostr");     PrintWriter out = response.getWriter();   //通過校正signature對請求進行校正,若校正成功則原樣返回echostr,表示接入成功,否則接入失敗   if(SignUtil.checkSignature(signature,timestamp,nonce)){   out.print(echostr);   }   out.close();   out = null; //  response.encodeRedirectURL("success.jsp");      }  /**  * 處理微信伺服器發來的訊息  */  public void doPost(HttpServletRequest request, HttpServletResponse response)   throws ServletException, IOException {  //訊息的接受、處理、響應  request.setCharacterEncoding("utf-8");  response.setCharacterEncoding("utf-8");  //調用核心業務類型接受訊息、處理訊息  String respMessage = AccountsService.processRequest(request);    //響應訊息  PrintWriter out = response.getWriter();  out.print(respMessage);  out.close();      }   public void init() throws ServletException {  // Put your code here  }  } 

2)、SignUtil.java類,請求校正工具類,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;  /**  * 請求校正工具類  * @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組成數組進行字典排序  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();  }  //釋放記憶體  sb = null;  //將sha1加密後的字串與signature對比,標識該請求來源於微信  return stnStr!=null?stnStr.equals(signature.toUpperCase()):false;  }  /**  * 將位元組數群組轉換成十六進位字串  * @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;  }  /**  * 將位元組轉換成為十六進位字串  */  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服務類,主要是訊息的請求和響應處理,並且當使用者關注你的公眾號的時候,可以設定預設推送訊息

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;  /**  * 解耦,使控制層與商務邏輯層分離開來,主要處理請求,響應  * @author jon  */ public class AccountsService {   public static String processRequest(HttpServletRequest request) {  String respMessage = null;  //預設返回的簡訊內容  String respContent = "請求處理異常,請稍後嘗試!";  try {   //xml請求解析   Map<String,String> requestMap = MessageUtil.pareXml(request);     //發送方帳號(open_id)   String fromUserName = requestMap.get("FromUserName");   //公眾帳號   String toUserName = requestMap.get("ToUserName");   //訊息類型   String msgType = requestMap.get("MsgType");     //預設回複此簡訊   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屬性值必須用雙引號引起,這與字串本身的雙引號衝突,所以要轉義   defaultTextMessage.setContent("歡迎訪問<a href=\"http://blog.csdn.net/j086924\">jon的部落格</a>!"); //  defaultTextMessage.setContent(getMainMenu());   // 將簡訊對象轉換成xml字串   respMessage = MessageUtil.textMessageToXml(defaultTextMessage);      //簡訊   if(msgType.equals(MessageUtil.MESSSAGE_TYPE_TEXT)){   //respContent = "Hi,您發送的是簡訊!";   //回複簡訊   TextMessage textMessage = new TextMessage(); //  textMessage.setToUserName(toUserName); //  textMessage.setFromUserName(fromUserName);   //這裡需要注意,否則無法回複訊息給使用者了   textMessage.setToUserName(fromUserName);   textMessage.setFromUserName(toUserName);   textMessage.setCreateTime(new Date().getTime());   textMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_TEXT);   textMessage.setFuncFlag(0);   respContent = "Hi,你發的訊息是:"+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("yun_qi_img/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 = "謝謝關注!";   }   //取消訂閱   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,請回複數字選擇服務:").append("\n");  buffer.append("1、我的部落格").append("\n");  buffer.append("2、 歌曲點播").append("\n");  buffer.append("3、 經典遊戲").append("\n");  buffer.append("4 、聊天打牌").append("\n\n");  buffer.append("回複"+"0"+"顯示協助菜單");  return buffer.toString();    } } 

4)、MessageUtil.java協助類,包括常量的定義和xml訊息轉換和處理

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(自訂菜單點擊事件)  */  public static final String EVENT_TYPE_CLICK= "CLICK";   /**  * 解析微信發來的請求 XML  */  @SuppressWarnings("unchecked")  public static Map<String,String> pareXml(HttpServletRequest request) throws Exception {    //將解析的結果儲存在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();  //得到根項目的所有子節點  List<Element> elementList = root.elements();  //遍曆所有的子節點取得資訊類容  for(Element elem:elementList){   reqMap.put(elem.getName(),elem.getText());  }  //釋放資源  inputStream.close();  inputStream = null;    return reqMap;  }  /**  * 響應訊息轉換成xml返回  * 文字物件轉換成xml  */  public static String textMessageToXml(TextMessage textMessage) {  xstream.alias("xml", textMessage.getClass());  return xstream.toXML(textMessage);  }  /**  * 語音對象的轉換成xml  *  */  public static String voiceMessageToXml(VoiceMessage voiceMessage) {  xstream.alias("xml", voiceMessage.getClass());  return xstream.toXML(voiceMessage);  }   /**  * 視頻對象的轉換成xml  *  */  public static String videoMessageToXml(VideoMessage videoMessage) {  xstream.alias("xml", videoMessage.getClass());  return xstream.toXML(videoMessage);  }   /**  * 音樂對象的轉換成xml  *  */  public static String musicMessageToXml(MusicMessage musicMessage) {  xstream.alias("xml", musicMessage.getClass());  return xstream.toXML(musicMessage);  }  /**  * 圖文對象轉換成xml  *  */  public static String newsMessageToXml(NewsMessage newsMessage) {  xstream.alias("xml", newsMessage.getClass());  xstream.alias("item", new Article().getClass());  return xstream.toXML(newsMessage);  }   /**  * 圖片對象轉換成xml  *  */   public static String imageMessageToXml(ImageMessage imageMessage)  {  xstream.alias("xml",imageMessage.getClass());  return xstream.toXML(imageMessage);    }   /**  * 連結化物件轉換成xml  *  */   public static String linkMessageToXml(LinkMessage linkMessage)  {  xstream.alias("xml",linkMessage.getClass());  return xstream.toXML(linkMessage);    }   /**  * 地理位置對象轉換成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){   //對所有的xml節點的轉換都增加CDATA標記   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訊息基類(包括:開發人員微訊號、使用者賬戶、建立時間、訊息類型、訊息ID變數),文本、視頻、圖片訊息都會繼承此基類,在此基礎上擴充自己的變數,可根據開發人員文檔中的各種訊息屬性進行定義

package cn.jon.wechat.message.req; /**  * 訊息基類 (普通使用者-公眾號)  * @author jon  */ public class BaseMessage {   //開發人員微訊號  private String ToUserName;  //發送方帳號(一個openId)  private String FromUserName;  //訊息建立時間(整型)  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中基類,擴充內容屬性

package cn.jon.wechat.message.req; /**  * 簡訊  * @author jon  */ public class TextMessage extends BaseMessage{  //訊息內容  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;  }  } 

其他訊息類可根據開發人員文檔自行進行完成,另外,開發人員也可以申請公眾平台測試帳號,對開發的相關內容進行測試。

本文已被整理到了《Android微信開發教程匯總》,歡迎大家學習閱讀。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.