weixin4j-qy:新增媒体素材接口
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
package com.foxinmy.weixin4j.api;
|
||||
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConst;
|
||||
|
||||
/**
|
||||
* API基础
|
||||
@@ -22,12 +24,16 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
*/
|
||||
public abstract class BaseApi {
|
||||
|
||||
protected final WeixinHttpClient weixinClient = new WeixinHttpClient();
|
||||
protected final WeixinHttpClient weixinClient;
|
||||
|
||||
protected abstract String getConfigValue(String key);
|
||||
protected abstract ResourceBundle weixinBundle();
|
||||
|
||||
public BaseApi() {
|
||||
this.weixinClient = new WeixinHttpClient();
|
||||
}
|
||||
|
||||
protected String getRequestUri(String key) {
|
||||
String url = getConfigValue(key);
|
||||
String url = weixinBundle().getString(key);
|
||||
Pattern p = Pattern.compile("(\\{[^\\}]*\\})");
|
||||
Matcher m = p.matcher(url);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
@@ -44,16 +50,22 @@ public abstract class BaseApi {
|
||||
/**
|
||||
* 默认使用weixin4j.properties文件中的公众号信息
|
||||
*/
|
||||
public final static WeixinAccount DEFAULT_WEIXIN_ACCOUNT;
|
||||
public static WeixinAccount DEFAULT_WEIXIN_ACCOUNT;
|
||||
|
||||
/**
|
||||
* 默认token使用File的方式存储
|
||||
*/
|
||||
public final static TokenStorager DEFAULT_TOKEN_STORAGER;
|
||||
public static TokenStorager DEFAULT_TOKEN_STORAGER;
|
||||
|
||||
static {
|
||||
DEFAULT_WEIXIN_ACCOUNT = JSON.parseObject(
|
||||
ConfigUtil.getValue("account"), WeixinAccount.class);
|
||||
DEFAULT_TOKEN_STORAGER = new FileTokenStorager();
|
||||
try {
|
||||
DEFAULT_WEIXIN_ACCOUNT = ConfigUtil.getWeixinAccount();
|
||||
} catch (MissingResourceException e) {
|
||||
System.err
|
||||
.println("'account' key not found in weixin4j.properties file.");
|
||||
; // error
|
||||
}
|
||||
DEFAULT_TOKEN_STORAGER = new FileTokenStorager(ConfigUtil.getValue(
|
||||
"token_path", Weixin4jConst.DEFAULT_TOKEN_PATH));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,10 +128,14 @@ public class SimpleHttpClient implements HttpClient {
|
||||
httpEntity = ((HttpEntityRequest) request).getEntity();
|
||||
connection.setUseCaches(false);
|
||||
if (httpEntity != null) {
|
||||
connection.setFixedLengthStreamingMode(httpEntity
|
||||
.getContentLength());
|
||||
connection.setRequestProperty("Content-Type", httpEntity
|
||||
.getContentType().getMimeType());
|
||||
if (httpEntity.getContentLength() > 0l) {
|
||||
connection.setFixedLengthStreamingMode(httpEntity
|
||||
.getContentLength());
|
||||
}
|
||||
if (httpEntity.getContentType() != null) {
|
||||
connection.setRequestProperty("Content-Type", httpEntity
|
||||
.getContentType().getMimeType());
|
||||
}
|
||||
}
|
||||
}
|
||||
connection.connect();
|
||||
|
||||
@@ -37,56 +37,62 @@ import java.io.OutputStream;
|
||||
*/
|
||||
public class InputStreamBody extends AbstractContentBody {
|
||||
|
||||
private final InputStream in;
|
||||
private final String filename;
|
||||
private final InputStream in;
|
||||
private final String filename;
|
||||
|
||||
public InputStreamBody(final InputStream in, final String mimeType, final String filename) {
|
||||
super(mimeType);
|
||||
if (in == null) {
|
||||
throw new IllegalArgumentException("Input stream may not be null");
|
||||
}
|
||||
this.in = in;
|
||||
this.filename = filename;
|
||||
}
|
||||
public InputStreamBody(final InputStream in, final String mimeType,
|
||||
final String filename) {
|
||||
super(mimeType);
|
||||
if (in == null) {
|
||||
throw new IllegalArgumentException("Input stream may not be null");
|
||||
}
|
||||
this.in = in;
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public InputStreamBody(final InputStream in, final String filename) {
|
||||
this(in, "application/octet-stream", filename);
|
||||
}
|
||||
public InputStreamBody(final InputStream in, final String filename) {
|
||||
this(in, "application/octet-stream", filename);
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return this.in;
|
||||
}
|
||||
public InputStream getInputStream() {
|
||||
return this.in;
|
||||
}
|
||||
|
||||
public void writeTo(final OutputStream out) throws IOException {
|
||||
if (out == null) {
|
||||
throw new IllegalArgumentException("Output stream may not be null");
|
||||
}
|
||||
try {
|
||||
byte[] tmp = new byte[4096];
|
||||
int l;
|
||||
while ((l = this.in.read(tmp)) != -1) {
|
||||
out.write(tmp, 0, l);
|
||||
}
|
||||
out.flush();
|
||||
} finally {
|
||||
this.in.close();
|
||||
}
|
||||
}
|
||||
public void writeTo(final OutputStream out) throws IOException {
|
||||
if (out == null) {
|
||||
throw new IllegalArgumentException("Output stream may not be null");
|
||||
}
|
||||
try {
|
||||
byte[] tmp = new byte[4096];
|
||||
int l;
|
||||
while ((l = this.in.read(tmp)) != -1) {
|
||||
out.write(tmp, 0, l);
|
||||
}
|
||||
out.flush();
|
||||
} finally {
|
||||
this.in.close();
|
||||
}
|
||||
}
|
||||
|
||||
public String getTransferEncoding() {
|
||||
return MIME.ENC_BINARY;
|
||||
}
|
||||
public String getTransferEncoding() {
|
||||
return MIME.ENC_BINARY;
|
||||
}
|
||||
|
||||
public String getCharset() {
|
||||
return null;
|
||||
}
|
||||
public String getCharset() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public long getContentLength() {
|
||||
return -1;
|
||||
}
|
||||
public long getContentLength() {
|
||||
try {
|
||||
return in.available();
|
||||
} catch (IOException e) {
|
||||
;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return this.filename;
|
||||
}
|
||||
public String getFilename() {
|
||||
return this.filename;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.foxinmy.weixin4j.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* 媒体素材总数
|
||||
*
|
||||
* @className MediaCounter
|
||||
* @author jy
|
||||
* @date 2015年3月22日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class MediaCounter implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1752502821323552783L;
|
||||
|
||||
/**
|
||||
* 应用素材总数目(企业号独有)
|
||||
*/
|
||||
@JSONField(name = "total_count")
|
||||
private int totalCount;
|
||||
/**
|
||||
* 文件素材总数目(企业号都有)
|
||||
*/
|
||||
@JSONField(name = "file_count")
|
||||
private int fileCount;
|
||||
/**
|
||||
* 语音总数量
|
||||
*/
|
||||
@JSONField(name = "voice_count")
|
||||
private long voiceCount;
|
||||
/**
|
||||
* 视频总数量
|
||||
*/
|
||||
@JSONField(name = "video_count")
|
||||
private long videoCount;
|
||||
/**
|
||||
* 图片总数量
|
||||
*/
|
||||
@JSONField(name = "image_count")
|
||||
private long imageCount;
|
||||
/**
|
||||
* 图文总数量
|
||||
*/
|
||||
@JSONField(name = "news_count")
|
||||
private long newsCount;
|
||||
|
||||
public long getVoiceCount() {
|
||||
return voiceCount;
|
||||
}
|
||||
|
||||
public void setVoiceCount(long voiceCount) {
|
||||
this.voiceCount = voiceCount;
|
||||
}
|
||||
|
||||
public long getVideoCount() {
|
||||
return videoCount;
|
||||
}
|
||||
|
||||
public void setVideoCount(long videoCount) {
|
||||
this.videoCount = videoCount;
|
||||
}
|
||||
|
||||
public long getImageCount() {
|
||||
return imageCount;
|
||||
}
|
||||
|
||||
public void setImageCount(long imageCount) {
|
||||
this.imageCount = imageCount;
|
||||
}
|
||||
|
||||
public long getNewsCount() {
|
||||
return newsCount;
|
||||
}
|
||||
|
||||
public void setNewsCount(long newsCount) {
|
||||
this.newsCount = newsCount;
|
||||
}
|
||||
|
||||
public int getTotalCount() {
|
||||
return totalCount;
|
||||
}
|
||||
|
||||
public void setTotalCount(int totalCount) {
|
||||
this.totalCount = totalCount;
|
||||
}
|
||||
|
||||
public int getFileCount() {
|
||||
return fileCount;
|
||||
}
|
||||
|
||||
public void setFileCount(int fileCount) {
|
||||
this.fileCount = fileCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MediaCounter [totalCount=" + totalCount + ", fileCount="
|
||||
+ fileCount + ", voiceCount=" + voiceCount + ", videoCount="
|
||||
+ videoCount + ", imageCount=" + imageCount + ", newsCount="
|
||||
+ newsCount + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.foxinmy.weixin4j.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.tuple.MpArticle;
|
||||
|
||||
/**
|
||||
* 媒体素材信息
|
||||
*
|
||||
* @className MediaItem
|
||||
* @author jy
|
||||
* @date 2015年3月22日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class MediaItem implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -2923028664954250134L;
|
||||
|
||||
/**
|
||||
* 媒体素材ID
|
||||
*/
|
||||
@JSONField(name = "media_id")
|
||||
private String mediaId;
|
||||
/**
|
||||
* 媒体素材名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 媒体素材最后更新时间
|
||||
*/
|
||||
@JSONField(name = "update_time")
|
||||
private Date updateTime;
|
||||
/**
|
||||
* 图文素材列表
|
||||
*/
|
||||
@JSONField(name = "articles")
|
||||
private List<MpArticle> articles;
|
||||
|
||||
public String getMediaId() {
|
||||
return mediaId;
|
||||
}
|
||||
|
||||
public void setMediaId(String mediaId) {
|
||||
this.mediaId = mediaId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public List<MpArticle> getArticles() {
|
||||
return articles;
|
||||
}
|
||||
|
||||
public void setArticles(List<MpArticle> articles) {
|
||||
this.articles = articles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MediaItem [mediaId=" + mediaId + ", name=" + name
|
||||
+ ", updateTime=" + updateTime + ", articles=" + articles + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.foxinmy.weixin4j.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.foxinmy.weixin4j.type.MediaType;
|
||||
|
||||
/**
|
||||
* 媒体素材记录
|
||||
*
|
||||
* @className MediaRecord
|
||||
* @author jy
|
||||
* @date 2015年3月22日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public class MediaRecord implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7017503153256241457L;
|
||||
|
||||
/**
|
||||
* 该类型的素材的总数
|
||||
*/
|
||||
@JSONField(name = "total_count")
|
||||
private int totalCount;
|
||||
/**
|
||||
* 本次调用获取的素材的数量
|
||||
*/
|
||||
@JSONField(name = "item_count")
|
||||
private int itemCount;
|
||||
/**
|
||||
* 媒体类型
|
||||
*/
|
||||
@JSONField(serialize = false)
|
||||
private MediaType mediaType;
|
||||
/**
|
||||
* 媒体信息
|
||||
*/
|
||||
@JSONField(name = "item")
|
||||
private List<MediaItem> items;
|
||||
|
||||
public int getTotalCount() {
|
||||
return totalCount;
|
||||
}
|
||||
|
||||
public void setTotalCount(int totalCount) {
|
||||
this.totalCount = totalCount;
|
||||
}
|
||||
|
||||
public int getItemCount() {
|
||||
return itemCount;
|
||||
}
|
||||
|
||||
public void setItemCount(int itemCount) {
|
||||
this.itemCount = itemCount;
|
||||
}
|
||||
|
||||
public MediaType getMediaType() {
|
||||
return mediaType;
|
||||
}
|
||||
|
||||
public void setMediaType(MediaType mediaType) {
|
||||
this.mediaType = mediaType;
|
||||
}
|
||||
|
||||
public List<MediaItem> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(List<MediaItem> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MediaRecord [totalCount=" + totalCount + ", itemCount="
|
||||
+ itemCount + ", mediaType=" + mediaType + ", items=" + items
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import com.foxinmy.weixin4j.type.BillType;
|
||||
import com.foxinmy.weixin4j.type.CurrencyType;
|
||||
import com.foxinmy.weixin4j.type.IdQuery;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
import com.foxinmy.weixin4j.util.Weixin4jConst;
|
||||
|
||||
/**
|
||||
* 微信支付接口实现
|
||||
@@ -64,7 +65,8 @@ public class WeixinPayProxy {
|
||||
this.pay3Api = new Pay3Api(weixinAccount);
|
||||
this.couponApi = new CouponApi(weixinAccount);
|
||||
this.cashApi = new CashApi(weixinAccount);
|
||||
this.DEFAULT_CA_FILE = new File(ConfigUtil.getClassPathValue("ca_file"));
|
||||
this.DEFAULT_CA_FILE = new File(ConfigUtil.getClassPathValue("ca_file",
|
||||
Weixin4jConst.DEFAULT_MEDIA_PATH));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,6 @@ import java.io.IOException;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
||||
|
||||
/**
|
||||
@@ -22,10 +21,6 @@ public class FileTokenStorager implements TokenStorager {
|
||||
|
||||
private final String cachePath;
|
||||
|
||||
public FileTokenStorager() {
|
||||
this(ConfigUtil.getValue("token_path"));
|
||||
}
|
||||
|
||||
public FileTokenStorager(String cachePath) {
|
||||
this.cachePath = cachePath;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import com.alibaba.fastjson.annotation.JSONField;
|
||||
* @see
|
||||
*/
|
||||
public class Card implements MassTuple {
|
||||
|
||||
|
||||
private static final long serialVersionUID = 6119453633595102147L;
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.foxinmy.weixin4j.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -49,6 +50,25 @@ public class ConfigUtil {
|
||||
return weixinBundle.getString(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* key不存在时则返回传入的默认值
|
||||
*
|
||||
* @param key
|
||||
* @param defaultValue
|
||||
* @return
|
||||
*/
|
||||
public static String getValue(String key, String defaultValue) {
|
||||
String value = defaultValue;
|
||||
try {
|
||||
value = weixinBundle.getString(key);
|
||||
} catch (MissingResourceException e) {
|
||||
System.err.println("'" + key
|
||||
+ "' key not found in weixin4j.properties file.");
|
||||
; // error
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断属性是否存在[classpath:]如果存在则拼接项目路径后返回 一般用于文件的绝对路径获取
|
||||
*
|
||||
@@ -60,6 +80,24 @@ public class ConfigUtil {
|
||||
CLASSPATH_VALUE)).getPath();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param key
|
||||
* @param defaultValue
|
||||
* @return
|
||||
*/
|
||||
public static String getClassPathValue(String key, String defaultValue) {
|
||||
String value = defaultValue;
|
||||
try {
|
||||
value = getClassPathValue(key);
|
||||
} catch (MissingResourceException e) {
|
||||
System.err.println("'" + key
|
||||
+ "' key not found in weixin4j.properties file.");
|
||||
; // error
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static WeixinAccount getWeixinAccount() {
|
||||
String text = getValue("account");
|
||||
return JSON.parseObject(text, WeixinAccount.class);
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.foxinmy.weixin4j.util;
|
||||
|
||||
/**
|
||||
* 常量配置
|
||||
*
|
||||
* @className Weixin4jConst
|
||||
* @author jy
|
||||
* @date 2015年7月1日
|
||||
* @since JDK 1.7
|
||||
* @see
|
||||
*/
|
||||
public final class Weixin4jConst {
|
||||
/**
|
||||
* 使用FileTokenStorager时token的存放路径
|
||||
*/
|
||||
public static final String DEFAULT_TOKEN_PATH = "/tmp/weixin4j/token";
|
||||
/**
|
||||
* 二维码保存路径
|
||||
*/
|
||||
public static final String DEFAULT_QRCODE_PATH = "/tmp/weixin4j/qrcode";
|
||||
/**
|
||||
* 媒体文件保存路径
|
||||
*/
|
||||
public static final String DEFAULT_MEDIA_PATH = "/tmp/weixin4j/media";
|
||||
/**
|
||||
* 对账单保存路径
|
||||
*/
|
||||
public static final String DEFAULT_BILL_PATH = "/tmp/weixin4j/bill";
|
||||
/**
|
||||
* ca证书存放的完整路径 (V2版本后缀为*.pfx,V3版本后缀为*.p12)
|
||||
*/
|
||||
public static final String DEFAULT_CAFILE_PATH = "classpath:ca.p12";
|
||||
}
|
||||
Reference in New Issue
Block a user