微信開發者模式下的功能之一獲取素材列表並保存的方法瞭解一下:java
寫這個方法確定也是根據微信開發文檔說明總結出獲取的方法,首先先看微信開發文檔給出的內容獲取方法接口提示:數據庫
先給個連接地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1444738734json
首先文檔主要部分接口參數說明:api
這裏建議須要調用的接口請求連接爲了防止錯誤最好仍是本身複製下來用,請注意請求方式「POST」和請求的協議。微信
接下來時文檔給出的獲取列表的返回形式:微信開發
返回形式中的參數說明:app
好了,這就是微信開發文檔中給出的全部獲取素材列表的說明了,接下來咱們要根據這些說明本身定義一個方法去實現這個過程,直接上代碼:dom
首先在開發工具中頂一個通用工具類:CommonUtil.java,在這裏面實現所須要的方法:ide
1 import org.slf4j.Logger; 2 import org.slf4j.LoggerFactory; 3 4 5 /** 6 * 通用工具類 7 * @author Admin 8 * 9 */ 10 public class CommonUtil { 11 private static Logger log = LoggerFactory.getLogger(CommonUtil.class);//定義日誌獲取狀態輸出 12 13 // 憑證獲取 14 //獲取access_token 15 public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET"; 16 //獲取素材列表 17 public final static String MATERIAL = "https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN"; 18 19 20 }
這個工具類大致就是這個樣式,該有的說明我都標註了,所須要調用的接口請直接複製便可,避免出錯。工具
微信公衆號開發都是須要調取接口的,在這個公共工具類中首先先寫一個發送https請求的方法:
1 /** 2 * 發送https請求 3 * 4 * @param requestUrl 請求地址 5 * @param requestMethod 請求方式(GET、POST) 6 * @param outputStr 提交的數據 7 * @return JSONObject(經過JSONObject.get(key)的方式獲取json對象的屬性值) 8 */ 9 public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) { 10 JSONObject jsonObject = null; 11 try { 12 // 建立SSLContext對象,並使用咱們指定的信任管理器初始化 13 TrustManager[] tm = { new MyX509TrustManager() }; 14 SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); 15 sslContext.init(null, tm, new java.security.SecureRandom()); 16 // 從上述SSLContext對象中獲得SSLSocketFactory對象 17 SSLSocketFactory ssf = sslContext.getSocketFactory(); 18 19 URL url = new URL(requestUrl); 20 HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); 21 conn.setSSLSocketFactory(ssf); 22 23 conn.setDoOutput(true); 24 conn.setDoInput(true); 25 conn.setUseCaches(false); 26 // 設置請求方式(GET/POST) 27 conn.setRequestMethod(requestMethod); 28 29 // 當outputStr不爲null時向輸出流寫數據 30 if (null != outputStr) { 31 OutputStream outputStream = conn.getOutputStream(); 32 // 注意編碼格式 33 outputStream.write(outputStr.getBytes("UTF-8")); 34 outputStream.close(); 35 } 36 37 // 從輸入流讀取返回內容 38 InputStream inputStream = conn.getInputStream(); 39 InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); 40 BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 41 String str = null; 42 StringBuffer buffer = new StringBuffer(); 43 while ((str = bufferedReader.readLine()) != null) { 44 buffer.append(str); 45 } 46 47 // 釋放資源 48 bufferedReader.close(); 49 inputStreamReader.close(); 50 inputStream.close(); 51 inputStream = null; 52 conn.disconnect(); 53 jsonObject = JSONObject.fromObject(buffer.toString()); 54 } catch (ConnectException ce) { 55 log.error("鏈接超時:{}", ce); 56 } catch (Exception e) { 57 log.error("https請求異常:{}", e); 58 } 59 return jsonObject; 60 }
而後是獲取素材列表所須要的方法(這裏是獲取的圖文消息):
1 /** 2 * 獲取素材列表並存入集合中 3 * @param accessToken 獲取接口憑證的惟一標識 4 * @param type 素材的類型,圖片(image)、視頻(video)、語音 (voice)、圖文(news) 5 * @param offset 從所有素材的該偏移位置開始返回,0表示從第一個素材 返回 6 * @param count 返回素材的數量,取值在1到20之間 7 * @return 8 */ 9 public static List<Material> getMaterial(String accessToken,String type,int offset,int count) { 10 List<Material> lists = new ArrayList<Material>();//定義圖文素材實體類集合 11 String outputStr="";//定義一個空的參數字符串 12 String requestUrl = MATERIAL.replace("ACCESS_TOKEN", accessToken);//替換調access_token 13 MaterialParam para = new MaterialParam();//調用接口所須要的參數實體類 14 para.setType(type); 15 para.setOffset(offset); 16 para.setCount(count); 17 JSONObject jsonObject = new JSONObject(); 18 jsonObject = JSONObject.fromObject(para); 19 outputStr = jsonObject.toString();//將參數對象轉換成json字符串 20 21 jsonObject = httpsRequest(requestUrl, "POST", outputStr); //發送https請求(請求的路徑,方式,所攜帶的參數) 22 // 若是請求成功 23 if (null != jsonObject) { 24 try { 25 JSONArray jsonArray = jsonObject.getJSONArray("item"); 26 for (int i = 0; i < jsonArray.size(); i++) { 27 JSONObject json = (JSONObject) jsonArray.get(i); 28 json = json.getJSONObject("content"); 29 System.out.println(json); 30 31 JSONArray arr = json.getJSONArray("news_item"); 32 json = (JSONObject) arr.get(0); 33 34 Material material = new Material(); 35 String title = json.getString("title"); 36 String author = json.getString("author"); 37 String digest = json.getString("digest"); 38 String thumb_media_id = json.getString("thumb_media_id"); 39 //System.out.println(thumb_media_id); 40 String url = json.getString("url"); 41 String content = json.getString("content"); 42 material.setTitle(title); 43 material.setAuthor(author); 44 material.setDigest(digest); 45 material.setThumb_media_id(thumb_media_id); 46 material.setUrl(url); 47 material.setContent(content); 48 material.setShow_cover_pic(1); 49 lists.add(material); 50 } 51 } catch (JSONException e) { 52 accessToken = null; 53 // 獲取Material失敗 54 log.error("獲取Material失敗 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg")); 55 } 56 } 57 return lists; 58 }
上面全部的方法說明均已備註上,裏面的用到的實體類爲:
獲取素材列表參數實體類Material.java:
1 package com.shihe.shcoud.utils.pojo; 2 /*獲取素材列表參數實體類**/ 3 public class Material { 4 5 private String title;//圖文消息的標題 6 7 private String thumb_media_id;//圖文消息的封面圖片素材id(必須是永久mediaID) 8 9 private String author;//做者 10 11 private String digest;//圖文消息的摘要,僅有單圖文消息纔有摘要,多圖文此處爲空 12 13 private String content;//圖文消息的具體內容,支持HTML標籤,必須少於2萬字符,小於1M,且此處會去除JS 14 15 private String url;//圖文頁的URL,或者,當獲取的列表是圖片素材列表時,該字段是圖片的URL 16 17 private int show_cover_pic;//是否顯示封面,0爲false,即不顯示,1爲true,即顯示 18 19 public String getTitle() { 20 return title; 21 } 22 public void setTitle(String title) { 23 this.title = title; 24 } 25 public String getThumb_media_id() { 26 return thumb_media_id; 27 } 28 public void setThumb_media_id(String thumb_media_id) { 29 this.thumb_media_id = thumb_media_id; 30 } 31 public String getAuthor() { 32 return author; 33 } 34 public void setAuthor(String author) { 35 this.author = author; 36 } 37 public String getDigest() { 38 return digest; 39 } 40 public void setDigest(String digest) { 41 this.digest = digest; 42 } 43 public String getContent() { 44 return content; 45 } 46 public void setContent(String content) { 47 this.content = content; 48 } 49 public String getUrl() { 50 return url; 51 } 52 public void setUrl(String url) { 53 this.url = url; 54 } 55 public int getShow_cover_pic() { 56 return show_cover_pic; 57 } 58 public void setShow_cover_pic(int show_cover_pic) { 59 this.show_cover_pic = show_cover_pic; 60 } 61 62 }
獲取素材列表調用接口所須要的參數實體類MaterialParam.java:
1 package com.shihe.shcoud.utils.pojo; 2 /*獲取素材列表調用接口所須要的參數實體類**/ 3 public class MaterialParam { 4 5 private String type;//素材的類型,圖片(image)、視頻(video)、語音 (voice)、圖文(news) 6 7 private int offset;//從所有素材的該偏移位置開始返回,0表示從第一個素材 返回 8 9 private int count;//返回素材的數量,取值在1到20之間 10 11 public String getType() { 12 return type; 13 } 14 15 public void setType(String type) { 16 this.type = type; 17 } 18 19 public int getOffset() { 20 return offset; 21 } 22 23 public void setOffset(int offset) { 24 this.offset = offset; 25 } 26 27 public int getCount() { 28 return count; 29 } 30 31 public void setCount(int count) { 32 this.count = count; 33 } 34 35 }
注意重寫get和set方法。
接下即是測試所寫的方法是否能獲取到素材列表信息了,這裏我用的JUnit測試:
1 public class MaterialTest { 2 3 @Test 4 public void testGetMaterial() { 5 Token token = CommonUtil.getToken(WeChatConfig.APP_ID,WeChatConfig.APP_SECRET);//獲取接口訪問憑證access_token 6 List<Material> lists = CommonUtil.getMaterial(token.getAccessToken(),"news",0,10);//調用獲取素材列表的方法 7 System.out.println(lists.size());//輸出 8 } 9 }
這裏我獲取的是素材列表是圖文消息,type類型也就是「news」圖文消息,offset爲0,也就是從第一個開始獲取,count爲10,獲取素材的數量。
這裏我寫的輸出語句爲存入list裏面的素材數量。運行輸出,正常輸出結果。
若是想看到輸出的具體數據,在獲取素材列表方法的for循環中我寫了一個輸出語句:System.out.println(json);這樣運行就能夠看出所須要獲取到的素材列表內容了。
若是是要獲取到圖片素材列表的,能夠將getMaterial方法中的第10行定義圖文素材類的集合替換爲:List<MaterialImage> list = new ArrayList<MaterialImage>();
而後將try catch裏面的獲取圖文素材列表的方法給替換爲相應的獲取圖片素材的方法,具體方法爲:
1 JSONArray jsonArray = jsonObject.getJSONArray("item"); 2 for (int i = 0; i < jsonArray.size(); i++) { 3 JSONObject json = (JSONObject) jsonArray.get(i); 4 MaterialImage image = new MaterialImage(); 5 image.setMedia_id(json.getString("media_id")); 6 image.setName(json.getString("name")); 7 try { 8 /**舊的image 沒有url 需處理異常 新添加的有url*/ 9 image.setUrl(json.getString("url")); 10 } catch (Exception e) { 11 System.out.println("url 不存在異常"); 12 } 13 list.add(image);
其中用到的MaterialImage實體類方法爲:
1 /**素材圖片實體類*/ 2 public class MaterialImage { 3 4 //要獲取的素材的media_id 5 private String media_id; 6 //文件名稱 7 private String name; 8 //圖片的URL 9 private String url; 10 11 public String getMedia_id() { 12 return media_id; 13 } 14 15 public void setMedia_id(String media_id) { 16 this.media_id = media_id; 17 } 18 19 public String getName() { 20 return name; 21 } 22 23 public void setName(String name) { 24 this.name = name; 25 } 26 27 public String getUrl() { 28 return url; 29 } 30 31 public void setUrl(String url) { 32 this.url = url; 33 } 34 35 36 }
處處,所須要的方法寫完了。本身內測尚未出現什麼問題,原本測試的也很少。至於想把這些數據存入數據庫等,本身寫個數據表,寫個批量插入便可。
在此提供一下獲取access_token的方法,我也是寫在這個工具類中的:
1 /** 2 * 獲取接口訪問憑證 3 * 4 * @param appid 憑證 5 * @param appsecret 密鑰 6 * @return 7 */ 8 public static Token getToken(String appid, String appsecret) { 9 Token token = null; 10 String requestUrl = token_url.replace("APPID", appid).replace("APPSECRET", appsecret);//替換相應的參數 11 // 發起GET請求獲取憑證 12 JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);//發送https請求 13 if (null != jsonObject) { 14 try { 15 token = new Token(); 16 token.setAccessToken(jsonObject.getString("access_token")); 17 token.setExpiresIn(jsonObject.getInt("expires_in")); 18 } catch (JSONException e) { 19 token = null; 20 // 獲取token失敗 21 log.error("獲取token失敗 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg")); 22 } 23 } 24 return token; 25 }
調用這個方法獲取到的有兩個值:access_token獲取到的憑證和expires_in憑證有效時間,單位爲秒。這個方法中所須要的參數就是你公衆微信號上的appID和appsecret,對應填入便可。
順便給個接口憑證的實體類Token.java和JUnit測試方法:
1 /** 2 * 憑證 3 * access_token 4 * @author Admin 5 * 6 */ 7 public class Token { 8 9 // 接口訪問憑證 10 private String accessToken; 11 // 憑證有效期,單位:秒 12 private int expiresIn; 13 14 public String getAccessToken() { 15 return accessToken; 16 } 17 public void setAccessToken(String accessToken) { 18 this.accessToken = accessToken; 19 } 20 public int getExpiresIn() { 21 return expiresIn; 22 } 23 public void setExpiresIn(int expiresIn) { 24 this.expiresIn = expiresIn; 25 } 26 }
JUnit測試的方法:
1 @Test 2 public void testGetToken2() { 3 Token token = CommonUtil.getToken(WeChatConfig.APP_ID,WeChatConfig.APP_SECRET);//其中的WeChatConfig方法中有定義的本身微信公衆號的appid和appsecret值 用到時直接調用 4 System.out.println("access_token:"+token.getAccessToken()); 5 System.out.println("expires_in:"+token.getExpiresIn()); 6 }
替換相應的appID和appsecret便可。
上面即時獲取的所有方法了,具體實現測試後在作後期修改,溜了。