1 package com.foxinmy.weixin4j.mp.api;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.UnsupportedEncodingException;
7 import java.util.ArrayList;
8 import java.util.Date;
9 import java.util.List;
10
11 import com.alibaba.fastjson.JSON;
12 import com.alibaba.fastjson.JSONObject;
13 import com.alibaba.fastjson.TypeReference;
14 import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
15 import com.foxinmy.weixin4j.exception.WeixinException;
16 import com.foxinmy.weixin4j.http.ContentType;
17 import com.foxinmy.weixin4j.http.HttpHeaders;
18 import com.foxinmy.weixin4j.http.HttpMethod;
19 import com.foxinmy.weixin4j.http.HttpRequest;
20 import com.foxinmy.weixin4j.http.HttpResponse;
21 import com.foxinmy.weixin4j.http.MimeType;
22 import com.foxinmy.weixin4j.http.apache.content.ByteArrayBody;
23 import com.foxinmy.weixin4j.http.apache.content.InputStreamBody;
24 import com.foxinmy.weixin4j.http.apache.content.StringBody;
25 import com.foxinmy.weixin4j.http.apache.mime.FormBodyPart;
26 import com.foxinmy.weixin4j.http.entity.StringEntity;
27 import com.foxinmy.weixin4j.http.weixin.ApiResult;
28 import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
29 import com.foxinmy.weixin4j.model.Token;
30 import com.foxinmy.weixin4j.model.media.MediaCounter;
31 import com.foxinmy.weixin4j.model.media.MediaDownloadResult;
32 import com.foxinmy.weixin4j.model.media.MediaItem;
33 import com.foxinmy.weixin4j.model.media.MediaRecord;
34 import com.foxinmy.weixin4j.model.media.MediaUploadResult;
35 import com.foxinmy.weixin4j.model.paging.Pageable;
36 import com.foxinmy.weixin4j.token.TokenManager;
37 import com.foxinmy.weixin4j.tuple.MpArticle;
38 import com.foxinmy.weixin4j.tuple.MpVideo;
39 import com.foxinmy.weixin4j.type.MediaType;
40 import com.foxinmy.weixin4j.util.Consts;
41 import com.foxinmy.weixin4j.util.FileUtil;
42 import com.foxinmy.weixin4j.util.IOUtil;
43 import com.foxinmy.weixin4j.util.ObjectId;
44 import com.foxinmy.weixin4j.util.RegexUtil;
45 import com.foxinmy.weixin4j.util.StringUtil;
46
47
48
49
50
51
52
53
54
55 public class MediaApi extends MpApi {
56
57 private final TokenManager tokenManager;
58
59 public MediaApi(TokenManager tokenManager) {
60 this.tokenManager = tokenManager;
61 }
62
63
64
65
66
67
68
69
70
71
72
73
74 public String uploadImage(InputStream is, String fileName)
75 throws WeixinException {
76 if (StringUtil.isBlank(fileName)) {
77 fileName = ObjectId.get().toHexString();
78 }
79 if (StringUtil.isBlank(FileUtil.getFileExtension(fileName))) {
80 fileName = String.format("%s.jpg", fileName);
81 }
82 String image_upload_uri = getRequestUri("image_upload_uri");
83 MimeType mimeType = new MimeType("image",
84 FileUtil.getFileExtension(fileName));
85 Token token = tokenManager.getCache();
86 WeixinResponse response = weixinExecutor.post(
87 String.format(image_upload_uri, token.getAccessToken()),
88 new FormBodyPart("media", new InputStreamBody(is, mimeType
89 .toString(), fileName)));
90 return response.getAsJson().getString("url");
91 }
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 public MpVideo uploadVideo(InputStream is, String fileName, String title,
111 String description) throws WeixinException {
112 MediaUploadResult uploadResult = uploadMedia(false, is, fileName);
113 JSONObject obj = new JSONObject();
114 obj.put("media_id", uploadResult.getMediaId());
115 obj.put("title", title);
116 obj.put("description", description);
117 String video_upload_uri = getRequestUri("video_upload_uri");
118 Token token = tokenManager.getCache();
119 WeixinResponse response = weixinExecutor.post(
120 String.format(video_upload_uri, token.getAccessToken()),
121 obj.toJSONString());
122
123 String mediaId = response.getAsJson().getString("media_id");
124 return new MpVideo(mediaId);
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 public MediaUploadResult uploadMedia(boolean isMaterial, InputStream is,
151 String fileName) throws WeixinException {
152 byte[] content;
153 try {
154 content = IOUtil.toByteArray(is);
155 } catch (IOException e) {
156 throw new WeixinException(e);
157 }
158 if (StringUtil.isBlank(fileName)) {
159 fileName = ObjectId.get().toHexString();
160 }
161 String suffixName = FileUtil.getFileExtension(fileName);
162 if (StringUtil.isBlank(suffixName)) {
163 suffixName = FileUtil
164 .getFileType(new ByteArrayInputStream(content));
165 fileName = String.format("%s.%s", fileName, suffixName);
166 }
167 MediaType mediaType;
168 if (",bmp,png,jpeg,jpg,gif,"
169 .contains(String.format(",%s,", suffixName))) {
170 mediaType = MediaType.image;
171 } else if (",mp3,wma,wav,amr,".contains(String.format(",%s,",
172 suffixName))) {
173 mediaType = MediaType.voice;
174 } else if (",rm,rmvb,wmv,avi,mpg,mpeg,mp4,".contains(String.format(
175 ",%s,", suffixName))) {
176 mediaType = MediaType.video;
177 } else {
178 throw new WeixinException("cannot handle mediaType:" + suffixName);
179 }
180 if (mediaType == MediaType.video && isMaterial) {
181 throw new WeixinException(
182 "please invoke uploadMaterialVideo method");
183 }
184 Token token = tokenManager.getCache();
185 WeixinResponse response = null;
186 try {
187 if (isMaterial) {
188 String material_media_upload_uri = getRequestUri("material_media_upload_uri");
189 response = weixinExecutor.post(
190 String.format(material_media_upload_uri,
191 token.getAccessToken()),
192 new FormBodyPart("media", new ByteArrayBody(content,
193 mediaType.getMimeType().toString(), fileName)),
194 new FormBodyPart("type", new StringBody(mediaType
195 .name(), Consts.UTF_8)));
196 JSONObject obj = response.getAsJson();
197 return new MediaUploadResult(obj.getString("media_id"),
198 mediaType, new Date(), obj.getString("url"));
199 } else {
200 String media_upload_uri = getRequestUri("media_upload_uri");
201 response = weixinExecutor.post(String.format(media_upload_uri,
202 token.getAccessToken(), mediaType.name()),
203 new FormBodyPart("media", new InputStreamBody(
204 new ByteArrayInputStream(content), mediaType
205 .getMimeType().toString(), fileName)));
206 JSONObject obj = response.getAsJson();
207 return new MediaUploadResult(obj.getString("media_id"),
208 obj.getObject("type", MediaType.class), new Date(
209 obj.getLong("created_at") * 1000l),
210 obj.getString("url"));
211 }
212 } catch (UnsupportedEncodingException e) {
213 throw new WeixinException(e);
214 } finally {
215 try {
216 is.close();
217 } catch (IOException e) {
218 ;
219 }
220 }
221 }
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239 public MediaDownloadResult downloadMedia(String mediaId, boolean isMaterial)
240 throws WeixinException {
241 Token token = tokenManager.getCache();
242 HttpRequest request = null;
243 if (isMaterial) {
244 String material_media_download_uri = getRequestUri("material_media_download_uri");
245 request = new HttpRequest(HttpMethod.POST, String.format(
246 material_media_download_uri, token.getAccessToken()));
247 request.setEntity(new StringEntity(String.format(
248 "{\"media_id\":\"%s\"}", mediaId)));
249 } else {
250 String meida_download_uri = getRequestUri("meida_download_uri");
251 request = new HttpRequest(HttpMethod.GET, String.format(
252 meida_download_uri, token.getAccessToken(), mediaId));
253 }
254 HttpResponse response = weixinExecutor.doRequest(request);
255 HttpHeaders headers = response.getHeaders();
256 String contentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
257 String disposition = headers.getFirst(HttpHeaders.CONTENT_DISPOSITION);
258 String fileName = RegexUtil
259 .regexFileNameFromContentDispositionHeader(disposition);
260 if (StringUtil.isBlank(fileName)) {
261 fileName = String.format("%s.%s", mediaId,
262 contentType.split("/")[1]);
263 }
264 return new MediaDownloadResult(response.getContent(),
265 ContentType.create(contentType), fileName);
266 }
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283 public String uploadMaterialArticle(List<MpArticle> articles)
284 throws WeixinException {
285 Token token = tokenManager.getCache();
286 String material_article_upload_uri = getRequestUri("material_article_upload_uri");
287 JSONObject obj = new JSONObject();
288 obj.put("articles", articles);
289 WeixinResponse response = weixinExecutor.post(
290 String.format(material_article_upload_uri,
291 token.getAccessToken()), obj.toJSONString());
292
293 return response.getAsJson().getString("media_id");
294 }
295
296
297
298
299
300
301
302
303
304
305
306 public List<MpArticle> downloadArticle(String mediaId)
307 throws WeixinException {
308 MediaDownloadResult result = downloadMedia(mediaId, true);
309 byte[] content = result.getContent();
310 JSONObject obj = JSON.parseObject(content, 0, content.length,
311 Consts.UTF_8.newDecoder(), JSONObject.class);
312 return JSON.parseArray(obj.getString("news_item"), MpArticle.class);
313 }
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330 public ApiResult updateMaterialArticle(String mediaId, int index,
331 MpArticle article) throws WeixinException {
332 Token token = tokenManager.getCache();
333 String material_article_update_uri = getRequestUri("material_article_update_uri");
334 JSONObject obj = new JSONObject();
335 obj.put("articles", article);
336 obj.put("media_id", mediaId);
337 obj.put("index", index);
338 WeixinResponse response = weixinExecutor.post(
339 String.format(material_article_update_uri,
340 token.getAccessToken()), obj.toJSONString());
341
342 return response.getAsResult();
343 }
344
345
346
347
348
349
350
351
352
353
354
355 public ApiResult deleteMaterialMedia(String mediaId) throws WeixinException {
356 Token token = tokenManager.getCache();
357 String material_media_del_uri = getRequestUri("material_media_del_uri");
358 JSONObject obj = new JSONObject();
359 obj.put("media_id", mediaId);
360 WeixinResponse response = weixinExecutor.post(
361 String.format(material_media_del_uri, token.getAccessToken()),
362 obj.toJSONString());
363
364 return response.getAsResult();
365 }
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383 public String uploadMaterialVideo(InputStream is, String fileName,
384 String title, String introduction) throws WeixinException {
385 if (StringUtil.isBlank(fileName)) {
386 fileName = ObjectId.get().toHexString();
387 }
388 if (StringUtil.isBlank(FileUtil.getFileExtension(fileName))) {
389 fileName = String.format("%s.mp4", fileName);
390 }
391 String material_media_upload_uri = getRequestUri("material_media_upload_uri");
392 MimeType mimeType = new MimeType("video",
393 FileUtil.getFileExtension(fileName));
394 Token token = tokenManager.getCache();
395 try {
396 JSONObject description = new JSONObject();
397 description.put("title", title);
398 description.put("introduction", introduction);
399 WeixinResponse response = weixinExecutor.post(
400 String.format(material_media_upload_uri,
401 token.getAccessToken()),
402 new FormBodyPart("media", new InputStreamBody(is, mimeType
403 .toString(), fileName)),
404 new FormBodyPart("description", new StringBody(description
405 .toJSONString(), Consts.UTF_8)));
406 return response.getAsJson().getString("media_id");
407 } catch (UnsupportedEncodingException e) {
408 throw new WeixinException(e);
409 } finally {
410 if (is != null) {
411 try {
412 is.close();
413 } catch (IOException e) {
414 ;
415 }
416 }
417 }
418 }
419
420
421
422
423
424
425
426
427
428
429 public MediaCounter countMaterialMedia() throws WeixinException {
430 Token token = tokenManager.getCache();
431 String material_media_count_uri = getRequestUri("material_media_count_uri");
432 WeixinResponse response = weixinExecutor.get(String.format(
433 material_media_count_uri, token.getAccessToken()));
434
435 return response.getAsObject(new TypeReference<MediaCounter>() {
436 });
437 }
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456 public MediaRecord listMaterialMedia(MediaType mediaType, Pageable pageable)
457 throws WeixinException {
458 Token token = tokenManager.getCache();
459 String material_media_list_uri = getRequestUri("material_media_list_uri");
460 JSONObject obj = new JSONObject();
461 obj.put("type", mediaType.name());
462 obj.put("offset", pageable.getOffset());
463 obj.put("count", pageable.getPageSize());
464 WeixinResponse response = weixinExecutor.post(
465 String.format(material_media_list_uri, token.getAccessToken()),
466 obj.toJSONString());
467 obj = response.getAsJson();
468 obj.put("items", obj.remove("item"));
469 MediaRecord mediaRecord = null;
470 if (mediaType == MediaType.news) {
471 mediaRecord = JSON.parseObject(obj.toJSONString(),
472 MediaRecord.class, new ExtraProcessor() {
473 @Override
474 public void processExtra(Object object, String key,
475 Object value) {
476 if (key.equals("content")) {
477 ((MediaItem) object).setArticles(JSON
478 .parseArray(((JSONObject) value)
479 .getString("news_item"),
480 MpArticle.class));
481 }
482 }
483 });
484 } else {
485 mediaRecord = JSON.toJavaObject(obj, MediaRecord.class);
486 }
487 mediaRecord.setMediaType(mediaType);
488 mediaRecord.setPageable(pageable);
489 return mediaRecord;
490 }
491
492
493
494
495
496
497
498
499
500
501 public List<MediaItem> listAllMaterialMedia(MediaType mediaType)
502 throws WeixinException {
503 Pageable pageable = new Pageable(1, 20);
504 List<MediaItem> mediaList = new ArrayList<MediaItem>();
505 MediaRecord mediaRecord = null;
506 for (;;) {
507 mediaRecord = listMaterialMedia(mediaType, pageable);
508 if (mediaRecord.getItems() == null
509 || mediaRecord.getItems().isEmpty()) {
510 break;
511 }
512 mediaList.addAll(mediaRecord.getItems());
513 if (!mediaRecord.getPagedata().hasNext()) {
514 break;
515 }
516 pageable = pageable.next();
517 }
518 return mediaList;
519 }
520 }