All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.foxinmy.weixin4j.mp.api.MediaApi Maven / Gradle / Ivy

There is a newer version: 1.10.2
Show newest version
package com.foxinmy.weixin4j.mp.api;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.ContentType;
import com.foxinmy.weixin4j.http.Header;
import com.foxinmy.weixin4j.http.HttpGet;
import com.foxinmy.weixin4j.http.HttpPost;
import com.foxinmy.weixin4j.http.HttpResponse;
import com.foxinmy.weixin4j.http.apache.FormBodyPart;
import com.foxinmy.weixin4j.http.apache.HttpHeaders;
import com.foxinmy.weixin4j.http.apache.InputStreamBody;
import com.foxinmy.weixin4j.http.apache.StringBody;
import com.foxinmy.weixin4j.http.entity.StringEntity;
import com.foxinmy.weixin4j.http.weixin.JsonResult;
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.model.MediaCounter;
import com.foxinmy.weixin4j.model.MediaDownloadResult;
import com.foxinmy.weixin4j.model.MediaItem;
import com.foxinmy.weixin4j.model.MediaRecord;
import com.foxinmy.weixin4j.model.MediaUploadResult;
import com.foxinmy.weixin4j.model.Pageable;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.tuple.MpVideo;
import com.foxinmy.weixin4j.type.MediaType;
import com.foxinmy.weixin4j.util.ConfigUtil;
import com.foxinmy.weixin4j.util.ErrorUtil;
import com.foxinmy.weixin4j.util.FileUtil;
import com.foxinmy.weixin4j.util.IOUtil;
import com.foxinmy.weixin4j.util.ObjectId;
import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.util.Weixin4jConst;

/**
 * 素材相关API
 * 
 * @className MediaApi
 * @author jy.hu
 * @date 2014年9月25日
 * @since JDK 1.7
 * @see com.foxinmy.weixin4j.type.MediaType
 */
public class MediaApi extends MpApi {

	private final TokenHolder tokenHolder;

	public MediaApi(TokenHolder tokenHolder) {
		this.tokenHolder = tokenHolder;
	}

	/**
	 * 上传图文消息内的图片获取URL
	 * 请注意,本接口所上传的图片不占用公众号的素材库中图片数量的5000个的限制。图片仅支持jpg/png格式,大小必须在1MB以下。
	 * 
	 * @param is
	 *            图片数据流
	 * @param fileName
	 *            文件名 为空时将自动生成
	 * @return 图片URL 可用于后续群发中,放置到图文消息中
	 * @throws WeixinException
	 */
	public String uploadImage(InputStream is, String fileName)
			throws WeixinException {
		if (StringUtil.isBlank(fileName)) {
			fileName = ObjectId.get().toHexString();
		}
		if (StringUtil.isBlank(FileUtil.getFileExtension(fileName))) {
			fileName = String.format("%s.jpg", fileName);
		}
		String image_upload_uri = getRequestUri("image_upload_uri");
		Token token = tokenHolder.getToken();
		WeixinResponse response = weixinClient.post(String.format(
				image_upload_uri, token.getAccessToken()),
				new FormBodyPart("media", new InputStreamBody(is,
						ContentType.IMAGE_JPG.getMimeType(), fileName)));
		return response.getAsJson().getString("url");
	}

	/**
	 * 上传群发中的视频素材
	 * 
	 * @param is
	 *            图片数据流
	 * @param fileName
	 *            文件名 为空时将自动生成
	 * @param title
	 *            视频标题 非空
	 * @param description
	 *            视频描述 可为空
	 * @return 群发视频消息对象
	 * @throws WeixinException
	 * @see 高级群发
	 * @see com.foxinmy.weixin4j.tuple.MpVideo
	 */
	public MpVideo uploadVideo(InputStream is, String fileName, String title,
			String description) throws WeixinException {
		MediaUploadResult uploadResult = uploadMedia(false, is, fileName);
		JSONObject obj = new JSONObject();
		obj.put("media_id", uploadResult.getMediaId());
		obj.put("title", title);
		obj.put("description", description);
		String video_upload_uri = getRequestUri("video_upload_uri");
		Token token = tokenHolder.getToken();
		WeixinResponse response = weixinClient.post(
				String.format(video_upload_uri, token.getAccessToken()),
				obj.toJSONString());

		String mediaId = response.getAsJson().getString("media_id");
		return new MpVideo(mediaId);
	}

	/**
	 * 上传媒体文件:图片(image)、语音(voice)、视频(video)和缩略图(thumb) 
此接口只包含图片、语音、缩略图、视频(临时)四种媒体类型的上传 *

* 正常情况下返回{"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789}, * 否则抛出异常. *

* * @param isMaterial * 是否永久上传 * @param is * 媒体数据流 * @param fileName * 文件名 * @return 上传到微信服务器返回的媒体标识 * @see 上传临时素材 * @see 上传永久素材 * @see com.foxinmy.weixin4j.model.MediaUploadResult * @see com.foxinmy.weixin4j.type.MediaType * @throws WeixinException */ public MediaUploadResult uploadMedia(boolean isMaterial, InputStream is, String fileName) throws WeixinException { byte[] content; try { content = IOUtil.toByteArray(is); } catch (IOException e) { throw new WeixinException(e); } if (StringUtil.isBlank(fileName)) { fileName = ObjectId.get().toHexString(); } String suffixName = FileUtil.getFileExtension(fileName); if (StringUtil.isBlank(suffixName)) { suffixName = FileUtil .getFileType(new ByteArrayInputStream(content)); fileName = String.format("%s.%s", fileName, suffixName); } MediaType mediaType; if (",bmp,png,jpeg,jpg,gif," .contains(String.format(",%s,", suffixName))) { mediaType = MediaType.image; } else if (",mp3,wma,wav,amr,".contains(String.format(",%s,", suffixName))) { mediaType = MediaType.voice; } else if (",rm,rmvb,wmv,avi,mpg,mpeg,mp4,".contains(String.format( ",%s,", suffixName))) { mediaType = MediaType.video; } else { throw new WeixinException("cannot handle mediaType:" + suffixName); } if (mediaType == MediaType.video && isMaterial) { throw new WeixinException( "please invoke uploadMaterialVideo method"); } Token token = tokenHolder.getToken(); WeixinResponse response = null; try { if (isMaterial) { String material_media_upload_uri = getRequestUri("material_media_upload_uri"); response = weixinClient .post(String.format(material_media_upload_uri, token.getAccessToken()), new FormBodyPart( "media", new InputStreamBody(is, mediaType .getContentType().getMimeType(), fileName)), new FormBodyPart("type", new StringBody(mediaType.name(), Consts.UTF_8))); return new MediaUploadResult(response.getAsJson().getString( "media_id"), mediaType, new Date()); } else { String media_upload_uri = getRequestUri("media_upload_uri"); response = weixinClient.post(String.format(media_upload_uri, token.getAccessToken(), mediaType.name()), new FormBodyPart("media", new InputStreamBody(is, mediaType.getContentType().getMimeType(), fileName))); JSONObject obj = response.getAsJson(); return new MediaUploadResult(obj.getString("media_id"), obj.getObject("type", MediaType.class), new Date( obj.getLong("created_at") * 1000l)); /* * return response.getAsObject(new TypeReference() * { }); */ } } catch (UnsupportedEncodingException e) { throw new WeixinException(e); } finally { try { is.close(); } catch (IOException e) { ; } } } /** * 下载媒体素材 *

* 正常情况下返回表头如Content-Type: image/jpeg,否则抛出异常. *

* * @param mediaId * 存储在微信服务器上的媒体标识 * @return 写入硬盘后的文件对象,存储路径见weixin4j.properties配置 * @throws WeixinException * @see 下载临时媒体文件 * @see 下载永久媒体素材 * @see {@link #downloadMedia(String,boolean)} */ public File downloadMediaFile(String mediaId, boolean isMaterial) throws WeixinException { String media_path = ConfigUtil.getValue("media_path", Weixin4jConst.DEFAULT_MEDIA_PATH); final String prefixName = String.format("%s.", mediaId); File[] files = new File(media_path).listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.startsWith(prefixName); } }); if (files.length > 0) { return files[0]; } MediaDownloadResult result = downloadMedia(mediaId, isMaterial); File file = new File(media_path + File.separator + result.getFileName()); OutputStream os = null; try { if (file.createNewFile()) { os = new FileOutputStream(file); os.write(result.getContent()); } else { throw new WeixinException(String.format("create file fail:%s", file.getAbsolutePath())); } } catch (IOException e) { throw new WeixinException(e.getMessage()); } finally { try { if (os != null) { os.close(); } } catch (IOException e) { ; } } return file; } /** * 下载媒体素材 * * @param mediaId * 媒体ID * @param isMaterial * 是否下载永久素材 * @return 媒体下载结果 * * @throws WeixinException * @see com.foxinmy.weixin4j.model.MediaDownloadResult * @see 下载临时媒体素材 * @see 下载永久媒体素材 */ public MediaDownloadResult downloadMedia(String mediaId, boolean isMaterial) throws WeixinException { Token token = tokenHolder.getToken(); try { HttpResponse response = null; if (isMaterial) { String material_media_download_uri = getRequestUri("material_media_download_uri"); HttpPost method = new HttpPost(String.format( material_media_download_uri, token.getAccessToken())); method.setEntity(new StringEntity(String.format( "{\"media_id\":\"%s\"}", mediaId))); response = weixinClient.execute(method); } else { String meida_download_uri = getRequestUri("meida_download_uri"); HttpGet method = new HttpGet(String.format(meida_download_uri, token.getAccessToken(), mediaId)); response = weixinClient.execute(method); } byte[] content = response.getContent(); Header contentType = response .getFirstHeader(HttpHeaders.CONTENT_TYPE); Header disposition = response.getFirstHeader("Content-disposition"); if (contentType.getValue().contains( ContentType.APPLICATION_JSON.getMimeType()) || (disposition != null && disposition.getValue().indexOf( ".json") > 0)) { JsonResult jsonResult = JSON.parseObject(content, 0, content.length, Consts.UTF_8.newDecoder(), JsonResult.class); if (jsonResult.getCode() != 0) { if (StringUtil.isBlank(jsonResult.getDesc())) { jsonResult.setDesc(ErrorUtil.getText(Integer .toString(jsonResult.getCode()))); } throw new WeixinException(Integer.toString(jsonResult .getCode()), jsonResult.getDesc()); } } String fileName = String.format("%s.%s", mediaId, contentType .getValue().split("/")[1]); return new MediaDownloadResult(content, ContentType.create(contentType.getValue()), fileName); } catch (IOException e) { throw new WeixinException(e); } } /** * 上传永久图文素材 *

* 、新增的永久素材也可以在公众平台官网素材管理模块中看到,永久素材的数量是有上限的,请谨慎新增。图文消息素材和图片素材的上限为5000, * 其他类型为1000 *

* * @param articles * 图文列表 * @return 上传到微信服务器返回的媒体标识 * @throws WeixinException * @see 上传永久媒体素材 * @see com.foxinmy.weixin4j.tuple.MpArticle */ public String uploadMaterialArticle(List articles) throws WeixinException { Token token = tokenHolder.getToken(); String material_article_upload_uri = getRequestUri("material_article_upload_uri"); JSONObject obj = new JSONObject(); obj.put("articles", articles); WeixinResponse response = weixinClient.post( String.format(material_article_upload_uri, token.getAccessToken()), obj.toJSONString()); return response.getAsJson().getString("media_id"); } /** * 下载永久图文素材 * * @param mediaId * 媒体ID * @return 图文列表 * @throws WeixinException * @see {@link #downloadMedia(String, boolean)} * @see com.foxinmy.weixin4j.tuple.MpArticle */ public List downloadArticle(String mediaId) throws WeixinException { MediaDownloadResult result = downloadMedia(mediaId, true); byte[] content = result.getContent(); JSONObject obj = JSON.parseObject(content, 0, content.length, Consts.UTF_8.newDecoder(), JSONObject.class); return JSON.parseArray(obj.getString("news_item"), MpArticle.class); } /** * 更新永久图文素材 * * @param mediaId * 要修改的图文消息的id * @param index * 要更新的文章在图文消息中的位置(多图文消息时,此字段才有意义),第一篇为0 * @param articles * 图文列表 * @return 处理结果 * @throws WeixinException * @see com.foxinmy.weixin4j.tuple.MpArticle * @see 更新永久图文素材 */ public JsonResult updateMaterialArticle(String mediaId, int index, List articles) throws WeixinException { Token token = tokenHolder.getToken(); String material_article_update_uri = getRequestUri("material_article_update_uri"); JSONObject obj = new JSONObject(); obj.put("articles", articles); obj.put("media_id", mediaId); obj.put("index", index); WeixinResponse response = weixinClient.post( String.format(material_article_update_uri, token.getAccessToken()), obj.toJSONString()); return response.getAsJsonResult(); } /** * 删除永久媒体素材 * * @param mediaId * 媒体素材的media_id * @return 处理结果 * @throws WeixinException * @see 删除永久媒体素材 */ public JsonResult deleteMaterialMedia(String mediaId) throws WeixinException { Token token = tokenHolder.getToken(); String material_media_del_uri = getRequestUri("material_media_del_uri"); JSONObject obj = new JSONObject(); obj.put("media_id", mediaId); WeixinResponse response = weixinClient.post( String.format(material_media_del_uri, token.getAccessToken()), obj.toJSONString()); return response.getAsJsonResult(); } /** * 上传永久视频素材 * * @param is * 大小不超过1M且格式为MP4的视频文件 * @param title * 视频标题 * @param introduction * 视频描述 * @return 上传到微信服务器返回的媒体标识 * @see 上传永久媒体素材 * @throws WeixinException */ public String uploadMaterialVideo(InputStream is, String title, String introduction) throws WeixinException { String material_media_upload_uri = getRequestUri("material_media_upload_uri"); Token token = tokenHolder.getToken(); try { JSONObject description = new JSONObject(); description.put("title", title); description.put("introduction", introduction); WeixinResponse response = weixinClient.post( String.format(material_media_upload_uri, token.getAccessToken()), new FormBodyPart("media", new InputStreamBody(is, MediaType.video.getContentType().getMimeType(), ObjectId.get().toHexString())), new FormBodyPart("type", new StringBody(MediaType.video .name(), Consts.UTF_8)), new FormBodyPart("description", new StringBody(description .toJSONString(), Consts.UTF_8))); return response.getAsJson().getString("media_id"); } catch (UnsupportedEncodingException e) { throw new WeixinException(e); } finally { if (is != null) { try { is.close(); } catch (IOException e) { ; } } } } /** * 获取永久媒体素材的总数
.图片和图文消息素材(包括单图文和多图文)的总数上限为5000,其他素材的总数上限为1000 * * @return 总数对象 * @throws WeixinException * @see com.foxinmy.weixin4j.model.MediaCounter * @see 获取素材总数 */ public MediaCounter countMaterialMedia() throws WeixinException { Token token = tokenHolder.getToken(); String material_media_count_uri = getRequestUri("material_media_count_uri"); WeixinResponse response = weixinClient.get(String.format( material_media_count_uri, token.getAccessToken())); return response.getAsObject(new TypeReference() { }); } /** * 获取媒体素材记录列表 * * @param mediaType * 素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news) * @param pageable * 分页数据 * @return 媒体素材的记录对象 * @throws WeixinException * @see com.foxinmy.weixin4j.model.MediaRecord * @see com.foxinmy.weixin4j.type.MediaType * @see com.foxinmy.weixin4j.model.MediaItem * @see com.foxinmy.weixin4j.model.Pageable * @see com.foxinmy.weixin4j.model.Pagedata * @see 获取素材列表 */ public MediaRecord listMaterialMedia(MediaType mediaType, Pageable pageable) throws WeixinException { Token token = tokenHolder.getToken(); String material_media_list_uri = getRequestUri("material_media_list_uri"); JSONObject obj = new JSONObject(); obj.put("type", mediaType.name()); obj.put("offset", pageable.getOffset()); obj.put("count", pageable.getPageSize()); WeixinResponse response = weixinClient.post( String.format(material_media_list_uri, token.getAccessToken()), obj.toJSONString()); MediaRecord mediaRecord = null; if (mediaType == MediaType.news) { mediaRecord = JSON.parseObject(response.getAsString(), MediaRecord.class, new ExtraProcessor() { @Override public void processExtra(Object object, String key, Object value) { if (key.equals("content")) { ((MediaItem) object).setArticles(JSON .parseArray(((JSONObject) value) .getString("news_item"), MpArticle.class)); } } }); } else { mediaRecord = response .getAsObject(new TypeReference() { }); } mediaRecord.setMediaType(mediaType); mediaRecord.setPageable(pageable); return mediaRecord; } /** * 获取全部的媒体素材 * * @param mediaType * 媒体类型 * @return 素材列表 * @see {@link #listMaterialMedia(MediaType, Pageable)} * @throws WeixinException */ public List listAllMaterialMedia(MediaType mediaType) throws WeixinException { Pageable pageable = new Pageable(1, 20); List mediaList = new ArrayList(); MediaRecord mediaRecord = null; for (;;) { mediaRecord = listMaterialMedia(mediaType, pageable); mediaList.addAll(mediaRecord.getItems()); if (pageable.getOffset() >= mediaRecord.getTotalCount()) { break; } pageable = pageable.next(); } return mediaList; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy