weixin4j-mp:新增图文消息中上传图片接口

This commit is contained in:
jinyu 2015-07-31 20:59:21 +08:00
parent ea03c92eb0
commit b6b1fd98ea
8 changed files with 76 additions and 18 deletions

View File

@ -399,4 +399,6 @@
+ **weixin4j-server**:`WeixinServerBootstrap` 构造函数支持多个公众号 + **weixin4j-server**:`WeixinServerBootstrap` 构造函数支持多个公众号
+ **weixin4j-server**:`MessageHandlerAdapter` 声明时限定泛型为`WeixinMessage`的子类 + **weixin4j-server**:`MessageHandlerAdapter` 声明时限定泛型为`WeixinMessage`的子类
+ **weixin4j-mp**: 新增图文消息中上传图片接口

View File

@ -317,6 +317,10 @@
<code>40121</code> <code>40121</code>
<text>不合法的media_id类型</text> <text>不合法的media_id类型</text>
</error> </error>
<error>
<code>40137</code>
<text>不支持的图片格式</text>
</error>
<error> <error>
<code>41001</code> <code>41001</code>
<desc>access_token missing</desc> <desc>access_token missing</desc>

View File

@ -126,4 +126,8 @@
+ 新增二维码结果类[QRResult.java](./src/main/java/com/foxinmy/weixin4j/mp/model/QRResult.java)并将二维码接口[QRApi.java](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/QrApi.java)名称变更为createQR和createQRFile + 新增二维码结果类[QRResult.java](./src/main/java/com/foxinmy/weixin4j/mp/model/QRResult.java)并将二维码接口[QRApi.java](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/QrApi.java)名称变更为createQR和createQRFile
+ [Oauth授权](./src/main/java/com/foxinmy/weixin4j/mp/api/OauthApi.java)跳转的uri在配置文件的属性名改为`oauth_redirect_uri` + [Oauth授权](./src/main/java/com/foxinmy/weixin4j/mp/api/OauthApi.java)跳转的uri在配置文件的属性名改为`oauth_redirect_uri`
* 2015-07-31
+ 新增图文消息中上传图片接口

View File

@ -128,6 +128,23 @@ public class WeixinProxy {
return this.tokenHolder; return this.tokenHolder;
} }
/**
* 上传图文消息内的图片获取URL
* 请注意本接口所上传的图片不占用公众号的素材库中图片数量的5000个的限制图片仅支持jpg/png格式大小必须在1MB以下
*
* @param is
* 图片数据流
* @param fileName
* 文件名 为空时将自动生成
* @return 图片URL 可用于后续群发中放置到图文消息中
* @see com.foxinmy.weixin4j.mp.api.MediaApi
* @throws WeixinException
*/
public String uploadImage(InputStream is, String fileName)
throws WeixinException {
return mediaApi.uploadImage(is, fileName);
}
/** /**
* 上传媒体文件 </br> <font color="red">此接口只包含图片语音缩略图视频(临时)四种媒体类型的上传</font> * 上传媒体文件 </br> <font color="red">此接口只包含图片语音缩略图视频(临时)四种媒体类型的上传</font>
* <p> * <p>
@ -148,7 +165,7 @@ public class WeixinProxy {
* href="http://mp.weixin.qq.com/wiki/14/7e6c03263063f4813141c3e17dd4350a.html">上传永久素材</a> * href="http://mp.weixin.qq.com/wiki/14/7e6c03263063f4813141c3e17dd4350a.html">上传永久素材</a>
* @see com.foxinmy.weixin4j.model.MediaUploadResult * @see com.foxinmy.weixin4j.model.MediaUploadResult
* @see com.foxinmy.weixin4j.type.MediaType * @see com.foxinmy.weixin4j.type.MediaType
* @see com.com.foxinmy.weixin4j.mp.api.MediaApi * @see com.foxinmy.weixin4j.mp.api.MediaApi
* @throws WeixinException * @throws WeixinException
*/ */
public MediaUploadResult uploadMedia(boolean isMaterial, InputStream is, public MediaUploadResult uploadMedia(boolean isMaterial, InputStream is,
@ -172,7 +189,7 @@ public class WeixinProxy {
* @throws WeixinException * @throws WeixinException
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/10/78b15308b053286e2a66b33f0f0f5fb6.html">上传下载说明</a> * href="http://mp.weixin.qq.com/wiki/10/78b15308b053286e2a66b33f0f0f5fb6.html">上传下载说明</a>
* @see com.com.foxinmy.weixin4j.mp.api.MediaApi * @see com.foxinmy.weixin4j.mp.api.MediaApi
* @see {@link #downloadMedia(String)} * @see {@link #downloadMedia(String)}
*/ */
public File downloadMediaFile(String mediaId, boolean isMaterial) public File downloadMediaFile(String mediaId, boolean isMaterial)
@ -189,7 +206,7 @@ public class WeixinProxy {
* 是否永久素材 * 是否永久素材
* @return 媒体文件下载结果 * @return 媒体文件下载结果
* @throws WeixinException * @throws WeixinException
* @see com.com.foxinmy.weixin4j.mp.api.MediaApi * @see com.foxinmy.weixin4j.mp.api.MediaApi
* @see com.foxinmy.weixin4j.model.MediaDownloadResult * @see com.foxinmy.weixin4j.model.MediaDownloadResult
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/10/78b15308b053286e2a66b33f0f0f5fb6.html">上传下载说明</a> * href="http://mp.weixin.qq.com/wiki/10/78b15308b053286e2a66b33f0f0f5fb6.html">上传下载说明</a>
@ -210,7 +227,7 @@ public class WeixinProxy {
* 图文列表 * 图文列表
* @return 上传到微信服务器返回的媒体标识 * @return 上传到微信服务器返回的媒体标识
* @throws WeixinException * @throws WeixinException
* @see com.com.foxinmy.weixin4j.mp.api.MediaApi * @see com.foxinmy.weixin4j.mp.api.MediaApi
* @see com.foxinmy.weixin4j.tuple.MpArticle * @see com.foxinmy.weixin4j.tuple.MpArticle
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/14/7e6c03263063f4813141c3e17dd4350a.html">上传永久媒体素材</a> * href="http://mp.weixin.qq.com/wiki/14/7e6c03263063f4813141c3e17dd4350a.html">上传永久媒体素材</a>
@ -229,7 +246,7 @@ public class WeixinProxy {
* @throws WeixinException * @throws WeixinException
* @see {@link #downloadMedia(String, boolean)} * @see {@link #downloadMedia(String, boolean)}
* @see com.foxinmy.weixin4j.tuple.MpArticle * @see com.foxinmy.weixin4j.tuple.MpArticle
* @see com.com.foxinmy.weixin4j.mp.api.MediaApi * @see com.foxinmy.weixin4j.mp.api.MediaApi
*/ */
public List<MpArticle> downloadArticle(String mediaId) public List<MpArticle> downloadArticle(String mediaId)
throws WeixinException { throws WeixinException {
@ -247,7 +264,7 @@ public class WeixinProxy {
* 图文列表 * 图文列表
* @return 处理结果 * @return 处理结果
* @throws WeixinException * @throws WeixinException
* @see com.com.foxinmy.weixin4j.mp.api.MediaApi * @see com.foxinmy.weixin4j.mp.api.MediaApi
* @see com.foxinmy.weixin4j.tuple.MpArticle * @see com.foxinmy.weixin4j.tuple.MpArticle
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/4/19a59cba020d506e767360ca1be29450.html">更新永久图文素材</a> * href="http://mp.weixin.qq.com/wiki/4/19a59cba020d506e767360ca1be29450.html">更新永久图文素材</a>
@ -264,7 +281,7 @@ public class WeixinProxy {
* 媒体素材的media_id * 媒体素材的media_id
* @return 处理结果 * @return 处理结果
* @throws WeixinException * @throws WeixinException
* @see com.com.foxinmy.weixin4j.mp.api.MediaApi * @see com.foxinmy.weixin4j.mp.api.MediaApi
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/5/e66f61c303db51a6c0f90f46b15af5f5.html">删除永久媒体素材</a> * href="http://mp.weixin.qq.com/wiki/5/e66f61c303db51a6c0f90f46b15af5f5.html">删除永久媒体素材</a>
*/ */
@ -285,7 +302,7 @@ public class WeixinProxy {
* @return 上传到微信服务器返回的媒体标识 * @return 上传到微信服务器返回的媒体标识
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/14/7e6c03263063f4813141c3e17dd4350a.html">上传永久媒体素材</a> * href="http://mp.weixin.qq.com/wiki/14/7e6c03263063f4813141c3e17dd4350a.html">上传永久媒体素材</a>
* @see com.com.foxinmy.weixin4j.mp.api.MediaApi * @see com.foxinmy.weixin4j.mp.api.MediaApi
* @throws WeixinException * @throws WeixinException
*/ */
public String uploadMaterialVideo(InputStream is, String title, public String uploadMaterialVideo(InputStream is, String title,
@ -301,7 +318,7 @@ public class WeixinProxy {
* @see com.foxinmy.weixin4j.mp.model.MediaCounter * @see com.foxinmy.weixin4j.mp.model.MediaCounter
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/16/8cc64f8c189674b421bee3ed403993b8.html">获取素材总数</a> * href="http://mp.weixin.qq.com/wiki/16/8cc64f8c189674b421bee3ed403993b8.html">获取素材总数</a>
* @see com.com.foxinmy.weixin4j.mp.api.MediaApi * @see com.foxinmy.weixin4j.mp.api.MediaApi
*/ */
public MediaCounter countMaterialMedia() throws WeixinException { public MediaCounter countMaterialMedia() throws WeixinException {
return mediaApi.countMaterialMedia(); return mediaApi.countMaterialMedia();
@ -318,7 +335,7 @@ public class WeixinProxy {
* 返回素材的数量取值在1到20之间 * 返回素材的数量取值在1到20之间
* @return 媒体素材的记录对象 * @return 媒体素材的记录对象
* @throws WeixinException * @throws WeixinException
* @see com.com.foxinmy.weixin4j.mp.api.MediaApi * @see com.foxinmy.weixin4j.mp.api.MediaApi
* @see com.foxinmy.weixin4j.mp.model.MediaRecord * @see com.foxinmy.weixin4j.mp.model.MediaRecord
* @see com.foxinmy.weixin4j.type.MediaType * @see com.foxinmy.weixin4j.type.MediaType
* @see com.foxinmy.weixin4j.mp.model.MediaItem * @see com.foxinmy.weixin4j.mp.model.MediaItem
@ -336,7 +353,7 @@ public class WeixinProxy {
* @param mediaType * @param mediaType
* 媒体类型 * 媒体类型
* @return 素材列表 * @return 素材列表
* @see com.com.foxinmy.weixin4j.mp.api.MediaApi * @see com.foxinmy.weixin4j.mp.api.MediaApi
* @see {@link #listMaterialMedia(MediaType, int, int)} * @see {@link #listMaterialMedia(MediaType, int, int)}
* @throws WeixinException * @throws WeixinException
*/ */
@ -636,7 +653,7 @@ public class WeixinProxy {
* @see com.foxinmy.weixin4j.mp.api.MassApi * @see com.foxinmy.weixin4j.mp.api.MassApi
* @see com.foxinmy.weixin4j.tuple.Video * @see com.foxinmy.weixin4j.tuple.Video
* @see com.foxinmy.weixin4j.tuple.MpVideo * @see com.foxinmy.weixin4j.tuple.MpVideo
* @see {@link com.com.foxinmy.weixin4j.mp.api.MediaApi#uploadMedia(File)} * @see {@link com.foxinmy.weixin4j.mp.api.MediaApi#uploadMedia(File)}
*/ */
public String uploadMassVideo(Video video) throws WeixinException { public String uploadMassVideo(Video video) throws WeixinException {
return massApi.uploadVideo(video); return massApi.uploadVideo(video);
@ -718,7 +735,7 @@ public class WeixinProxy {
* @see com.foxinmy.weixin4j.tuple.MassTuple * @see com.foxinmy.weixin4j.tuple.MassTuple
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E6.A0.B9.E6.8D.AEOpenID.E5.88.97.E8.A1.A8.E7.BE.A4.E5.8F.91.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8D.E5.8F.AF.E7.94.A8.EF.BC.8C.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.8F.AF.E7.94.A8.E3.80.91">根据openid群发</a> * href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E6.A0.B9.E6.8D.AEOpenID.E5.88.97.E8.A1.A8.E7.BE.A4.E5.8F.91.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8D.E5.8F.AF.E7.94.A8.EF.BC.8C.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.8F.AF.E7.94.A8.E3.80.91">根据openid群发</a>
* @see {@link com.com.foxinmy.weixin4j.mp.api.MediaApi#uploadMedia(File)} * @see {@link com.foxinmy.weixin4j.mp.api.MediaApi#uploadMedia(File)}
* @see {@link com.foxinmy.weixin4j.mp.api.UserApi#getUser(String)} * @see {@link com.foxinmy.weixin4j.mp.api.UserApi#getUser(String)}
*/ */
public String massByOpenIds(MassTuple tuple, String... openIds) public String massByOpenIds(MassTuple tuple, String... openIds)

View File

@ -64,6 +64,34 @@ public class MediaApi extends MpApi {
this.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");
}
/** /**
* 上传媒体文件:图片image语音voice视频(video)和缩略图thumb </br> <font * 上传媒体文件:图片image语音voice视频(video)和缩略图thumb </br> <font
* color="red">此接口只包含图片语音缩略图视频(临时)四种媒体类型的上传</font> * color="red">此接口只包含图片语音缩略图视频(临时)四种媒体类型的上传</font>

View File

@ -31,6 +31,8 @@ qr_ticket_uri={api_cgi_url}/qrcode/create?access_token=%s
qr_image_uri={mp_base_url}/showqrcode?ticket=%s qr_image_uri={mp_base_url}/showqrcode?ticket=%s
# \u4e0a\u4f20\u5a92\u4f53\u6587\u4ef6 # \u4e0a\u4f20\u5a92\u4f53\u6587\u4ef6
media_upload_uri={file_base_url}/media/upload?access_token=%s&type=%s media_upload_uri={file_base_url}/media/upload?access_token=%s&type=%s
# \u4e0a\u4f20\u56fe\u7247
image_upload_uri={api_cgi_url}/media/uploadimg?access_token=%s
# \u4e0b\u8f7d\u5a92\u4f53\u6587\u4ef6 # \u4e0b\u8f7d\u5a92\u4f53\u6587\u4ef6
meida_download_uri={file_base_url}/media/get?access_token=%s&media_id=%s meida_download_uri={file_base_url}/media/get?access_token=%s&media_id=%s
# \u53d1\u9001\u5ba2\u670d\u6d88\u606f # \u53d1\u9001\u5ba2\u670d\u6d88\u606f

View File

@ -26,8 +26,9 @@ public class ArticleSummary extends ArticleDatacube1 {
@JSONField(name = "ref_hour") @JSONField(name = "ref_hour")
private int refHour; private int refHour;
/** /**
* 这里的msgid实际上是由msgid图文消息id和index消息次序索引组成 例如12003_3 * 请注意这里的msgid实际上是由msgid图文消息id这也就是群发接口调用后返回的msg_data_id和index消息次序索引组成
* 其中12003是msgid即一次群发的id消息的 3为index假设该次群发的图文消息共5个文章因为可能为多图文 3表示5个中的第3个 * 例如12003_3 其中12003是msgid即一次群发的消息的id
* 3为index假设该次群发的图文消息共5个文章因为可能为多图文3表示5个中的第3个
*/ */
private String msgid; private String msgid;
/** /**

View File

@ -10,7 +10,7 @@ package com.foxinmy.weixin4j.mp.type;
* @see * @see
*/ */
public enum UserSourceType { public enum UserSourceType {
OTHER("其它"), QRCODE("扫二维码"), CARDSHARE("名片分享"), SONUMBER("搜号码(即微信添加朋友页的搜索)"), SOMPACCOUNT( OTHER("其它(包括带参数二维码)"), QRCODE("扫二维码"), CARDSHARE("名片分享"), SONUMBER("搜号码(即微信添加朋友页的搜索)"), SOMPACCOUNT(
"查询微信公众帐号"), ARTICLEMENU("图文页右上角菜单"); "查询微信公众帐号"), ARTICLEMENU("图文页右上角菜单");
private String desc; private String desc;