微信素材管理和群發(fā)這塊文檔對java很不友好。本文只對新增臨時素材,新增永久素材做介紹,其余獲取、刪除、修改自行補充
公眾號經(jīng)常有需要用到一些臨時性的多媒體素材的場景,例如在使用接口特別是發(fā)送消息時,對多媒體文件、多媒體消息的獲取和調(diào)用等操作,是通過media_id來進行的。素材管理接口對所有認證的訂閱號和服務(wù)號開放。
素材的限制
圖片(image): 2m,支持png\jpeg\jpg\gif格式
語音(voice):2m,播放長度不超過60s,支持amr\mp3格式
視頻(video):10mb,支持mp4格式
縮略圖(thumb):64kb,支持jpg格式
一、新增臨時素材
接口:https://api.weixin.qq.com/cgi-bin/media/upload?access_token=access_token&type=type,再傳一個媒體文件類型,可以是圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb)。
1、訂閱號和服務(wù)號要通過認證
2、臨時素材media_id是可復(fù)用的
3、媒體文件在微信后臺保存時間為3天,即3天后media_id失效。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
/** * 上傳臨時素材(本地) * * @param accesstoken * @param type * 媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb) * @param path * 圖片路徑 * @return */ public static uploadmediasresult uploadtempmediafile(string accesstoken, string type, string path) { uploadmediasresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); params.put( "type" , type); try { string json = httpsuploadmediafile(systemconfig.post_method, wechatconfig.upload_temp_media_type_url, params, path); result = jsonutil.fromjsonstring(json, uploadmediasresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } /** * 上傳臨時素材(網(wǎng)絡(luò)) * * @param accesstoken * @param type * 媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb) * @param path * 圖片路徑 * @return */ public static uploadmediasresult uploadtempmedia(string accesstoken, string type, string path) { uploadmediasresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); params.put( "type" , type); try { string json = httpsuploadmedia(systemconfig.post_method, wechatconfig.upload_temp_media_type_url, params, path, 0 , 0 ); result = jsonutil.fromjsonstring(json, uploadmediasresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } |
二、新增永久素材
接口:https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=access_token&type=type,媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video,例外)和縮略圖(thumb)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
/** * 上傳永久素材(本地) * * @param accesstoken * @param type * 媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb) * @return */ public static uploadmediasresult uploadforevermediafile(string accesstoken, string type, string path) { uploadmediasresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); params.put( "type" , type); try { string json = httpsuploadmediafile(systemconfig.post_method, wechatconfig.upload_forever_media_type_url, params, path); result = jsonutil.fromjsonstring(json, uploadmediasresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } /** * 上傳永久素材(網(wǎng)絡(luò)) * * @param accesstoken * @param type * 媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb) * @return */ public static uploadmediasresult uploadforevermedia(string accesstoken, string type, string path) { uploadmediasresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); params.put( "type" , type); try { string json = httpsuploadmedia(systemconfig.post_method, wechatconfig.upload_forever_media_type_url, params, path, 0 , 0 ); result = jsonutil.fromjsonstring(json, uploadmediasresult. class ); } catch (exception e) { e.printstacktrace(); } return result; } |
新增永久視頻素材需特別注意,在上傳視頻素材時需要post另一個表單,id為description,包含素材的描述信息title和introduction,內(nèi)容格式為json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
/** * 上傳永久素材(video) * * @param accesstoken * @return */ public static string uploadforevermediafile(string accesstoken, string title, string introduction, string path) { treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); params.put( "type" , "video" ); string mediaid = null ; try { string json = httpsuploadvideomediafile(systemconfig.post_method, wechatconfig.upload_forever_media_type_url, params, path, title, introduction); mediaid = jsonutil.fromjsonstring(json, "media_id" ); } catch (exception e) { e.printstacktrace(); } return mediaid; } /** * 上傳永久素材(video,網(wǎng)絡(luò)) * * @param accesstoken * @return */ public static string uploadforevermedia(string accesstoken, string title, string introduction, string path) { treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); params.put( "type" , "video" ); string mediaid = null ; try { string json = httpsuploadvideomedia(systemconfig.post_method, wechatconfig.upload_forever_media_type_url, params, path, title, introduction, 0 , 0 ); mediaid = jsonutil.fromjsonstring(json, "media_id" ); } catch (exception e) { e.printstacktrace(); } return mediaid; } |
三、新增永久圖文素材
接口:https://api.weixin.qq.com/cgi-bin/material/add_news?access_token=access_token,post信息參見uploadnewsmedia 實體類
對于常用的素材,開發(fā)者可通過本接口上傳到微信服務(wù)器,永久使用.
1、永久圖片素材新增后,將帶有url返回給開發(fā)者,開發(fā)者可以在騰訊系域名內(nèi)使用(騰訊系域名外使用,圖片將被屏蔽)。
2、公眾號的素材庫保存總數(shù)量有上限:圖文消息素材、圖片素材上限為5000,其他類型為1000。
3、圖文消息的具體內(nèi)容中,微信后臺將過濾外部的圖片鏈接,圖片url需通過"上傳圖文消息內(nèi)的圖片獲取url"接口上傳圖片獲取。
4、"上傳圖文消息內(nèi)的圖片獲取url"接口所上傳的圖片,不占用公眾號的素材庫中圖片數(shù)量的5000個的限制,圖片僅支持jpg/png格式,大小必須在1mb以下。
5、圖文消息支持正文中插入自己帳號和其他公眾號已群發(fā)文章鏈接的能力。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/** * 上傳永久圖文消息的素材 * * @param accesstoken * 授權(quán)token * @param entity * 圖文消息對象 * @return */ public static uploadmediasresult uploadnewsmedia(string accesstoken, list<uploadnewsmedia> entity) { uploadmediasresult result = null ; treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); // post 提交的參數(shù) treemap<string, list<uploadnewsmedia>> dataparams = new treemap<string, list<uploadnewsmedia>>(); dataparams.put( "articles" , entity); string data = jsonutil.tojsonstring(dataparams); string json = httprequtil.httpsdefaultexecute(systemconfig.post_method, wechatconfig.upload_forever_news_media_url, params, data); result = jsonutil.fromjsonstring(json, uploadmediasresult. class ); return result; } |
四、上傳圖文消息內(nèi)的圖片獲取url
接口:https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=access_token
本接口所上傳的圖片不占用公眾號的素材庫中圖片數(shù)量的5000個的限制。圖片僅支持jpg/png格式,大小必須在1mb以下,此接口返回的url就是上傳圖片的url,可放置圖文消息中使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
/** * 上傳圖文消息內(nèi)的圖片獲取url(本地) * * @param accesstoken * @param path * @return */ public static string uploadimgmediafile(string accesstoken, string path) { treemap<string, string> params = new treemap<>(); params.put( "access_token" , accesstoken); string url = null ; try { string json = httpsuploadmediafile(systemconfig.post_method, wechatconfig.upload_img_media_url, params, path); url = jsonutil.fromjsonstring(json, "url" ); } catch (exception e) { e.printstacktrace(); } return url; } /** * 上傳圖文消息內(nèi)的圖片獲取url(網(wǎng)絡(luò)) * * @param accesstoken * @param path * @return */ public static string uploadimgmedia(string accesstoken, string path) { treemap<string, string> params = new treemap<string, string>(); params.put( "access_token" , accesstoken); string url = null ; try { string json = httpsuploadmedia(systemconfig.post_method, wechatconfig.upload_img_media_url, params, path, 0 , 0 ); url = jsonutil.fromjsonstring(json, "url" ); } catch (exception e) { e.printstacktrace(); } return url; } |
五、部分工具類
配置類
1
2
3
4
|
public static final string upload_img_media_url = "https://api.weixin.qq.com/cgi-bin/media/uploadimg" ; public static final string upload_forever_news_media_url = "https://api.weixin.qq.com/cgi-bin/material/add_news" ; public static final string upload_temp_media_type_url = "https://api.weixin.qq.com/cgi-bin/media/upload" ; public static final string upload_forever_media_type_url = "https://api.weixin.qq.com/cgi-bin/material/add_material" ; |
上傳圖文消息素材返回類
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package com.phil.wechat.msg.model.media; /** * 上傳圖文消息素材返回的結(jié)果 * @author phil * @date 2017年9月20日 * */ public class uploadmediasresult { private string type; // 媒體文件類型,分別有圖片(image)、語音(voice)、視頻(video)和縮略圖(thumb),次數(shù)為news,即圖文消息 private string media_id; // 媒體文件/圖文消息上傳后獲取的唯一標識 private string created_at; // 媒體文件上傳時間 } |
上傳圖文消息素材實體類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
package com.phil.wechat.msg.model.media; import java.io.serializable; /** * 上傳圖文消息素材實體類 * @author phil * @date 2017年9月20日 */ public class uploadnewsmedia implements serializable { private static final long serialversionuid = 6551817058101753854l; private string thumb_media_id; // 圖文消息縮略圖的media_id,可以在基礎(chǔ)支持-上傳多媒體文件接口中獲得 private string author; // 圖文消息的作者 private string title; // 圖文消息的標題 private string content_source_url; // 圖文消息點擊閱讀原文的鏈接 private string content; // 圖文消息頁面的內(nèi)容,支持html標簽 private string digest; // 圖文消息的描述 private int show_conver_pic; // 是否顯示為封面 1表示顯示為封面 0 不顯示為封面 } |
上傳方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
|
/** * 上傳媒體文件(本地) * * @param method * 請求方法 get/post * @param path * api的路徑 * @param param * api參數(shù) * @param mediapath * 待上傳的image/music 的path * @return * @throws exception */ public static string httpsuploadmediafile(string method, string path, map<string, string> param, string mediapath) throws exception { string result = null ; url url = new url(setparmas(param, path, "" )); outputstream output = null ; datainputstream inputstream = null ; try { file file = new file(mediapath); if (!file.isfile() || !file.exists()) { throw new ioexception( "file is not exist" ); } httpurlconnection con = (httpurlconnection) url.openconnection(); con.setdoinput( true ); con.setdooutput( true ); con.setusecaches( false ); con.setrequestmethod(systemconfig.post_method); // 設(shè)置請求頭信息 con.setrequestproperty( "connection" , "keep-alive" ); con.setrequestproperty( "charset" , systemconfig.default_character_encoding); // 設(shè)置邊界 string boundary = "----------" + system.currenttimemillis(); con.setrequestproperty( "content-type" , "multipart/form-data; boundary=" + boundary); // 請求正文信息 // 第一部分 output = new dataoutputstream(con.getoutputstream()); ioutils.write(( "--" + boundary + "\r\n" ).getbytes(systemconfig.default_character_encoding), output); ioutils.write(( "content-disposition: form-data;name=\"media\"; filename=\"" + file.getname() + "\"\r\n" ) .getbytes(systemconfig.default_character_encoding), output); ioutils.write( "content-type:application/octet-stream\r\n\r\n" .getbytes(systemconfig.default_character_encoding), output); // ioutils.write(("content-type: "+ fileext + "\r\n\r\n").getbytes(), output); // 文件正文部分 // 把文件已流文件的方式 推入到url中 inputstream = new datainputstream( new fileinputstream(file)); ioutils.copy(inputstream, output); // 結(jié)尾部分 ioutils.write(( "\r\n--" + boundary + "--\r\n" ).getbytes(systemconfig.default_character_encoding), output); output.flush(); result = inputstreamtostring(con.getinputstream()); } catch (malformedurlexception e) { e.printstacktrace(); } catch (protocolexception e) { e.printstacktrace(); } catch (ioexception e) { throw new ioexception( "read data error" ); } finally { ioutils.closequietly(output); ioutils.closequietly(inputstream); } return result; } /** * 上傳媒體文件(不能本地) * * @param method * 請求方法 get/post * @param path * api的路徑 * @param param * api參數(shù) * @param mediapath * 待上傳的image/music 的path * @param conntime * 連接時間 默認為5000 * @param readtime * 讀取時間 默認為5000 * @return * @throws exception */ public static string httpsuploadmedia(string method, string path, map<string, string> param, string mediapath, int conntime, int readtime) throws exception { string result = "" ; url url = new url(setparmas(param, path, "" )); outputstream output = null ; bufferedinputstream inputstream = null ; try { string boundary = "----" ; httpurlconnection conn = getconnection(method, url); conn.setconnecttimeout(conntime == 0 ? default_conntime : conntime); conn.setreadtimeout(readtime == 0 ? default_upload_readtime : readtime); conn.setrequestproperty( "content-type" , "multipart/form-data;boundary=" + boundary); output = conn.getoutputstream(); url mediaurl = new url(mediapath); if (mediaurl != null ) { httpurlconnection mediaconn = (httpurlconnection) mediaurl.openconnection(); mediaconn.setdooutput( true ); mediaconn.setusecaches( false ); mediaconn.setrequestmethod(systemconfig.get_method); mediaconn.setconnecttimeout(conntime == 0 ? default_conntime : conntime); mediaconn.setreadtimeout(readtime == 0 ? default_upload_readtime : readtime); string conntype = mediaconn.getcontenttype(); // 獲得文件擴展 string fileext = getfileext(conntype); ioutils.write(( "--" + boundary + "\r\n" ).getbytes(), output); ioutils.write(( "content-disposition: form-data; name=\"media\"; filename=\"" + getfilename(mediapath) + "\"\r\n" ).getbytes(), output); ioutils.write(( "content-type: " + fileext + "\r\n\r\n" ).getbytes(), output); inputstream = new bufferedinputstream(mediaconn.getinputstream()); ioutils.copy(inputstream, output); ioutils.write(( "\r\n----" + boundary + "--\r\n" ).getbytes(), output); mediaconn.disconnect(); // 獲取輸入流 result = inputstreamtostring(conn.getinputstream()); } } catch (malformedurlexception e) { e.printstacktrace(); } catch (protocolexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } finally { ioutils.closequietly(output); ioutils.closequietly(inputstream); } return result; } /** * 上傳video媒體文件(本地) * * @param method * 請求方法 get/post * @param path * api的路徑 * @param param * api參數(shù) * @param mediapath * 待上傳的voide 的path * @param title * 視頻標題 * @param introduction * 視頻描述 * @return * @throws exception */ public static string httpsuploadvideomediafile(string method, string path, map<string, string> param, string mediapath, string title, string introduction) throws exception { string result = null ; url url = new url(setparmas(param, path, "" )); outputstream output = null ; datainputstream inputstream = null ; try { file file = new file(mediapath); if (!file.isfile() || !file.exists()) { throw new ioexception( "file is not exist" ); } httpurlconnection con = (httpurlconnection) url.openconnection(); con.setdoinput( true ); con.setdooutput( true ); con.setusecaches( false ); con.setrequestmethod(systemconfig.post_method); // 設(shè)置請求頭信息 con.setrequestproperty( "connection" , "keep-alive" ); con.setrequestproperty( "charset" , systemconfig.default_character_encoding); // 設(shè)置邊界 string boundary = "----------" + system.currenttimemillis(); con.setrequestproperty( "content-type" , "multipart/form-data; boundary=" + boundary); // 請求正文信息 // 第一部分 output = new dataoutputstream(con.getoutputstream()); ioutils.write(( "--" + boundary + "\r\n" ).getbytes(systemconfig.default_character_encoding), output); ioutils.write(( "content-disposition: form-data;name=\"media\"; filename=\"" + file.getname() + "\"\r\n" ) .getbytes(), output); ioutils.write( "content-type: video/mp4 \r\n\r\n" .getbytes(), output); // 文件正文部分 // 把文件已流文件的方式 推入到url中 inputstream = new datainputstream( new fileinputstream(file)); ioutils.copy(inputstream, output); // 結(jié)尾部分 ioutils.write(( "--" + boundary + "\r\n" ).getbytes(systemconfig.default_character_encoding), output); ioutils.write( "content-disposition: form-data; name=\"description\";\r\n\r\n" .getbytes(systemconfig.default_character_encoding), output); ioutils.write(( "{\"title\":\"" + title + "\",\"introduction\":\"" + introduction + "\"}" ) .getbytes(systemconfig.default_character_encoding), output); ioutils.write(( "\r\n--" + boundary + "--\r\n\r\n" ).getbytes(systemconfig.default_character_encoding), output); output.flush(); result = inputstreamtostring(con.getinputstream()); } catch (malformedurlexception e) { e.printstacktrace(); } catch (protocolexception e) { e.printstacktrace(); } catch (ioexception e) { throw new ioexception( "read data error" ); } finally { ioutils.closequietly(output); ioutils.closequietly(inputstream); } return result; } /** * 上傳video媒體文件(網(wǎng)絡(luò)) * * @param method * 請求方法 get/post * @param path * api的路徑 * @param param * api參數(shù) * @param mediapath * 待上傳的voide 的path * @param title * 視頻標題 * @param introduction * 視頻描述 * @param conntime * 連接時間 默認為5000 * @param readtime * 讀取時間 默認為5000 * @return * @throws exception */ public static string httpsuploadvideomedia(string method, string path, map<string, string> param, string mediapath, string title, string introduction, int conntime, int readtime) throws exception { string result = null ; url url = new url(setparmas(param, path, "" )); outputstream output = null ; bufferedinputstream inputstream = null ; try { string boundary = "----" ; httpurlconnection conn = getconnection(method, url); conn.setconnecttimeout(conntime == 0 ? default_conntime : conntime); conn.setreadtimeout(readtime == 0 ? default_upload_readtime : readtime); conn.setrequestproperty( "content-type" , "multipart/form-data;boundary=" + boundary); output = conn.getoutputstream(); url mediaurl = new url(mediapath); if (mediaurl != null ) { httpurlconnection mediaconn = (httpurlconnection) mediaurl.openconnection(); mediaconn.setdooutput( true ); mediaconn.setusecaches( false ); mediaconn.setrequestmethod(systemconfig.get_method); mediaconn.setconnecttimeout(conntime == 0 ? default_conntime : conntime); mediaconn.setreadtimeout(readtime == 0 ? default_upload_readtime : readtime); ioutils.write(( "--" + boundary + "\r\n" ).getbytes(), output); ioutils.write(( "content-disposition: form-data; name=\"media\"; filename=\"" + getfilename(mediapath) + "\"\r\n" ).getbytes(), output); ioutils.write( "content-type: video/mp4 \r\n\r\n" .getbytes(), output); inputstream = new bufferedinputstream(mediaconn.getinputstream()); ioutils.copy(inputstream, output); // 結(jié)尾部分 ioutils.write(( "--" + boundary + "\r\n" ).getbytes(systemconfig.default_character_encoding), output); ioutils.write( "content-disposition: form-data; name=\"description\";\r\n\r\n" .getbytes(systemconfig.default_character_encoding), output); ioutils.write(( "{\"title\":\"" + title + "\",\"introduction\":\"" + introduction + "\"}" ) .getbytes(systemconfig.default_character_encoding), output); ioutils.write(( "\r\n--" + boundary + "--\r\n\r\n" ).getbytes(systemconfig.default_character_encoding), output); mediaconn.disconnect(); // 獲取輸入流 result = inputstreamtostring(conn.getinputstream()); } } catch (malformedurlexception e) { e.printstacktrace(); } catch (protocolexception e) { e.printstacktrace(); } catch (ioexception e) { throw new ioexception( "read data error" ); } finally { ioutils.closequietly(output); ioutils.closequietly(inputstream); } return result; } |
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://blog.csdn.net/phil_jing/article/details/78755782