weixin4j-qy:新增媒体素材接口

This commit is contained in:
jinyu
2015-07-04 18:28:24 +08:00
parent 402d87c978
commit 82cc589640
33 changed files with 820 additions and 282 deletions
+5 -1
View File
@@ -68,4 +68,8 @@
* 2015-06-26
+ 管理成员新增头像参数
+ 管理成员新增头像参数
* 2015-07-04
+ 新增[媒体素材接口](src/main/java/com/foxinmy/weixin4j/qy/api/MediaApi.java)
@@ -9,6 +9,9 @@ import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.JsonResult;
import com.foxinmy.weixin4j.model.Button;
import com.foxinmy.weixin4j.model.MediaCounter;
import com.foxinmy.weixin4j.model.MediaItem;
import com.foxinmy.weixin4j.model.MediaRecord;
import com.foxinmy.weixin4j.qy.api.AgentApi;
import com.foxinmy.weixin4j.qy.api.BatchApi;
import com.foxinmy.weixin4j.qy.api.HelperApi;
@@ -34,6 +37,7 @@ import com.foxinmy.weixin4j.qy.type.InviteType;
import com.foxinmy.weixin4j.qy.type.UserStatus;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.token.TokenStorager;
import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.type.MediaType;
/**
@@ -204,75 +208,203 @@ public class WeixinProxy {
/**
* 上传媒体文件
*
* @param agentid
* 企业应用ID(<font color="red">大于0时视为上传永久媒体文件</font>)
* @param file
* 媒体对象
* 文件对象
* @return 上传到微信服务器返回的媒体标识
* @see com.foxinmy.weixin4j.qy.api.MediaApi
* @see {@link com.foxinmy.weixin4j.qy.WeixinProxy.MediaApi#uploadMedia(InputStream, MediaType)}
* @see {@link com.foxinmy.weixin4j.qy.api.MediaApi#uploadMedia(int,InputStream, MediaType)}
* @throws WeixinException
* @throws IOException
*/
public String uploadMedia(File file) throws WeixinException, IOException {
return mediaApi.uploadMedia(file);
public String uploadMedia(int agentid, File file) throws WeixinException,
IOException {
return mediaApi.uploadMedia(agentid, file);
}
/**
* 上传媒体文件(完全公开。所有管理员均可调用,media_id可以共享)
* 上传媒体文件
* <p>
* 正常情况下返回{"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789},
* 否则抛出异常.
* </p>
*
* @param agentid
* 企业应用ID(<font color="red">大于0时视为上传永久媒体文件</font>)
* @param is
* 媒体数据流
* @param mediaType
* 媒体类型
* @see com.foxinmy.weixin4j.qy.api.MediaApi
* @see com.foxinmy.weixin4j.type.MediaType
* @return 上传到微信服务器返回的媒体标识
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">上传媒体文件说明</a>
* @throws WeixinException
*/
public String uploadMedia(InputStream is, MediaType mediaType)
throws WeixinException {
return mediaApi.uploadMedia(is, mediaType);
}
/**
* 下载媒体文件(完全公开。所有管理员均可调用,media_id可以共享)
*
* @param mediaId
* 媒体ID
* @return 二进制数据包
* @see com.foxinmy.weixin4j.qy.api.MediaApi
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">获取媒体说明</a>
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%B4%E6%97%B6%E7%B4%A0%E6%9D%90%E6%96%87%E4%BB%B6">上传临时素材文件说明</a>
* @see <a
* href="http://http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90">上传永久素材文件说明</a>
* @throws WeixinException
*/
public byte[] downloadMedia(String mediaId) throws WeixinException {
return mediaApi.downloadMedia(mediaId);
public String uploadMedia(int agentid, InputStream is, MediaType mediaType)
throws WeixinException {
return mediaApi.uploadMedia(agentid, is, mediaType);
}
/**
* 下载媒体文件(完全公开。所有管理员均可调用,media_id可以共享)
* <p>
* 正常情况下返回表头如Content-Type: image/jpeg,否则抛出异常.
* </p>
* 下载媒体文件
*
* @param agentid
* 企业应用Id(<font color="red">大于0时视为获取永久媒体文件</font>)
* @param mediaId
* 存储在微信服务器上的媒体标识
* @return 写入硬盘后的文件对象,存储路径见weixin4j.properties配置
* @throws WeixinException
* @throws IOException
* @see com.foxinmy.weixin4j.qy.api.MediaApi
* @see com.foxinmy.weixin4j.type.MediaType
* @see {@link com.foxinmy.weixin4j.qy.api.MediaApi#downloadMedia(int,String)}
*/
public File downloadMediaFile(int agentid, String mediaId)
throws WeixinException {
return mediaApi.downloadMediaFile(agentid, mediaId);
}
/**
* 下载媒体文件
*
* @param agentid
* 企业应用Id(<font color="red">大于0时视为获取永久媒体文件</font>)
* @param mediaId
* 媒体ID
* @return 二进制数据包(需自行判断类型)
* @see com.foxinmy.weixin4j.qy.api.MediaApi
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">获取媒体说明</a>
* @see com.foxinmy.weixin4j.type.MediaType
* @see {@link com.foxinmy.weixin4j.WeixinProxy.MediaApi#downloadMedia(String)}
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E4%B8%B4%E6%97%B6%E7%B4%A0%E6%9D%90%E6%96%87%E4%BB%B6">获取临时媒体说明</a>
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90">获取永久媒体说明</a>
* @throws WeixinException
*/
public File downloadMediaFile(String mediaId) throws WeixinException {
return mediaApi.downloadMediaFile(mediaId);
public byte[] downloadMedia(int agentid, String mediaId)
throws WeixinException {
return mediaApi.downloadMedia(agentid, mediaId);
}
/**
* 上传永久图文素材
* <p>
* 、新增的永久素材也可以在公众平台官网素材管理模块中看到,永久素材的数量是有上限的,请谨慎新增。图文消息素材和图片素材的上限为5000,
* 其他类型为1000
* </P>
*
* @param agentid
* 企业应用的id
* @param articles
* 图文列表
* @return 上传到微信服务器返回的媒体标识
* @throws WeixinException
* @see com.foxinmy.weixin4j.qy.api.MediaApi
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90">上传永久媒体素材</a>
* @see com.foxinmy.weixin4j.tuple.MpArticle
*/
public String uploadMaterialArticle(int agentid, List<MpArticle> articles)
throws WeixinException {
return mediaApi.uploadMaterialArticle(agentid, articles);
}
/**
* 删除永久媒体素材
*
* @param agentid
* 企业应用ID
* @param mediaId
* 媒体素材的media_id
* @return 处理结果
* @throws WeixinException
* @see com.foxinmy.weixin4j.qy.api.MediaApi
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E5%88%A0%E9%99%A4%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90">删除永久媒体素材</a>
*/
public JsonResult deleteMaterialMedia(int agentid, String mediaId)
throws WeixinException {
return mediaApi.deleteMaterialMedia(agentid, mediaId);
}
/**
* 修改永久图文素材
*
* @param agentid
* 企业应用的id
* @param mediaId
* 上传后的media_id
* @param articles
* 图文列表
* @return 操作结果
* @throws WeixinException
* @see com.foxinmy.weixin4j.qy.api.MediaApi
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BF%AE%E6%94%B9%E6%B0%B8%E4%B9%85%E5%9B%BE%E6%96%87%E7%B4%A0%E6%9D%90">修改永久媒体素材</a>
* @see com.foxinmy.weixin4j.tuple.MpArticle
*/
public String updateMaterialArticle(int agentid, String mediaId,
List<MpArticle> articles) throws WeixinException {
return mediaApi.updateMaterialArticle(agentid, mediaId, articles);
}
/**
* 获取永久媒体素材的总数
*
* @param agentid
* 企业应用id
* @return 总数对象
* @throws WeixinException
* @see com.foxinmy.weixin4j.qy.api.MediaApi
* @see com.foxinmy.weixin4j.model.MediaCounter
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E7%B4%A0%E6%9D%90%E6%80%BB%E6%95%B0">获取素材总数</a>
*/
public MediaCounter countMaterialMedia(int agentid) throws WeixinException {
return mediaApi.countMaterialMedia(agentid);
}
/**
* 获取媒体素材记录列表
*
* @param agentid
* 企业应用ID
* @param mediaType
* 素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news)、文件(file)
* @param offset
* 从全部素材的该偏移位置开始返回,0表示从第一个素材返回
* @param count
* 返回素材的数量,取值在1到20之间
* @return 媒体素材的记录对象
* @throws WeixinException
* @see com.foxinmy.weixin4j.qy.api.MediaApi
* @see com.foxinmy.weixin4j.model.MediaRecord
* @see com.foxinmy.weixin4j.type.MediaType
* @see com.foxinmy.weixin4j.model.MediaItem
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E7%B4%A0%E6%9D%90%E5%88%97%E8%A1%A8">获取素材列表</a>
*/
public MediaRecord listMaterialMedia(int agentid, MediaType mediaType,
int offset, int count) throws WeixinException {
return mediaApi.listMaterialMedia(agentid, mediaType, offset, count);
}
/**
* 获取全部的媒体素材
*
* @param agentid
* 企业应用id
* @param mediaType
* 媒体类型
* @return 素材列表
* @see com.foxinmy.weixin4j.qy.api.MediaApi
* @see {@link com.foxinmy.weixin4j.qy.api.MediaApi#listMaterialMedia(int,MediaType, int, int)}
* @throws WeixinException
*/
public List<MediaItem> listAllMaterialMedia(int agentid, MediaType mediaType)
throws WeixinException {
return mediaApi.listAllMaterialMedia(agentid, mediaType);
}
/**
@@ -8,6 +8,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -17,21 +18,28 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.HttpGet;
import com.foxinmy.weixin4j.http.apache.FormBodyPart;
import com.foxinmy.weixin4j.http.apache.InputStreamBody;
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.MediaItem;
import com.foxinmy.weixin4j.model.MediaRecord;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.qy.model.Callback;
import com.foxinmy.weixin4j.qy.model.Party;
import com.foxinmy.weixin4j.qy.model.User;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.type.MediaType;
import com.foxinmy.weixin4j.util.ConfigUtil;
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
@@ -41,7 +49,7 @@ import com.foxinmy.weixin4j.util.StringUtil;
* @date 2014年9月25日
* @since JDK 1.7
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E5%A4%9A%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">管理多媒体文件</a>
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E7%B4%A0%E6%9D%90%E6%96%87%E4%BB%B6">管理素材文件</a>
* @see com.foxinmy.weixin4j.type.MediaType
*/
public class MediaApi extends QyApi {
@@ -55,96 +63,118 @@ public class MediaApi extends QyApi {
/**
* 上传媒体文件
*
* @param agentid
* 企业应用ID(<font color="red">大于0时视为上传永久媒体文件</font>)
* @param file
* 媒体对象
* 文件对象
* @return 上传到微信服务器返回的媒体标识
* @see {@link com.foxinmy.weixin4j.qy.api.MediaApi#uploadMedia(InputStream, MediaType)}
* @see {@link com.foxinmy.weixin4j.qy.api.MediaApi#uploadMedia(int,InputStream, MediaType)}
* @throws WeixinException
* @throws IOException
*/
public String uploadMedia(File file) throws WeixinException, IOException {
public String uploadMedia(int agentid, File file) throws WeixinException,
IOException {
String mediaTypeKey = IOUtil.getExtension(file.getName());
if (StringUtil.isBlank(mediaTypeKey)) {
mediaTypeKey = FileUtil.getFileType(file);
}
MediaType mediaType = null;
if (mediaTypeKey.equals("jpg")) {
if ("bmp/png/jpeg/jpg/gif".contains(mediaTypeKey)) {
mediaType = MediaType.image;
} else if ("amr/mp3".contains(mediaTypeKey)) {
} else if ("mp3/wma/wav/amr".contains(mediaTypeKey)) {
mediaType = MediaType.voice;
} else if (mediaTypeKey.equals("mp4")) {
} else if ("mp4".equals(mediaTypeKey)) {
mediaType = MediaType.video;
} else {
mediaType = MediaType.file;
}
return uploadMedia(new FileInputStream(file), mediaType);
return uploadMedia(agentid, new FileInputStream(file), mediaType);
}
/**
* 上传媒体文件(完全公开。所有管理员均可调用,media_id可以共享)
* 上传媒体文件
* <p>
* 正常情况下返回{"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789},
* 否则抛出异常.
* </p>
*
* @param agentid
* 企业应用ID(<font color="red">大于0时视为上传永久媒体文件</font>)
* @param is
* 媒体数据流
* @param mediaType
* 媒体类型
* @return 上传到微信服务器返回的媒体标识
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">上传媒体文件说明</a>
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%B4%E6%97%B6%E7%B4%A0%E6%9D%90%E6%96%87%E4%BB%B6">上传临时素材文件说明</a>
* @see <a
* href="http://http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90">上传永久素材文件说明</a>
* @throws WeixinException
*/
public String uploadMedia(InputStream is, MediaType mediaType)
public String uploadMedia(int agentid, InputStream is, MediaType mediaType)
throws WeixinException {
String file_upload_uri = getRequestUri("file_upload_uri");
Token token = tokenHolder.getToken();
if (mediaType == null || mediaType == MediaType.news) {
if (mediaType == null) {
mediaType = MediaType.file;
} else if (mediaType == MediaType.thumb) {
mediaType = MediaType.image;
} else if (mediaType == MediaType.news) {
throw new WeixinException(
"please invoke uploadMaterialArticle method");
}
WeixinResponse response = weixinClient.post(String.format(
file_upload_uri, token.getAccessToken(), mediaType),
new FormBodyPart("media", new InputStreamBody(is, mediaType
.getContentType().getMimeType(), ObjectId.get()
.toHexString())));
try {
is.close();
} catch (IOException e) {
;
WeixinResponse response = null;
if (agentid > 0) {
String material_media_upload_uri = getRequestUri("material_media_upload_uri");
response = weixinClient.post(String.format(
material_media_upload_uri, token.getAccessToken(),
mediaType.name(), agentid), new FormBodyPart("media",
new InputStreamBody(is, mediaType.getContentType()
.getMimeType(), ObjectId.get().toHexString())));
} else {
String file_upload_uri = getRequestUri("file_upload_uri");
response = weixinClient.post(String.format(file_upload_uri,
token.getAccessToken(), mediaType.name()),
new FormBodyPart("media", new InputStreamBody(is,
mediaType.getContentType().getMimeType(),
ObjectId.get().toHexString())));
}
return response.getAsJson().getString("media_id");
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
;
}
}
}
return response.getAsJson().getString("media_id");
}
/**
* 下载媒体文件(完全公开。所有管理员均可调用,media_id可以共享)
* <p>
* 正常情况下返回表头如Content-Type: image/jpeg,否则抛出异常.
* </p>
* 下载媒体文件
*
* @param agentid
* 企业应用Id(<font color="red">大于0时视为获取永久媒体文件</font>)
* @param mediaId
* 存储在微信服务器上的媒体标识
* @return 写入硬盘后的文件对象,存储路径见weixin4j.properties配置
* @throws WeixinException
* @throws IOException
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">获取媒体说明</a>
* @see com.foxinmy.weixin4j.type.MediaType
* @see {@link com.foxinmy.weixin4j.qy.api.MediaApi#downloadMedia(String)}
* @see {@link com.foxinmy.weixin4j.qy.api.MediaApi#downloadMedia(int,String)}
*/
public File downloadMediaFile(String mediaId) throws WeixinException {
String media_path = ConfigUtil.getValue("media_path");
public File downloadMediaFile(int agentid, String mediaId)
throws WeixinException {
String media_path = ConfigUtil.getValue("media_path",
Weixin4jConst.DEFAULT_MEDIA_PATH);
File file = new File(media_path + File.separator + mediaId);
if (file.exists()) {
return file;
}
byte[] datas = downloadMedia(mediaId);
byte[] datas = downloadMedia(agentid, mediaId);
OutputStream os = null;
try {
boolean flag = file.createNewFile();
if (flag) {
if (file.createNewFile()) {
os = new FileOutputStream(file);
os.write(datas);
} else {
@@ -166,21 +196,216 @@ public class MediaApi extends QyApi {
}
/**
* 下载媒体文件(完全公开。所有管理员均可调用,media_id可以共享)
* 下载媒体文件
*
* @param agentid
* 企业应用Id(<font color="red">大于0时视为获取永久媒体文件</font>)
* @param mediaId
* 媒体ID
* @return 二进制数据包
* @return 二进制数据包(需自行判断类型)
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">获取媒体说明</a>
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E4%B8%B4%E6%97%B6%E7%B4%A0%E6%9D%90%E6%96%87%E4%BB%B6">获取临时媒体说明</a>
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90">获取永久媒体说明</a>
* @throws WeixinException
*/
public byte[] downloadMedia(String mediaId) throws WeixinException {
public byte[] downloadMedia(int agentid, String mediaId)
throws WeixinException {
Token token = tokenHolder.getToken();
String file_download_uri = getRequestUri("file_download_uri");
try {
HttpGet method = null;
if (agentid > 0) {
String material_media_download_uri = getRequestUri("material_media_download_uri");
method = new HttpGet(String.format(material_media_download_uri,
token.getAccessToken(), mediaId, agentid));
} else {
String meida_download_uri = getRequestUri("meida_download_uri");
method = new HttpGet(String.format(meida_download_uri,
token.getAccessToken(), mediaId));
}
return weixinClient.execute(method).getContent();
} catch (IOException e) {
throw new WeixinException(e);
}
}
/**
* 上传永久图文素材
* <p>
* 、新增的永久素材也可以在公众平台官网素材管理模块中看到,永久素材的数量是有上限的,请谨慎新增。图文消息素材和图片素材的上限为5000,
* 其他类型为1000
* </P>
*
* @param agentid
* 企业应用的id
* @param articles
* 图文列表
* @return 上传到微信服务器返回的媒体标识
* @throws WeixinException
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90">上传永久媒体素材</a>
* @see com.foxinmy.weixin4j.tuple.MpArticle
*/
public String uploadMaterialArticle(int agentid, List<MpArticle> articles)
throws WeixinException {
Token token = tokenHolder.getToken();
String material_article_upload_uri = getRequestUri("material_article_upload_uri");
JSONObject obj = new JSONObject();
obj.put("agentid", agentid);
JSONObject news = new JSONObject();
news.put("articles", articles);
obj.put("mpnews", news);
WeixinResponse response = weixinClient.post(
String.format(material_article_upload_uri,
token.getAccessToken()), obj.toJSONString());
return response.getAsJson().getString("media_id");
}
/**
* 删除永久媒体素材
*
* @param agentid
* 企业应用ID
* @param mediaId
* 媒体素材的media_id
* @return 处理结果
* @throws WeixinException
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E5%88%A0%E9%99%A4%E6%B0%B8%E4%B9%85%E7%B4%A0%E6%9D%90">删除永久媒体素材</a>
*/
public JsonResult deleteMaterialMedia(int agentid, String mediaId)
throws WeixinException {
Token token = tokenHolder.getToken();
String material_media_del_uri = getRequestUri("material_media_del_uri");
WeixinResponse response = weixinClient.get(String.format(
file_download_uri, token.getAccessToken(), mediaId));
return response.getContent();
material_media_del_uri, token.getAccessToken(), mediaId,
agentid));
return response.getAsJsonResult();
}
/**
* 修改永久图文素材
*
* @param agentid
* 企业应用的id
* @param mediaId
* 上传后的media_id
* @param articles
* 图文列表
* @return 操作结果
* @throws WeixinException
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BF%AE%E6%94%B9%E6%B0%B8%E4%B9%85%E5%9B%BE%E6%96%87%E7%B4%A0%E6%9D%90">修改永久媒体素材</a>
* @see com.foxinmy.weixin4j.tuple.MpArticle
*/
public String updateMaterialArticle(int agentid, String mediaId,
List<MpArticle> articles) throws WeixinException {
Token token = tokenHolder.getToken();
String material_article_update_uri = getRequestUri("material_article_update_uri");
JSONObject obj = new JSONObject();
obj.put("agentid", agentid);
JSONObject news = new JSONObject();
news.put("articles", articles);
obj.put("mpnews", news);
obj.put("media_id", mediaId);
WeixinResponse response = weixinClient.post(
String.format(material_article_update_uri,
token.getAccessToken()), obj.toJSONString());
return response.getAsJson().getString("media_id");
}
/**
* 获取永久媒体素材的总数
*
* @param agentid
* 企业应用id
* @return 总数对象
* @throws WeixinException
* @see com.foxinmy.weixin4j.model.MediaCounter
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E7%B4%A0%E6%9D%90%E6%80%BB%E6%95%B0">获取素材总数</a>
*/
public MediaCounter countMaterialMedia(int agentid) 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(), agentid));
JSONObject result = response.getAsJson();
MediaCounter counter = JSON.toJavaObject(result, MediaCounter.class);
counter.setNewsCount(result.getIntValue("mpnews_count"));
return counter;
}
/**
* 获取媒体素材记录列表
*
* @param agentid
* 企业应用ID
* @param mediaType
* 素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news)、文件(file)
* @param offset
* 从全部素材的该偏移位置开始返回,0表示从第一个素材返回
* @param count
* 返回素材的数量,取值在1到20之间
* @return 媒体素材的记录对象
* @throws WeixinException
* @see com.foxinmy.weixin4j.model.MediaRecord
* @see com.foxinmy.weixin4j.type.MediaType
* @see com.foxinmy.weixin4j.model.MediaItem
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E7%B4%A0%E6%9D%90%E5%88%97%E8%A1%A8">获取素材列表</a>
*/
public MediaRecord listMaterialMedia(int agentid, MediaType mediaType,
int offset, int count) throws WeixinException {
Token token = tokenHolder.getToken();
String material_media_list_uri = getRequestUri("material_media_list_uri");
JSONObject obj = new JSONObject();
obj.put("type",
mediaType == MediaType.news ? "mpnews" : mediaType.name());
obj.put("offset", offset);
obj.put("count", count);
WeixinResponse response = weixinClient.post(
String.format(material_media_list_uri, token.getAccessToken()),
obj.toJSONString());
obj = response.getAsJson();
MediaRecord mediaRecord = JSON.toJavaObject(obj, MediaRecord.class);
if (mediaType == MediaType.news) {
mediaRecord.setItems(JSON.parseArray(obj.getString("itemlist"),
MediaItem.class));
}
mediaRecord.setMediaType(mediaType);
return mediaRecord;
}
/**
* 获取全部的媒体素材
*
* @param agentid
* 企业应用id
* @param mediaType
* 媒体类型
* @return 素材列表
* @see {@link com.foxinmy.weixin4j.qy.api.MediaApi#listMaterialMedia(int,MediaType, int, int)}
* @throws WeixinException
*/
public List<MediaItem> listAllMaterialMedia(int agentid, MediaType mediaType)
throws WeixinException {
int offset = 0;
int count = 20;
List<MediaItem> mediaList = new ArrayList<MediaItem>();
MediaRecord mediaRecord = null;
for (;;) {
mediaRecord = listMaterialMedia(agentid, mediaType, offset, count);
mediaList.addAll(mediaRecord.getItems());
if (offset >= mediaRecord.getTotalCount()) {
break;
}
offset += count;
}
return mediaList;
}
/**
@@ -217,35 +442,39 @@ public class MediaApi extends QyApi {
private <T> String batchUpload(String batchName, List<T> models)
throws WeixinException {
JSONObject csvObj = JSON.parseObject(getConfigValue(batchName));
JSONArray columns = csvObj.getJSONArray("column");
StringWriter writer = new StringWriter();
writer.write(csvObj.getString("header"));
final Map<String, Object> column = new LinkedHashMap<String, Object>();
for (Object col : columns) {
column.put(col.toString(), "");
}
writer.write("\r\n");
for (T model : models) {
JSON.toJSONString(model, new PropertyFilter() {
@Override
public boolean apply(Object object, String name, Object value) {
if (column.containsKey(name)) {
column.put(name, value);
}
return true;
}
});
writer.write(StringUtil.join(column.values(), ','));
writer.write("\r\n");
}
String mediaId = uploadMedia(new ByteArrayInputStream(writer
.getBuffer().toString().getBytes(Consts.UTF_8)), MediaType.file);
try {
writer.close();
} catch (IOException e) {
;
JSONObject csvObj = JSON.parseObject(weixinBundle().getString(
batchName));
JSONArray columns = csvObj.getJSONArray("column");
writer.write(csvObj.getString("header"));
final Map<String, Object> column = new LinkedHashMap<String, Object>();
for (Object col : columns) {
column.put(col.toString(), "");
}
writer.write("\r\n");
for (T model : models) {
JSON.toJSONString(model, new PropertyFilter() {
@Override
public boolean apply(Object object, String name,
Object value) {
if (column.containsKey(name)) {
column.put(name, value);
}
return true;
}
});
writer.write(StringUtil.join(column.values(), ','));
writer.write("\r\n");
}
return uploadMedia(0, new ByteArrayInputStream(writer.getBuffer()
.toString().getBytes(Consts.UTF_8)), MediaType.file);
} finally {
try {
writer.close();
} catch (IOException e) {
;
}
}
return mediaId;
}
}
@@ -33,7 +33,7 @@ public class QyApi extends BaseApi {
}
@Override
protected String getConfigValue(String key) {
return WEIXIN_BUNDLE.getString(key);
protected ResourceBundle weixinBundle() {
return WEIXIN_BUNDLE;
}
}
@@ -119,7 +119,7 @@ public class UserApi extends QyApi {
}
if (avatar != null) {
obj.put("avatar_mediaid",
mediaApi.uploadMedia(avatar, MediaType.image));
mediaApi.uploadMedia(0, avatar, MediaType.image));
}
Token token = tokenHolder.getToken();
WeixinResponse response = weixinClient.post(
@@ -99,4 +99,23 @@ suite_set_agent_uri={api_base_url}/service/set_agent?suite_access_token=%s
# userid\u8f6c\u6362\u6210openid
userid2openid_uri={api_base_url}/user/convert_to_openid?access_token=%s
# openid\u8f6c\u6362\u6210userid
openid2userid_uri={api_base_url}/user/convert_to_userid?access_token=%s
openid2userid_uri={api_base_url}/user/convert_to_userid?access_token=%s
# \u4e0a\u4f20\u4e34\u65f6\u7d20\u6750\u6587\u4ef6
media_upload_uri={api_base_url}/media/upload?access_token=%s&type=%s
# \u4e0b\u8f7d\u4e34\u65f6\u7d20\u6750\u6587\u4ef6
meida_download_uri={api_base_url}/media/get?access_token=%s&media_id=%s
# \u4e0a\u4f20\u6c38\u4e45\u56fe\u6587\u7d20\u6750
material_article_upload_uri={api_base_url}/material/add_news?access_token=%s
# \u4e0a\u4f20\u6c38\u4e45\u5a92\u4f53\u7d20\u6750
material_media_upload_uri={api_base_url}/material/add_material?access_token=%s&type=%s&agentid=%d
# \u4e0b\u8f7d\u6c38\u4e45\u5a92\u4f53\u7d20\u6750
material_media_download_uri={api_base_url}/material/get?access_token=%s&media_id=%s&agentid=%d
# \u66f4\u65b0\u6c38\u4e45\u56fe\u6587\u7d20\u6750
material_article_update_uri={api_base_url}/material/update_mpnews?access_token=%s
# \u5220\u9664\u6c38\u4e45\u5a92\u4f53\u7d20\u6750
material_media_del_uri={api_base_url}/material/del?access_token=%s&media_id=%s&agentid=%d
# \u83b7\u53d6\u5a92\u4f53\u7d20\u6750\u603b\u6570
material_media_count_uri={api_base_url}/material/get_count?access_token=%s&agentid=%d
# \u83b7\u53d6\u5a92\u4f53\u7d20\u6750\u5217\u8868
material_media_list_uri={api_base_url}/material/batchget?access_token=%s
@@ -70,7 +70,7 @@ public class User implements Serializable {
/**
* 启用/禁用成员。1表示启用成员,0表示禁用成员
*/
private int enable;
private Integer enable;
/**
* 非必须 扩展属性。扩展属性需要在WEB管理端创建后才生效,否则忽略未知属性的赋值
*/
@@ -218,16 +218,23 @@ public class User implements Serializable {
this.status = status;
}
public int getEnable() {
public int getStatus() {
return status;
}
public Integer getEnable() {
return enable;
}
@JSONField(serialize = false, deserialize = false)
public boolean getFormatEnable() {
return enable == 1;
if (enable != null) {
return enable.intValue() == 1;
}
return false;
}
public void setEnable(int enable) {
public void setEnable(Integer enable) {
this.enable = enable;
}
@@ -9,6 +9,7 @@ import org.junit.Test;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.qy.api.MediaApi;
import com.foxinmy.weixin4j.type.MediaType;
/**
* 媒体上传下载测试
@@ -30,8 +31,8 @@ public class MediaTest extends TokenTest {
@Test
public void upload() throws IOException, WeixinException {
File file = new File("/tmp/test.docx");
String mediaId = mediaApi.uploadMedia(file);
File file = new File("//Users/jy/Downloads/import_file.csv");
String mediaId = mediaApi.uploadMedia(1, file);
// 1-1gpykXsR8bhNvO13-ZvskptCBxQF1UE535jFdCF63N2inGRAqEb-psF6eppjIIl
// 1CF6sBgWWFGY9s4JCEet5ASszsTuyHpeN1f2LWXADveqBlKoxSgb3cO401NEM7dNY
Assert.assertNotNull(mediaId);
@@ -41,7 +42,13 @@ public class MediaTest extends TokenTest {
@Test
public void download() throws WeixinException, IOException {
File file = mediaApi
.downloadMediaFile("1CF6sBgWWFGY9s4JCEet5ASszsTuyHpeN1f2LWXADveqBlKoxSgb3cO401NEM7dNY");
.downloadMediaFile(1,
"jM5OWhnYb2DgrNm97HGj8aUdsZcweQc93tnwbH1mERo");
Assert.assertTrue(file.exists());
}
@Test
public void listAll() throws WeixinException {
mediaApi.listAllMaterialMedia(1, MediaType.image);
}
}
@@ -28,7 +28,8 @@ public class TokenTest {
WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount();
tokenHolder = new TokenHolder(new WeixinTokenCreator(
weixinAccount.getId(), weixinAccount.getSecret()),
new FileTokenStorager());
new FileTokenStorager(ConfigUtil.getValue(
"token_path", "/tmp/weixin4j/token")));
}
@Test
@@ -71,10 +71,7 @@ public class UserTest extends TokenTest {
@Test
public void list() throws WeixinException {
List<User> userList = userApi.listUser(1, true, UserStatus.BOTH, true);
Assert.assertFalse(userList.isEmpty());
System.out.println(userList);
userList = userApi.listUser(1);
List<User> userList = userApi.listUser(3, true, UserStatus.BOTH, true);
Assert.assertFalse(userList.isEmpty());
System.out.println(userList);
}