微信公众号开发之获取素材列表并保存

时间:2024-02-20 17:12:01

微信开发者模式下的功能之一获取素材列表并保存的方法了解一下

写这个方法肯定也是根据微信开发文档说明总结出获取的方法,首先先看微信开发文档给出的内容获取方法接口提示:

先给个链接地址https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1444738734

首先文档主要部分接口参数说明

这里建议需要调用的接口请求链接为了防止错误最好还是自己复制下来用,请注意请求方式“POST”和请求的协议。

接下来时文档给出的获取列表的返回形式:

返回形式中的参数说明:

好了,这就是微信开发文档中给出的所有获取素材列表的说明了,接下来我们要根据这些说明自己定义一个方法去实现这个过程,直接上代码:

首先在开发工具中顶一个通用工具类:CommonUtil.java,在这里面实现所需要的方法:

 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.javaJUnit测试方法:

 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即可。

上面即时获取的全部方法了,具体实现测试后在做后期修改,溜了。