摘要:時間年月日星期六說明本文部分內容均來自慕課網。慕課網教學源碼學習源碼第一章概述課程簡介本課程是在之前的初識微信公眾號開發課程基礎之上的。慕課網課程涵蓋前端開發等前沿技術語言,包括基礎課程實用案例高級分享三大類型,適合不同階段的學習人群。
時間:2017年08月12日星期六
說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com
教學源碼:http://img.mukewang.com/down/...
學習源碼:https://github.com/zccodere/s...
本課程是在之前的《初識Java微信公眾號開發》課程基礎之上的。
之前入門課程主要講解了
微信公眾號及公眾號平臺的相關概念 編輯模式和開發模式的相關操作
課程內容
消息回復接口 素材管理接口 自定義菜單接口 百度翻譯API1-2 微信公眾平臺測試號
因個人訂閱號權限有限,很多高級接口無法使用,所以可以申請測試賬號,測試賬號對這些接口的權限都放開了。
第二章:素材管理接口 2-1 圖文消息復制項目wxdevaccess重命名為wxdevadvanced。其中POM文件如下
4.0.0 com.myimooc wxdevadvanced 0.0.1-SNAPSHOT jar wxdevadvanced http://maven.apache.org org.springframework.boot spring-boot-starter-parent 1.5.1.RELEASE UTF-8 UTF-8 org.springframework.boot spring-boot-starter-web com.alibaba fastjson 1.2.36 org.apache.httpcomponents httpclient commons-codec commons-codec org.apache.maven.plugins maven-compiler-plugin 1.8
由于從此節開始,均屬于代碼編寫,類及代碼較多。這里就不全部一一展示了,請到我的github地址查看。完成后的項目結構如下
說明:由于條件限制,此項目代碼均沒有進行測試,這里只是顯示大概開發過程。
接口文檔
路徑:消息管理》發送消息-被動回復用戶消息》回復圖文消息 地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp14211401832-2 獲取access_token(上)
接口文檔地址:https://mp.weixin.qq.com/wiki...
編寫AccessToken類
package com.myimooc.wxdevadvanced.domain; import java.io.Serializable; /** * 獲取 access_token 微信接口響應對象 * @author ZhangCheng on 2017-08-12 * */ public class AccessToken implements Serializable{ private static final long serialVersionUID = 1L; private String token; private int expiresIn; @Override public String toString() { return "AccessToken [token=" + token + ", expiresIn=" + expiresIn + "]"; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } public int getExpiresIn() { return expiresIn; } public void setExpiresIn(int expiresIn) { this.expiresIn = expiresIn; } }2-3 獲取access_token(下)
編寫TokenUtils類
package com.myimooc.wxdevadvanced.util; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; import com.alibaba.fastjson.JSONObject; import com.myimooc.wxdevadvanced.domain.AccessToken; /** * 微信工具類 * @author ZhangCheng on 2017-08-12 * */ public class TokenUtils { private static final String APPID="dsadqawer2124a5wdqw1"; private static final String APPSECRET = "dsadaq875w5edqwd58qwdqwbgthr4t5qa"; private static final String CHARSET_FORMAT = "UTF-8"; private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; /** * 發起GET請求 */ public static JSONObject doGetStr(String url) throws Exception{ HttpClientBuilder builder = HttpClientBuilder.create(); HttpGet httpGet = new HttpGet(url); JSONObject object = null; HttpResponse response = builder.build().execute(httpGet); HttpEntity entity = response.getEntity(); if(null != entity){ String result = EntityUtils.toString(entity,CHARSET_FORMAT); object = JSONObject.parseObject(result); } return object; } /** * 發起POST請求 */ public static JSONObject doPostStr(String url,String outStr)throws Exception{ HttpClientBuilder builder = HttpClientBuilder.create(); JSONObject object = null; HttpPost httpPost = new HttpPost(url); httpPost.setEntity(new StringEntity(outStr,CHARSET_FORMAT)); HttpResponse response = builder.build().execute(httpPost); HttpEntity entity = response.getEntity(); String result = EntityUtils.toString(entity,CHARSET_FORMAT); object = JSONObject.parseObject(result); return object; } /** * 獲取access_token */ public static AccessToken getAccessToken(){ AccessToken token = new AccessToken(); String url = ACCESS_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET); JSONObject json = null; try{ json = doGetStr(url); }catch (Exception e) { } if(null != json && json.containsKey("access_token")){ token.setToken(json.getString("access_token")); token.setExpiresIn(json.getIntValue("expires_in")); } return token; } }2-4 圖片消息回復
接口文檔
路徑:消息管理》發送消息-被動回復用戶消息》回復圖片消息 地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp14211401832-5 音樂消息的回復
接口文檔
路徑:消息管理》發送消息-被動回復用戶消息》回復音樂消息 地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543第三章:自定義菜單接口 3-1 自定義菜單(上)
接口文檔
路徑:自定義菜單》自定義菜單創建接口 地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013
代碼演示:
1.編寫Button類
package com.myimooc.wxdevadvanced.domain.menu; /** * 菜單按鈕 * @author ZhangCheng on 2017-08-12 * */ public class Button { private String type; private String name; private Button[] sub_button; public String getType() { return type; } public void setType(String type) { this.type = type; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Button[] getSub_button() { return sub_button; } public void setSub_button(Button[] sub_button) { this.sub_button = sub_button; } }
2.編寫Menu類
package com.myimooc.wxdevadvanced.domain.menu; /** * 菜單 * @author ZhangCheng on 2017-08-12 * */ public class Menu { private Button[] button; public Button[] getButton() { return button; } public void setButton(Button[] button) { this.button = button; } }
3.編寫ClickButton類
package com.myimooc.wxdevadvanced.domain.menu; /** * 點擊按鈕 * @author ZhangCheng on 2017-08-12 * */ public class ClickButton extends Button{ private String key; public String getKey() { return key; } public void setKey(String key) { this.key = key; } }
4.編寫ViewButton類
package com.myimooc.wxdevadvanced.domain.menu; /** * 視圖按鈕 * @author ZhangCheng on 2017-08-12 * */ public class ViewButton extends Button{ private String url; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } }3-2 自定義菜單(下)
代碼演示:
1.修改WinxinUtils類
package com.myimooc.wxdevadvanced.util; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.List; import java.util.Map; import com.alibaba.fastjson.JSONObject; import com.myimooc.wxdevadvanced.domain.menu.Button; import com.myimooc.wxdevadvanced.domain.menu.ClickButton; import com.myimooc.wxdevadvanced.domain.menu.Menu; import com.myimooc.wxdevadvanced.domain.menu.ViewButton; import com.myimooc.wxdevadvanced.domain.trans.Data; import com.myimooc.wxdevadvanced.domain.trans.Parts; import com.myimooc.wxdevadvanced.domain.trans.Symbols; import com.myimooc.wxdevadvanced.domain.trans.TransResult; /** * 微信工具類 * @author ZhangCheng on 2017-08-12 * */ public class WeixinUtils { private static final String UPLOAD_URL = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE"; private static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN"; private static final String QUERY_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN"; private static final String DELETE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN"; public static String upload(String filePath,String accessToken,String type)throws Exception{ File file = new File(filePath); if(!file.exists() || !file.isFile()){ throw new IOException("文件不存在"); } String url = UPLOAD_URL.replace("ACCESS_TOKEN", accessToken).replace("TYPE", type); URL urlObj = new URL(url); // 連接 HttpURLConnection con = (HttpURLConnection)urlObj.openConnection(); con.setRequestMethod("POST"); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); // 設置請求頭信息 con.setRequestProperty("Connection", "Keep-Alive"); con.setRequestProperty("Charset", "UTF-8"); // 設置邊界 String BOUNDARY = "-----------" + System.currentTimeMillis(); con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY); StringBuilder sb = new StringBuilder(); sb.append("--"); sb.append(BOUNDARY); sb.append(" "); sb.append("Content-Disposition;form-data;name="file",filename=""+ file.getName() + "" "); sb.append("Content-Type;application/octet-strean "); byte[] head = sb.toString().getBytes("UTF-8"); // 獲得輸出流 OutputStream out = new DataOutputStream(con.getOutputStream()); // 輸出表頭 out.write(head); // 文件正文部分 把文件以流文件的方式 推入到url中 DataInputStream in = new DataInputStream(new FileInputStream(file)); int bytes = 0; byte[] bufferOut = new byte[1024]; while((bytes = in.read(bufferOut))!= -1){ out.write(bufferOut, 0, bytes); } in.close(); // 結尾部分 byte[] foot = (" --" + BOUNDARY + "-- ").getBytes("utf-8");//定義最后數據分隔線 out.write(foot); out.flush(); out.close(); StringBuffer buffer = new StringBuffer(); BufferedReader reader = null; String result = null; try { //定義BufferedReader輸入流來讀取URL的響應 reader = new BufferedReader(new InputStreamReader(con.getInputStream())); String line = null; while ((line = reader.readLine()) != null) { buffer.append(line); } if (result == null) { result = buffer.toString(); } } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { reader.close(); } } JSONObject jsonObj = JSONObject.parseObject(result); System.out.println(jsonObj); String typeName = "media_id"; if(!"image".equals(type)){ typeName = type + "_media_id"; } String mediaId = jsonObj.getString(typeName); return mediaId; } /** * 組裝菜單 */ public static Menu initMenu(){ Menu menu = new Menu(); ClickButton button11 = new ClickButton(); button11.setName("click菜單"); button11.setType("click"); button11.setKey("11"); ViewButton button21 = new ViewButton(); button21.setName("view菜單"); button21.setType("view"); button21.setUrl("http://www.imooc.com"); ClickButton button31 = new ClickButton(); button31.setName("掃碼事件"); button31.setType("scancode_push"); button31.setKey("31"); ClickButton button32 = new ClickButton(); button32.setName("地理位置"); button32.setType("location_select"); button32.setKey("32"); Button button = new Button(); button.setName("菜單"); button.setSub_button(new Button[]{button31,button32}); menu.setButton(new Button[]{button11,button21,button}); return menu; } /** * 創建菜單 */ public static int createMenu(String token,String menu) throws Exception{ int result = 0; String url = CREATE_MENU_URL.replace("ACCESS_TOKEN", token); JSONObject jsonObject = TokenUtils.doPostStr(url, menu); if(jsonObject != null){ result = jsonObject.getIntValue("errcode"); } return result; } /** * 獲取菜單 */ public static JSONObject queryMenu(String token) throws Exception{ String url = QUERY_MENU_URL.replace("ACCESS_TOKEN", token); JSONObject jsonObject = TokenUtils.doGetStr(url); return jsonObject; } /** * 移除菜單 */ public static int deleteMenu(String token) throws Exception{ String url = DELETE_MENU_URL.replace("ACCESS_TOKEN", token); JSONObject jsonObject = TokenUtils.doGetStr(url); int result = 0; if(jsonObject != null){ result = jsonObject.getIntValue("errcode"); } return result; } /** * 詞組翻譯 */ public static String translate(String source) throws Exception{ String url = "http://openapi.baidu.com/public/2.0/translate/dict/simple?client_id=jNg0LPSBe691Il0CG5MwDupw&q=KEYWORD&from=auto&to=auto"; url = url.replace("KEYWORD", URLEncoder.encode(source, "UTF-8")); JSONObject jsonObject = TokenUtils.doGetStr(url); String errno = jsonObject.getString("errno"); Object obj = jsonObject.get("data"); StringBuffer dst = new StringBuffer(); if("0".equals(errno) && !"[]".equals(obj.toString())){ TransResult transResult = (TransResult) JSONObject.toJavaObject(jsonObject, TransResult.class); Data data = transResult.getData(); Symbols symbols = data.getSymbols()[0]; String phzh = symbols.getPh_zh()==null ? "" : "中文拼音:"+symbols.getPh_zh()+" "; String phen = symbols.getPh_en()==null ? "" : "英式英標:"+symbols.getPh_en()+" "; String pham = symbols.getPh_am()==null ? "" : "美式英標:"+symbols.getPh_am()+" "; dst.append(phzh+phen+pham); Parts[] parts = symbols.getParts(); String pat = null; for(Parts part : parts){ pat = (part.getPart()!=null && !"".equals(part.getPart())) ? "["+part.getPart()+"]" : ""; String[] means = part.getMeans(); dst.append(pat); for(String mean : means){ dst.append(mean+";"); } } }else{ dst.append(translateFull(source)); } return dst.toString(); } /** * 句子翻譯 */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static String translateFull(String source) throws Exception{ String url = "http://openapi.baidu.com/public/2.0/bmt/translate?client_id=jNg0LPSBe691Il0CG5MwDupw&q=KEYWORD&from=auto&to=auto"; url = url.replace("KEYWORD", URLEncoder.encode(source, "UTF-8")); JSONObject jsonObject = TokenUtils.doGetStr(url); StringBuffer dst = new StringBuffer(); List3-3 菜單的事件推送
接口文檔
路徑:自定義菜單》自定義菜單事件推送 地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141016
代碼演示:
1.修改MessageRest類
package com.myimooc.wxdevadvanced.rest; import java.util.Date; import java.util.Map; import java.util.Objects; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import com.myimooc.wxdevadvanced.domain.EventMessage; import com.myimooc.wxdevadvanced.domain.NewsMessage; import com.myimooc.wxdevadvanced.domain.TextMessage; import com.myimooc.wxdevadvanced.util.MessageUtils; import com.myimooc.wxdevadvanced.util.WeixinUtils; /** * 處理消息請求與響應 * @author ZhangCheng on 2017-08-11 * */ @RestController public class MessageRest { private static final Logger logger = LoggerFactory.getLogger(MessageRest.class); /** * 接收微信服務器發送的POST請求 * @throws Exception */ @PostMapping("textmessage") public Object textmessage(TextMessage msg) throws Exception{ logger.info("請求參數:{}",msg.toString()); // 文本消息 if(Objects.equals(MessageUtils.MESSAGE_TEXT, msg.getMsgType())){ TextMessage textMessage = new TextMessage(); // 關鍵字 1 if(Objects.equals("1", msg.getContent())){ textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.firstMenu()); return textMessage; } // 關鍵字 2 if(Objects.equals("2", msg.getContent())){ NewsMessage newsMessage = MessageUtils.initNewsMessage(msg.getToUserName(), msg.getFromUserName()); return newsMessage; } // 關鍵字 3 if(Objects.equals("3", msg.getContent())){ textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.threeMenu()); return textMessage; } // 關鍵字 翻譯 if(msg.getContent().startsWith("翻譯")){ String word = msg.getContent().replaceAll("^翻譯","").trim(); if("".equals(word)){ textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.threeMenu()); return textMessage; } textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),WeixinUtils.translate(word)); return textMessage; } // 關鍵字 ?? 調出菜單 if(Objects.equals("?", msg.getContent()) || Objects.equals("?", msg.getContent())){ textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.menuText()); return textMessage; } // 非關鍵字 textMessage.setFromUserName(msg.getToUserName()); textMessage.setToUserName(msg.getFromUserName()); textMessage.setMsgType(MessageUtils.MESSAGE_TEXT); textMessage.setCreateTime(new Date().getTime()+""); textMessage.setContent("您發送的消息是:" + msg.getContent()); return textMessage; } return null; } /** * 接收微信服務器發送的POST請求 */ @PostMapping("eventmessage") public Object eventmessage(Map3-4 菜單查詢與刪除param){ EventMessage msg = new EventMessage(); BeanUtils.copyProperties(param, msg); // 事件推送 if(Objects.equals(MessageUtils.MESSAGE_EVENT, msg.getMsgType())){ // 關注 if(Objects.equals(MessageUtils.MESSAGE_SUBSCRIBE, msg.getEvent())){ TextMessage text = new TextMessage(); text = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.menuText()); return text; } // 菜單 點擊類型 if(Objects.equals(MessageUtils.MESSAGE_CLICK, msg.getEvent())){ TextMessage text = new TextMessage(); text = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.menuText()); return text; } // 菜單 視圖類型 if(Objects.equals(MessageUtils.MESSAGE_VIEW, msg.getEvent())){ String url = param.get("EventKey"); return MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),url); } // 菜單 掃碼事件 if(Objects.equals(MessageUtils.MESSAGE_SCANCODE, msg.getEvent())){ String key = param.get("EventKey"); return MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),key); } // 菜單 地理位置 if(Objects.equals(MessageUtils.MESSAGE_LOCATION, msg.getEvent())){ String Label = param.get("Label"); return MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),Label); } } return "no message"; } }
接口文檔
路徑:自定義菜單》自定義菜單查詢接口 地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141014 路徑:自定義菜單》自定義菜單刪除接口 地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141015
代碼演示:
1.修改WinxinUtils類
package com.myimooc.wxdevadvanced.util; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.List; import java.util.Map; import com.alibaba.fastjson.JSONObject; import com.myimooc.wxdevadvanced.domain.menu.Button; import com.myimooc.wxdevadvanced.domain.menu.ClickButton; import com.myimooc.wxdevadvanced.domain.menu.Menu; import com.myimooc.wxdevadvanced.domain.menu.ViewButton; import com.myimooc.wxdevadvanced.domain.trans.Data; import com.myimooc.wxdevadvanced.domain.trans.Parts; import com.myimooc.wxdevadvanced.domain.trans.Symbols; import com.myimooc.wxdevadvanced.domain.trans.TransResult; /** * 微信工具類 * @author ZhangCheng on 2017-08-12 * */ public class WeixinUtils { private static final String UPLOAD_URL = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE"; private static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN"; private static final String QUERY_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN"; private static final String DELETE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN"; public static String upload(String filePath,String accessToken,String type)throws Exception{ File file = new File(filePath); if(!file.exists() || !file.isFile()){ throw new IOException("文件不存在"); } String url = UPLOAD_URL.replace("ACCESS_TOKEN", accessToken).replace("TYPE", type); URL urlObj = new URL(url); // 連接 HttpURLConnection con = (HttpURLConnection)urlObj.openConnection(); con.setRequestMethod("POST"); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); // 設置請求頭信息 con.setRequestProperty("Connection", "Keep-Alive"); con.setRequestProperty("Charset", "UTF-8"); // 設置邊界 String BOUNDARY = "-----------" + System.currentTimeMillis(); con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY); StringBuilder sb = new StringBuilder(); sb.append("--"); sb.append(BOUNDARY); sb.append(" "); sb.append("Content-Disposition;form-data;name="file",filename=""+ file.getName() + "" "); sb.append("Content-Type;application/octet-strean "); byte[] head = sb.toString().getBytes("UTF-8"); // 獲得輸出流 OutputStream out = new DataOutputStream(con.getOutputStream()); // 輸出表頭 out.write(head); // 文件正文部分 把文件以流文件的方式 推入到url中 DataInputStream in = new DataInputStream(new FileInputStream(file)); int bytes = 0; byte[] bufferOut = new byte[1024]; while((bytes = in.read(bufferOut))!= -1){ out.write(bufferOut, 0, bytes); } in.close(); // 結尾部分 byte[] foot = (" --" + BOUNDARY + "-- ").getBytes("utf-8");//定義最后數據分隔線 out.write(foot); out.flush(); out.close(); StringBuffer buffer = new StringBuffer(); BufferedReader reader = null; String result = null; try { //定義BufferedReader輸入流來讀取URL的響應 reader = new BufferedReader(new InputStreamReader(con.getInputStream())); String line = null; while ((line = reader.readLine()) != null) { buffer.append(line); } if (result == null) { result = buffer.toString(); } } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { reader.close(); } } JSONObject jsonObj = JSONObject.parseObject(result); System.out.println(jsonObj); String typeName = "media_id"; if(!"image".equals(type)){ typeName = type + "_media_id"; } String mediaId = jsonObj.getString(typeName); return mediaId; } /** * 組裝菜單 */ public static Menu initMenu(){ Menu menu = new Menu(); ClickButton button11 = new ClickButton(); button11.setName("click菜單"); button11.setType("click"); button11.setKey("11"); ViewButton button21 = new ViewButton(); button21.setName("view菜單"); button21.setType("view"); button21.setUrl("http://www.imooc.com"); ClickButton button31 = new ClickButton(); button31.setName("掃碼事件"); button31.setType("scancode_push"); button31.setKey("31"); ClickButton button32 = new ClickButton(); button32.setName("地理位置"); button32.setType("location_select"); button32.setKey("32"); Button button = new Button(); button.setName("菜單"); button.setSub_button(new Button[]{button31,button32}); menu.setButton(new Button[]{button11,button21,button}); return menu; } /** * 創建菜單 */ public static int createMenu(String token,String menu) throws Exception{ int result = 0; String url = CREATE_MENU_URL.replace("ACCESS_TOKEN", token); JSONObject jsonObject = TokenUtils.doPostStr(url, menu); if(jsonObject != null){ result = jsonObject.getIntValue("errcode"); } return result; } /** * 獲取菜單 */ public static JSONObject queryMenu(String token) throws Exception{ String url = QUERY_MENU_URL.replace("ACCESS_TOKEN", token); JSONObject jsonObject = TokenUtils.doGetStr(url); return jsonObject; } /** * 移除菜單 */ public static int deleteMenu(String token) throws Exception{ String url = DELETE_MENU_URL.replace("ACCESS_TOKEN", token); JSONObject jsonObject = TokenUtils.doGetStr(url); int result = 0; if(jsonObject != null){ result = jsonObject.getIntValue("errcode"); } return result; } /** * 詞組翻譯 */ public static String translate(String source) throws Exception{ String url = "http://openapi.baidu.com/public/2.0/translate/dict/simple?client_id=jNg0LPSBe691Il0CG5MwDupw&q=KEYWORD&from=auto&to=auto"; url = url.replace("KEYWORD", URLEncoder.encode(source, "UTF-8")); JSONObject jsonObject = TokenUtils.doGetStr(url); String errno = jsonObject.getString("errno"); Object obj = jsonObject.get("data"); StringBuffer dst = new StringBuffer(); if("0".equals(errno) && !"[]".equals(obj.toString())){ TransResult transResult = (TransResult) JSONObject.toJavaObject(jsonObject, TransResult.class); Data data = transResult.getData(); Symbols symbols = data.getSymbols()[0]; String phzh = symbols.getPh_zh()==null ? "" : "中文拼音:"+symbols.getPh_zh()+" "; String phen = symbols.getPh_en()==null ? "" : "英式英標:"+symbols.getPh_en()+" "; String pham = symbols.getPh_am()==null ? "" : "美式英標:"+symbols.getPh_am()+" "; dst.append(phzh+phen+pham); Parts[] parts = symbols.getParts(); String pat = null; for(Parts part : parts){ pat = (part.getPart()!=null && !"".equals(part.getPart())) ? "["+part.getPart()+"]" : ""; String[] means = part.getMeans(); dst.append(pat); for(String mean : means){ dst.append(mean+";"); } } }else{ dst.append(translateFull(source)); } return dst.toString(); } /** * 句子翻譯 */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static String translateFull(String source) throws Exception{ String url = "http://openapi.baidu.com/public/2.0/bmt/translate?client_id=jNg0LPSBe691Il0CG5MwDupw&q=KEYWORD&from=auto&to=auto"; url = url.replace("KEYWORD", URLEncoder.encode(source, "UTF-8")); JSONObject jsonObject = TokenUtils.doGetStr(url); StringBuffer dst = new StringBuffer(); List第四章:百度翻譯API 4-1 百度翻譯list = (List ) jsonObject.get("trans_result"); for(Map map : list){ dst.append(map.get("dst")); } return dst.toString(); } }
案例開發
通過百度翻譯API來實現詞組翻譯功能。
百度開放服務平臺
地址:http://developer.baidu.com/ms/oauth/ 百度翻譯API 地址:http://api.fanyi.baidu.com/api/trans/product/index 百度翻譯API文檔 地址:http://api.fanyi.baidu.com/api/trans/product/apidoc
代碼演示:
1.編寫Parts類
package com.myimooc.wxdevadvanced.domain.trans; /** * 百度翻譯API * @author ZhangCheng on 2017-08-12 * */ public class Parts { private String part; private String[] means; public String getPart() { return part; } public void setPart(String part) { this.part = part; } public String[] getMeans() { return means; } public void setMeans(String[] means) { this.means = means; } }
2.編寫Symbols類
package com.myimooc.wxdevadvanced.domain.trans; /** * 百度翻譯API * @author ZhangCheng on 2017-08-12 * */ public class Symbols { private String ph_am; private String ph_en; private String ph_zh; private Parts[] parts; public String getPh_am() { return ph_am; } public void setPh_am(String ph_am) { this.ph_am = ph_am; } public String getPh_en() { return ph_en; } public void setPh_en(String ph_en) { this.ph_en = ph_en; } public String getPh_zh() { return ph_zh; } public void setPh_zh(String ph_zh) { this.ph_zh = ph_zh; } public Parts[] getParts() { return parts; } public void setParts(Parts[] parts) { this.parts = parts; } }
3.編寫Data類
package com.myimooc.wxdevadvanced.domain.trans; /** * 百度翻譯API * @author ZhangCheng on 2017-08-12 * */ public class Data { private String word_name; private Symbols[] symbols; public String getWord_name() { return word_name; } public void setWord_name(String word_name) { this.word_name = word_name; } public Symbols[] getSymbols() { return symbols; } public void setSymbols(Symbols[] symbols) { this.symbols = symbols; } }
4.編寫TransResult類
package com.myimooc.wxdevadvanced.domain.trans; /** * 百度翻譯API * @author ZhangCheng on 2017-08-12 * */ public class TransResult { private String from; private String to; private Data data; private String errno; public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getTo() { return to; } public void setTo(String to) { this.to = to; } public Data getData() { return data; } public void setData(Data data) { this.data = data; } public String getErrno() { return errno; } public void setErrno(String errno) { this.errno = errno; } }
5.修改WeixinUtils類
package com.myimooc.wxdevadvanced.util; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.List; import java.util.Map; import com.alibaba.fastjson.JSONObject; import com.myimooc.wxdevadvanced.domain.menu.Button; import com.myimooc.wxdevadvanced.domain.menu.ClickButton; import com.myimooc.wxdevadvanced.domain.menu.Menu; import com.myimooc.wxdevadvanced.domain.menu.ViewButton; import com.myimooc.wxdevadvanced.domain.trans.Data; import com.myimooc.wxdevadvanced.domain.trans.Parts; import com.myimooc.wxdevadvanced.domain.trans.Symbols; import com.myimooc.wxdevadvanced.domain.trans.TransResult; /** * 微信工具類 * @author ZhangCheng on 2017-08-12 * */ public class WeixinUtils { private static final String UPLOAD_URL = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE"; private static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN"; private static final String QUERY_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN"; private static final String DELETE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN"; public static String upload(String filePath,String accessToken,String type)throws Exception{ File file = new File(filePath); if(!file.exists() || !file.isFile()){ throw new IOException("文件不存在"); } String url = UPLOAD_URL.replace("ACCESS_TOKEN", accessToken).replace("TYPE", type); URL urlObj = new URL(url); // 連接 HttpURLConnection con = (HttpURLConnection)urlObj.openConnection(); con.setRequestMethod("POST"); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); // 設置請求頭信息 con.setRequestProperty("Connection", "Keep-Alive"); con.setRequestProperty("Charset", "UTF-8"); // 設置邊界 String BOUNDARY = "-----------" + System.currentTimeMillis(); con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY); StringBuilder sb = new StringBuilder(); sb.append("--"); sb.append(BOUNDARY); sb.append(" "); sb.append("Content-Disposition;form-data;name="file",filename=""+ file.getName() + "" "); sb.append("Content-Type;application/octet-strean "); byte[] head = sb.toString().getBytes("UTF-8"); // 獲得輸出流 OutputStream out = new DataOutputStream(con.getOutputStream()); // 輸出表頭 out.write(head); // 文件正文部分 把文件以流文件的方式 推入到url中 DataInputStream in = new DataInputStream(new FileInputStream(file)); int bytes = 0; byte[] bufferOut = new byte[1024]; while((bytes = in.read(bufferOut))!= -1){ out.write(bufferOut, 0, bytes); } in.close(); // 結尾部分 byte[] foot = (" --" + BOUNDARY + "-- ").getBytes("utf-8");//定義最后數據分隔線 out.write(foot); out.flush(); out.close(); StringBuffer buffer = new StringBuffer(); BufferedReader reader = null; String result = null; try { //定義BufferedReader輸入流來讀取URL的響應 reader = new BufferedReader(new InputStreamReader(con.getInputStream())); String line = null; while ((line = reader.readLine()) != null) { buffer.append(line); } if (result == null) { result = buffer.toString(); } } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { reader.close(); } } JSONObject jsonObj = JSONObject.parseObject(result); System.out.println(jsonObj); String typeName = "media_id"; if(!"image".equals(type)){ typeName = type + "_media_id"; } String mediaId = jsonObj.getString(typeName); return mediaId; } /** * 組裝菜單 */ public static Menu initMenu(){ Menu menu = new Menu(); ClickButton button11 = new ClickButton(); button11.setName("click菜單"); button11.setType("click"); button11.setKey("11"); ViewButton button21 = new ViewButton(); button21.setName("view菜單"); button21.setType("view"); button21.setUrl("http://www.imooc.com"); ClickButton button31 = new ClickButton(); button31.setName("掃碼事件"); button31.setType("scancode_push"); button31.setKey("31"); ClickButton button32 = new ClickButton(); button32.setName("地理位置"); button32.setType("location_select"); button32.setKey("32"); Button button = new Button(); button.setName("菜單"); button.setSub_button(new Button[]{button31,button32}); menu.setButton(new Button[]{button11,button21,button}); return menu; } /** * 創建菜單 */ public static int createMenu(String token,String menu) throws Exception{ int result = 0; String url = CREATE_MENU_URL.replace("ACCESS_TOKEN", token); JSONObject jsonObject = TokenUtils.doPostStr(url, menu); if(jsonObject != null){ result = jsonObject.getIntValue("errcode"); } return result; } /** * 獲取菜單 */ public static JSONObject queryMenu(String token) throws Exception{ String url = QUERY_MENU_URL.replace("ACCESS_TOKEN", token); JSONObject jsonObject = TokenUtils.doGetStr(url); return jsonObject; } /** * 移除菜單 */ public static int deleteMenu(String token) throws Exception{ String url = DELETE_MENU_URL.replace("ACCESS_TOKEN", token); JSONObject jsonObject = TokenUtils.doGetStr(url); int result = 0; if(jsonObject != null){ result = jsonObject.getIntValue("errcode"); } return result; } /** * 詞組翻譯 */ public static String translate(String source) throws Exception{ String url = "http://openapi.baidu.com/public/2.0/translate/dict/simple?client_id=jNg0LPSBe691Il0CG5MwDupw&q=KEYWORD&from=auto&to=auto"; url = url.replace("KEYWORD", URLEncoder.encode(source, "UTF-8")); JSONObject jsonObject = TokenUtils.doGetStr(url); String errno = jsonObject.getString("errno"); Object obj = jsonObject.get("data"); StringBuffer dst = new StringBuffer(); if("0".equals(errno) && !"[]".equals(obj.toString())){ TransResult transResult = (TransResult) JSONObject.toJavaObject(jsonObject, TransResult.class); Data data = transResult.getData(); Symbols symbols = data.getSymbols()[0]; String phzh = symbols.getPh_zh()==null ? "" : "中文拼音:"+symbols.getPh_zh()+" "; String phen = symbols.getPh_en()==null ? "" : "英式英標:"+symbols.getPh_en()+" "; String pham = symbols.getPh_am()==null ? "" : "美式英標:"+symbols.getPh_am()+" "; dst.append(phzh+phen+pham); Parts[] parts = symbols.getParts(); String pat = null; for(Parts part : parts){ pat = (part.getPart()!=null && !"".equals(part.getPart())) ? "["+part.getPart()+"]" : ""; String[] means = part.getMeans(); dst.append(pat); for(String mean : means){ dst.append(mean+";"); } } }else{ dst.append(translateFull(source)); } return dst.toString(); } /** * 句子翻譯 */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static String translateFull(String source) throws Exception{ String url = "http://openapi.baidu.com/public/2.0/bmt/translate?client_id=jNg0LPSBe691Il0CG5MwDupw&q=KEYWORD&from=auto&to=auto"; url = url.replace("KEYWORD", URLEncoder.encode(source, "UTF-8")); JSONObject jsonObject = TokenUtils.doGetStr(url); StringBuffer dst = new StringBuffer(); Listlist = (List ) jsonObject.get("trans_result"); for(Map map : list){ dst.append(map.get("dst")); } return dst.toString(); } }
6.修改MessageUtils類
package com.myimooc.wxdevadvanced.util; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.myimooc.wxdevadvanced.domain.Image; import com.myimooc.wxdevadvanced.domain.ImageMessage; import com.myimooc.wxdevadvanced.domain.Music; import com.myimooc.wxdevadvanced.domain.MusicMessage; import com.myimooc.wxdevadvanced.domain.News; import com.myimooc.wxdevadvanced.domain.NewsMessage; import com.myimooc.wxdevadvanced.domain.TextMessage; /** * 消息類型及工具類 * @author ZhangCheng on 2017-08-11 * */ public class MessageUtils { public static final String MESSAGE_TEXT = "text"; public static final String MESSAGE_NEWS = "news"; public static final String MESSAGE_IMAGE = "image"; public static final String MESSAGE_VOICE = "voice"; public static final String MESSAGE_MUSIC = "music"; public static final String MESSAGE_VIDEO = "video"; public static final String MESSAGE_LINK = "link"; public static final String MESSAGE_LOCATION = "location"; public static final String MESSAGE_EVENT = "event"; public static final String MESSAGE_SUBSCRIBE = "subscribe"; public static final String MESSAGE_UNSUBSCRIBE = "unsubscribe"; public static final String MESSAGE_CLICK = "CLICK"; public static final String MESSAGE_VIEW = "VIEW"; public static final String MESSAGE_SCANCODE = "scancode_push"; public static TextMessage initText(String toUserName,String fromUserName,String content){ TextMessage text = new TextMessage(); text.setFromUserName(toUserName); text.setToUserName(fromUserName); text.setMsgType(MessageUtils.MESSAGE_TEXT); text.setCreateTime(new Date().getTime()+""); text.setContent(content); return text; } /** * 主菜單 */ public static String menuText(){ StringBuffer sb = new StringBuffer(); sb.append("歡迎您的關注,請按照菜單提升進行操作: "); sb.append("1、課程介紹 "); sb.append("2、慕課網介紹 "); sb.append("3、詞組翻譯 "); sb.append("回復?顯示主菜單。"); return sb.toString(); } public static String firstMenu(){ StringBuffer sb = new StringBuffer(); sb.append("本套課程介紹微信公眾號開發,主要涉及公眾號介紹、編輯模式介紹、開發模式介紹等。"); return sb.toString(); } public static String secondMenu(){ StringBuffer sb = new StringBuffer(); sb.append("慕課網是垂直的互聯網IT技能免費學習網站。以獨家視頻教程、在線編程工具、學習計劃、" + "問答社區為核心特色。在這里,你可以找到最好的互聯網技術牛人,也可以通過免費的在線公" + "開視頻課程學習國內領先的互聯網IT技術。" + "慕課網課程涵蓋前端開發、PHP、Html5、Android、iOS、Swift等IT前沿技術語言," + "包括基礎課程、實用案例、高級分享三大類型,適合不同階段的學習人群。" + "以純干貨、短視頻的形式為平臺特點,為在校學生、職場白領提供了一個迅速提升技能、共同分享進步的學習平臺。"); return sb.toString(); } public static String threeMenu(){ StringBuffer sb = new StringBuffer(); sb.append("詞組翻譯使用指南 "); sb.append("使用示例: "); sb.append("翻譯足球: "); sb.append("翻譯中國足球 "); sb.append("翻譯football "); sb.append("回復?顯示主菜單。"); return sb.toString(); } /** * 圖文消息的組裝 */ public static NewsMessage initNewsMessage(String toUserNmae,String fromUserName){ ListnewsList = new ArrayList (); NewsMessage newsMessage = new NewsMessage(); News news = new News(); news.setTitle("慕課網介紹"); news.setDescription("慕課網是垂直的互聯網IT技能免費學習網站。以獨家視頻教程、在線編程工具、學習計劃、" + "問答社區為核心特色。在這里,你可以找到最好的互聯網技術牛人,也可以通過免費的在線公" + "開視頻課程學習國內領先的互聯網IT技術。" + "慕課網課程涵蓋前端開發、PHP、Html5、Android、iOS、Swift等IT前沿技術語言," + "包括基礎課程、實用案例、高級分享三大類型,適合不同階段的學習人群。" + "以純干貨、短視頻的形式為平臺特點,為在校學生、職場白領提供了一個迅速提升技能、共同分享進步的學習平臺。"); news.setPicUrl("http://imooc.jpg"); news.setUrl("www.imooc.com"); newsList.add(news); newsMessage.setToUserName(fromUserName); newsMessage.setFromUserName(toUserNmae); newsMessage.setCreateTime(new Date().getTime()+""); newsMessage.setMsgType(MESSAGE_NEWS); newsMessage.setArticles(newsList); newsMessage.setArticleCount(newsList.size()); return newsMessage; } /** * 圖片消息組裝 */ public static ImageMessage initImageMessage(String toUserName,String fromUserName){ Image image = new Image(); image.setMediaId("JTH8vBl0zDRlrrn2bBnMleySuHjVbMhyAo0U2x7kQyd1ciydhhsVPONbnRrKGp8m"); ImageMessage imageMessage = new ImageMessage(); imageMessage.setFromUserName(toUserName); imageMessage.setToUserName(fromUserName); imageMessage.setMsgType(MESSAGE_IMAGE); imageMessage.setCreateTime(new Date().getTime()+""); imageMessage.setImage(image); return imageMessage; } /** * 組裝音樂消息 * @param toUserName * @param fromUserName * @return */ public static MusicMessage initMusicMessage(String toUserName,String fromUserName){ Music music = new Music(); music.setThumbMediaId("WsHCQr1ftJQwmGUGhCP8gZ13a77XVg5Ah_uHPHVEAQuRE5FEjn-DsZJzFZqZFeFk"); music.setTitle("see you again"); music.setDescription("速7片尾曲"); music.setMusicUrl("http://zapper.tunnel.mobi/Weixin/resource/See You Again.mp3"); music.setHQMusicUrl("http://zapper.tunnel.mobi/Weixin/resource/See You Again.mp3"); MusicMessage musicMessage = new MusicMessage(); musicMessage.setFromUserName(toUserName); musicMessage.setToUserName(fromUserName); musicMessage.setMsgType(MESSAGE_MUSIC); musicMessage.setCreateTime(new Date().getTime()+""); musicMessage.setMusic(music); return musicMessage; } }
7.修改MessageRest類
package com.myimooc.wxdevadvanced.rest; import java.util.Date; import java.util.Map; import java.util.Objects; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import com.myimooc.wxdevadvanced.domain.EventMessage; import com.myimooc.wxdevadvanced.domain.NewsMessage; import com.myimooc.wxdevadvanced.domain.TextMessage; import com.myimooc.wxdevadvanced.util.MessageUtils; import com.myimooc.wxdevadvanced.util.WeixinUtils; /** * 處理消息請求與響應 * @author ZhangCheng on 2017-08-11 * */ @RestController public class MessageRest { private static final Logger logger = LoggerFactory.getLogger(MessageRest.class); /** * 接收微信服務器發送的POST請求 * @throws Exception */ @PostMapping("textmessage") public Object textmessage(TextMessage msg) throws Exception{ logger.info("請求參數:{}",msg.toString()); // 文本消息 if(Objects.equals(MessageUtils.MESSAGE_TEXT, msg.getMsgType())){ TextMessage textMessage = new TextMessage(); // 關鍵字 1 if(Objects.equals("1", msg.getContent())){ textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.firstMenu()); return textMessage; } // 關鍵字 2 if(Objects.equals("2", msg.getContent())){ NewsMessage newsMessage = MessageUtils.initNewsMessage(msg.getToUserName(), msg.getFromUserName()); return newsMessage; } // 關鍵字 3 if(Objects.equals("3", msg.getContent())){ textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.threeMenu()); return textMessage; } // 關鍵字 翻譯 if(msg.getContent().startsWith("翻譯")){ String word = msg.getContent().replaceAll("^翻譯","").trim(); if("".equals(word)){ textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.threeMenu()); return textMessage; } textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),WeixinUtils.translate(word)); return textMessage; } // 關鍵字 ?? 調出菜單 if(Objects.equals("?", msg.getContent()) || Objects.equals("?", msg.getContent())){ textMessage = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.menuText()); return textMessage; } // 非關鍵字 textMessage.setFromUserName(msg.getToUserName()); textMessage.setToUserName(msg.getFromUserName()); textMessage.setMsgType(MessageUtils.MESSAGE_TEXT); textMessage.setCreateTime(new Date().getTime()+""); textMessage.setContent("您發送的消息是:" + msg.getContent()); return textMessage; } return null; } /** * 接收微信服務器發送的POST請求 */ @PostMapping("eventmessage") public Object eventmessage(Mapparam){ EventMessage msg = new EventMessage(); BeanUtils.copyProperties(param, msg); // 事件推送 if(Objects.equals(MessageUtils.MESSAGE_EVENT, msg.getMsgType())){ // 關注 if(Objects.equals(MessageUtils.MESSAGE_SUBSCRIBE, msg.getEvent())){ TextMessage text = new TextMessage(); text = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.menuText()); return text; } // 菜單 點擊類型 if(Objects.equals(MessageUtils.MESSAGE_CLICK, msg.getEvent())){ TextMessage text = new TextMessage(); text = MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(), MessageUtils.menuText()); return text; } // 菜單 視圖類型 if(Objects.equals(MessageUtils.MESSAGE_VIEW, msg.getEvent())){ String url = param.get("EventKey"); return MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),url); } // 菜單 掃碼事件 if(Objects.equals(MessageUtils.MESSAGE_SCANCODE, msg.getEvent())){ String key = param.get("EventKey"); return MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),key); } // 菜單 地理位置 if(Objects.equals(MessageUtils.MESSAGE_LOCATION, msg.getEvent())){ String Label = param.get("Label"); return MessageUtils.initText(msg.getToUserName(), msg.getFromUserName(),Label); } } return "no message"; } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67600.html
摘要:時間年月日星期五說明本文部分內容均來自慕課網。本套課程介紹微信公眾號開發,主要涉及公眾號介紹編輯模式介紹開發模式介紹等。慕課網是垂直的互聯網技能免費學習網站。 時間:2017年08月11日星期五說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學源碼:https://github.com/zccodere/s...學習源碼:https://github...
摘要:時間年月日星期六說明本文部分內容均來自慕課網。第六章公眾號與開發平臺關聯公眾號與開放平臺關聯情景說明當使用端進行微信授權登錄時,得到的和公眾號授權登錄時得到的不一樣。 時間:2017年08月12日星期六說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學源碼:無學習源碼:https://github.com/zccodere/s... 第一章:課程介紹...
摘要:因為某些原因,不方便在這里直接發送百度鏈接,關注我的微信公眾號面試通關手冊回復資源分享第一波即可領取。然后大家還有什么問題的話,可以在我的微信公眾號后臺面試通關手冊給我說或者加我微信,我會根據自己的學習經驗給了說一下自己的看法。 這是一篇針對Java初學者,或者說在Java學習路線上出了一些問題(不知道該學什么、不知道整體的學習路線是什么樣的) 第一步:Java基礎(一個月左右) 推薦...
摘要:編程思想第版這本書要常讀,初學者可以快速概覽,中等程序員可以深入看看,老鳥還可以用之回顧的體系。以下視頻整理自慕課網工程師路徑相關免費課程。 我自己總結的Java學習的系統知識點以及面試問題,目前已經開源,會一直完善下去,歡迎建議和指導歡迎Star: https://github.com/Snailclimb/Java-Guide 筆者建議初學者學習Java的方式:看書+視頻+實踐(初...
摘要:時間年月日星期日說明本文部分內容均來自慕課網。慕課網教學示例源碼個人學習源碼第一章課程介紹課程介紹本課程緊接著小時學會課程,請先看入門課。異常返回通知在連接點拋出異常后執行。 時間:2017年3月19日星期日說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示例源碼:https://github.com/zccodere/s...個人學習源碼:htt...
閱讀 25629·2021-09-29 09:41
閱讀 4787·2021-09-10 11:20
閱讀 1918·2021-09-09 09:32
閱讀 1881·2019-08-30 15:44
閱讀 3192·2019-08-29 17:13
閱讀 2809·2019-08-29 14:14
閱讀 2062·2019-08-29 14:11
閱讀 3221·2019-08-29 12:36