From e8422b1076a4ea185f9087be31819b14175220ee Mon Sep 17 00:00:00 2001
From: jinyu
Date: Sat, 27 Jun 2015 09:14:45 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AA=92=E4=BD=93=E6=8E=A5=E5=8F=A3(MediaApi)?=
=?UTF-8?q?=E4=B8=AD=E4=B8=8A=E4=BC=A0=E6=96=B9=E6=B3=95=E4=B8=AD=E7=9A=84?=
=?UTF-8?q?File=E7=B1=BB=E5=9E=8B=E8=B0=83=E6=95=B4=E4=B8=BAInputStream?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CHANGE.md | 6 +-
.../foxinmy/weixin4j/http/ContentType.java | 6 +
.../com/foxinmy/weixin4j/type/MediaType.java | 30 +-
.../com/foxinmy/weixin4j/util/ObjectId.java | 333 ++++++++++++++++++
.../com/foxinmy/weixin4j/mp/WeixinProxy.java | 50 +--
.../com/foxinmy/weixin4j/mp/api/MediaApi.java | 113 +++---
.../foxinmy/weixin4j/mp/test/MassTest.java | 7 +-
.../foxinmy/weixin4j/mp/test/MediaTest.java | 15 +-
.../foxinmy/weixin4j/mp/test/NotifyTest.java | 4 +-
.../com/foxinmy/weixin4j/qy/WeixinProxy.java | 48 +--
.../com/foxinmy/weixin4j/qy/api/MediaApi.java | 86 ++---
.../com/foxinmy/weixin4j/qy/api/UserApi.java | 19 +-
.../foxinmy/weixin4j/qy/test/MediaTest.java | 7 +-
13 files changed, 503 insertions(+), 221 deletions(-)
create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ObjectId.java
diff --git a/CHANGE.md b/CHANGE.md
index 8316f902..b5fd93a3 100644
--- a/CHANGE.md
+++ b/CHANGE.md
@@ -357,4 +357,8 @@
+ 将微信支付模块移到base工程
- + **weixin4j-qy**: 管理成员新增头像参数
\ No newline at end of file
+ + **weixin4j-qy**: 管理成员新增头像参数
+
+* 2015-06-27
+
+ + 媒体接口(MediaApi)中上传方法中的File类型调整为InputStream
\ No newline at end of file
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/ContentType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/ContentType.java
index 43f8d8be..1e1355ee 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/ContentType.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/ContentType.java
@@ -40,6 +40,12 @@ public final class ContentType implements Serializable {
Consts.UTF_8);
public static final ContentType TEXT_PLAIN = create("text/plain",
Consts.UTF_8);
+ public static final ContentType IMAGE_JPG = create("image/jpg",
+ Consts.UTF_8);
+ public static final ContentType AUDIO_MP3 = create("audio/mp3",
+ Consts.UTF_8);
+ public static final ContentType VIDEO_MPEG4 = create("video/mpeg4",
+ Consts.UTF_8);
public static final ContentType TEXT_XML = create("text/xml", Consts.UTF_8);
public static final ContentType WILDCARD = create("*/*", (Charset) null);
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/MediaType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/MediaType.java
index daca3d44..3c927496 100644
--- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/MediaType.java
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/MediaType.java
@@ -1,5 +1,7 @@
package com.foxinmy.weixin4j.type;
+import com.foxinmy.weixin4j.http.ContentType;
+
/**
* 上传的媒体类型
*
@@ -21,28 +23,18 @@ package com.foxinmy.weixin4j.type;
* @since JDK 1.7
*/
public enum MediaType {
- image("jpg"), voice("amr/mp3"), video("mp4"), thumb("jpg"), file("unknown"), news(
- "");
+ image(ContentType.IMAGE_JPG), voice(ContentType.AUDIO_MP3), video(
+ ContentType.VIDEO_MPEG4), thumb(ContentType.IMAGE_JPG), file(
+ ContentType.APPLICATION_OCTET_STREAM), news(
+ ContentType.APPLICATION_OCTET_STREAM);
- MediaType(String formatName) {
- this.formatName = formatName;
+ MediaType(ContentType contentType) {
+ this.contentType = contentType;
}
- public static MediaType getMediaType(String key) {
- if (key.equals("jpg")) {
- return MediaType.image;
- } else if ("amr/mp3".contains(key)) {
- return MediaType.voice;
- } else if (key.equals("mp4")) {
- return MediaType.video;
- } else {
- return MediaType.file;
- }
- }
+ private ContentType contentType;
- private String formatName;
-
- public String getFormatName() {
- return formatName;
+ public ContentType getContentType() {
+ return contentType;
}
}
diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ObjectId.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ObjectId.java
new file mode 100644
index 00000000..ccdd95b4
--- /dev/null
+++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ObjectId.java
@@ -0,0 +1,333 @@
+package com.foxinmy.weixin4j.util;
+
+/*
+ * Copyright (c) 2008-2014 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.net.NetworkInterface;
+import java.nio.ByteBuffer;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * A globally unique identifier for objects.
+ *
+ *
+ *
+ * Consists of 12 bytes, divided as follows:
+ *
+ *
+ * ObjectID layout
+ *
+ * | 0 |
+ * 1 |
+ * 2 |
+ * 3 |
+ * 4 |
+ * 5 |
+ * 6 |
+ * 7 |
+ * 8 |
+ * 9 |
+ * 10 |
+ * 11 |
+ *
+ *
+ * | time |
+ * machine |
+ * pid |
+ * inc |
+ *
+ *
+ *
+ *
+ * Instances of this class are immutable.
+ *
+ *
+ * @mongodb.driver.manual core/object-id ObjectId
+ */
+public class ObjectId implements Comparable, java.io.Serializable {
+
+ private static final long serialVersionUID = -4415279469780082174L;
+
+ static final Logger LOGGER = Logger.getLogger("org.bson.ObjectId");
+
+ /**
+ * Gets a new object id.
+ *
+ * @return the new id
+ */
+ public static ObjectId get() {
+ return new ObjectId();
+ }
+
+ /**
+ * Checks if a string could be an {@code ObjectId}.
+ *
+ * @param s
+ * a potential ObjectId as a String.
+ * @return whether the string could be an object id
+ * @throws IllegalArgumentException
+ * if hexString is null
+ */
+ public static boolean isValid(String s) {
+ if (s == null)
+ return false;
+
+ final int len = s.length();
+ if (len != 24)
+ return false;
+
+ for (int i = 0; i < len; i++) {
+ char c = s.charAt(i);
+ if (c >= '0' && c <= '9')
+ continue;
+ if (c >= 'a' && c <= 'f')
+ continue;
+ if (c >= 'A' && c <= 'F')
+ continue;
+
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Constructs an ObjectId given its 12-byte binary representation.
+ *
+ * @param b
+ * a byte array of length 12
+ */
+ public ObjectId(byte[] b) {
+ if (b.length != 12)
+ throw new IllegalArgumentException("need 12 bytes");
+ ByteBuffer bb = ByteBuffer.wrap(b);
+ _time = bb.getInt();
+ _machine = bb.getInt();
+ _inc = bb.getInt();
+ _new = false;
+ }
+
+ /**
+ * Create a new object id.
+ */
+ public ObjectId() {
+ _time = (int) (System.currentTimeMillis() / 1000);
+ _machine = _genmachine;
+ _inc = _nextInc.getAndIncrement();
+ _new = true;
+ }
+
+ @Override
+ public int hashCode() {
+ int x = _time;
+ x += (_machine * 111);
+ x += (_inc * 17);
+ return x;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ ObjectId other = (ObjectId) o;
+ if (other == null)
+ return false;
+
+ return _time == other._time && _machine == other._machine
+ && _inc == other._inc;
+ }
+
+ /**
+ * Converts this instance into a 24-byte hexadecimal string representation.
+ *
+ * @return a string representation of the ObjectId in hexadecimal format
+ */
+ public String toHexString() {
+ final StringBuilder buf = new StringBuilder(24);
+
+ for (final byte b : toByteArray()) {
+ buf.append(String.format("%02x", b & 0xff));
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * Convert to a byte array. Note that the numbers are stored in big-endian
+ * order.
+ *
+ * @return the byte array
+ */
+ public byte[] toByteArray() {
+ byte b[] = new byte[12];
+ ByteBuffer bb = ByteBuffer.wrap(b);
+ // by default BB is big endian like we need
+ bb.putInt(_time);
+ bb.putInt(_machine);
+ bb.putInt(_inc);
+ return b;
+ }
+
+ static String _pos(String s, int p) {
+ return s.substring(p * 2, (p * 2) + 2);
+ }
+
+ public String toString() {
+ byte b[] = toByteArray();
+
+ StringBuilder buf = new StringBuilder(24);
+
+ for (int i = 0; i < b.length; i++) {
+ int x = b[i] & 0xFF;
+ String s = Integer.toHexString(x);
+ if (s.length() == 1)
+ buf.append("0");
+ buf.append(s);
+ }
+
+ return buf.toString();
+ }
+
+ int _compareUnsigned(int i, int j) {
+ long li = 0xFFFFFFFFL;
+ li = i & li;
+ long lj = 0xFFFFFFFFL;
+ lj = j & lj;
+ long diff = li - lj;
+ if (diff < Integer.MIN_VALUE)
+ return Integer.MIN_VALUE;
+ if (diff > Integer.MAX_VALUE)
+ return Integer.MAX_VALUE;
+ return (int) diff;
+ }
+
+ public int compareTo(ObjectId id) {
+ if (id == null)
+ return -1;
+
+ int x = _compareUnsigned(_time, id._time);
+ if (x != 0)
+ return x;
+
+ x = _compareUnsigned(_machine, id._machine);
+ if (x != 0)
+ return x;
+
+ return _compareUnsigned(_inc, id._inc);
+ }
+
+ /**
+ * Gets the timestamp (number of seconds since the Unix epoch).
+ *
+ * @return the timestamp
+ */
+ public int getTimestamp() {
+ return _time;
+ }
+
+ /**
+ * Gets the timestamp as a {@code Date} instance.
+ *
+ * @return the Date
+ */
+ public Date getDate() {
+ return new Date(_time * 1000L);
+ }
+
+ /**
+ * Gets the current value of the auto-incrementing counter.
+ *
+ * @return the current counter value.
+ */
+ public static int getCurrentCounter() {
+ return _nextInc.get();
+ }
+
+ final int _time;
+ final int _machine;
+ final int _inc;
+
+ boolean _new;
+
+ private static AtomicInteger _nextInc = new AtomicInteger(
+ (new java.util.Random()).nextInt());
+
+ private static final int _genmachine;
+ static {
+
+ try {
+ // build a 2-byte machine piece based on NICs info
+ int machinePiece;
+ {
+ try {
+ StringBuilder sb = new StringBuilder();
+ Enumeration e = NetworkInterface
+ .getNetworkInterfaces();
+ while (e.hasMoreElements()) {
+ NetworkInterface ni = e.nextElement();
+ sb.append(ni.toString());
+ }
+ machinePiece = sb.toString().hashCode() << 16;
+ } catch (Throwable e) {
+ // exception sometimes happens with IBM JVM, use random
+ LOGGER.log(Level.WARNING, e.getMessage(), e);
+ machinePiece = (new Random().nextInt()) << 16;
+ }
+ LOGGER.fine("machine piece post: "
+ + Integer.toHexString(machinePiece));
+ }
+
+ // add a 2 byte process piece. It must represent not only the JVM
+ // but the class loader.
+ // Since static var belong to class loader there could be collisions
+ // otherwise
+ final int processPiece;
+ {
+ int processId = new java.util.Random().nextInt();
+ try {
+ processId = java.lang.management.ManagementFactory
+ .getRuntimeMXBean().getName().hashCode();
+ } catch (Throwable t) {
+ }
+
+ ClassLoader loader = ObjectId.class.getClassLoader();
+ int loaderId = loader != null
+ ? System.identityHashCode(loader)
+ : 0;
+
+ StringBuilder sb = new StringBuilder();
+ sb.append(Integer.toHexString(processId));
+ sb.append(Integer.toHexString(loaderId));
+ processPiece = sb.toString().hashCode() & 0xFFFF;
+ LOGGER.fine("process piece: "
+ + Integer.toHexString(processPiece));
+ }
+
+ _genmachine = machinePiece | processPiece;
+ LOGGER.fine("machine : " + Integer.toHexString(_genmachine));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+}
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java
index a890ab39..1d05bfb5 100644
--- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java
+++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java
@@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.mp;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.util.Date;
import java.util.List;
@@ -132,7 +133,8 @@ public class WeixinProxy {
* @param isMaterial
* 是否永久上传
* @return 上传到微信服务器返回的媒体标识
- * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#uploadMedia(File, MediaType)}
+ * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#uploadMedia(InputStream, MediaType,boolean)}
+ * @see com.foxinmy.weixin4j.mp.api.MediaApi
* @throws WeixinException
* @throws IOException
*/
@@ -142,49 +144,30 @@ public class WeixinProxy {
}
/**
- * 上传媒体文件
- *
- * @param file
- * 文件对象
- * @param mediaType
- * 媒体类型
- * @param isMaterial
- * 是否永久上传
- * @return 上传到微信服务器返回的媒体标识
- * @throws WeixinException
- * @throws IOException
- * @see com.foxinmy.weixin4j.type.MediaType
- * @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#uploadMedia(String, byte[],String)}
- */
- public String uploadMedia(File file, MediaType mediaType, boolean isMaterial)
- throws WeixinException, IOException {
- return mediaApi.uploadMedia(file, mediaType, isMaterial);
- }
-
- /**
- * 上传媒体文件
+ * 上传媒体文件 此接口只包含图片、语音、缩略图、视频(临时)四种媒体类型的上传
*
* 正常情况下返回{"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789},
* 否则抛出异常.
*
*
- * @param fileName
- * 文件名
- * @param data
- * 媒体数据包
+ * @param is
+ * 媒体数据流
* @param mediaType
- * 媒体类型
+ * 媒体文件类型:分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb)
* @param isMaterial
* 是否永久上传
* @return 上传到微信服务器返回的媒体标识
* @see 上传下载说明
+ * href="http://mp.weixin.qq.com/wiki/5/963fc70b80dc75483a271298a76a8d59.html">上传临时素材
+ * @see 上传永久素材
+ * @see com.foxinmy.weixin4j.type.MediaType
* @see com.foxinmy.weixin4j.mp.api.MediaApi
* @throws WeixinException
*/
- public String uploadMedia(String fileName, byte[] data, String mediaType,
+ public String uploadMedia(InputStream is, MediaType mediaType,
boolean isMaterial) throws WeixinException {
- return mediaApi.uploadMedia(fileName, data, mediaType, isMaterial);
+ return mediaApi.uploadMedia(is, mediaType, isMaterial);
}
/**
@@ -203,13 +186,12 @@ public class WeixinProxy {
* @throws WeixinException
* @see 上传下载说明
- * @see com.foxinmy.weixin4j.type.MediaType
* @see com.foxinmy.weixin4j.mp.api.MediaApi
* @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#downloadMedia(String)}
*/
- public File downloadMedia(String mediaId, MediaType mediaType,
- boolean isMaterial) throws WeixinException {
- return mediaApi.downloadMedia(mediaId, mediaType, isMaterial);
+ public File downloadMediaFile(String mediaId, boolean isMaterial)
+ throws WeixinException {
+ return mediaApi.downloadMediaFile(mediaId, isMaterial);
}
/**
diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MediaApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MediaApi.java
index fa366615..218ca1e8 100644
--- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MediaApi.java
+++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MediaApi.java
@@ -4,6 +4,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
@@ -16,6 +17,7 @@ import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.apache.ByteArrayBody;
import com.foxinmy.weixin4j.http.apache.FormBodyPart;
+import com.foxinmy.weixin4j.http.apache.InputStreamBody;
import com.foxinmy.weixin4j.http.apache.StringBody;
import com.foxinmy.weixin4j.http.weixin.JsonResult;
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
@@ -30,6 +32,7 @@ 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;
/**
@@ -57,7 +60,7 @@ public class MediaApi extends MpApi {
* @param isMaterial
* 是否永久上传
* @return 上传到微信服务器返回的媒体标识
- * @see {@link com.foxinmy.weixin4j.mp.api.MediaApi#uploadMedia(File, MediaType)}
+ * @see {@link com.foxinmy.weixin4j.mp.api.MediaApi#uploadMedia(InputStream, MediaType,boolean)}
* @throws WeixinException
* @throws IOException
*/
@@ -67,28 +70,17 @@ public class MediaApi extends MpApi {
if (StringUtil.isBlank(mediaTypeKey)) {
mediaTypeKey = FileUtil.getFileType(file);
}
- MediaType mediaType = MediaType.getMediaType(mediaTypeKey);
- return uploadMedia(file, mediaType, isMaterial);
- }
-
- /**
- * 上传媒体文件 此接口只包含图片、语音、缩略图三种媒体类型的上传
- *
- * @param file
- * 文件对象
- * @param mediaType
- * 媒体类型 (image)、语音(voice)和缩略图(thumb)
- * @param isMaterial
- * 是否永久上传
- * @return 上传到微信服务器返回的媒体标识
- * @throws WeixinException
- * @see com.foxinmy.weixin4j.type.MediaType
- * @see {@link com.foxinmy.weixin4j.mp.api.MediaApi#uploadMedia(String, byte[],String,boolean)}
- */
- public String uploadMedia(File file, MediaType mediaType, boolean isMaterial)
- throws WeixinException, IOException {
- byte[] datas = IOUtil.toByteArray(new FileInputStream(file));
- return uploadMedia(file.getName(), datas, mediaType.name(), isMaterial);
+ MediaType mediaType = null;
+ if ("bmp/png/jpeg/jpg/gif".contains(mediaTypeKey)) {
+ mediaType = MediaType.image;
+ } else if ("amr/mp3".contains(mediaTypeKey)) {
+ mediaType = MediaType.voice;
+ } else if ("mp3/wma/wav/amr".equals(mediaTypeKey)) {
+ mediaType = MediaType.video;
+ } else {
+ throw new WeixinException("unknown mediaType:" + mediaTypeKey);
+ }
+ return uploadMedia(new FileInputStream(file), mediaType, isMaterial);
}
/**
@@ -98,10 +90,8 @@ public class MediaApi extends MpApi {
* 否则抛出异常.
*
*
- * @param fileName
- * 文件名
- * @param bytes
- * 媒体数据包
+ * @param is
+ * 媒体数据流
* @param mediaType
* 媒体文件类型:分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb)
* @param isMaterial
@@ -111,37 +101,45 @@ public class MediaApi extends MpApi {
* href="http://mp.weixin.qq.com/wiki/5/963fc70b80dc75483a271298a76a8d59.html">上传临时素材
* @see 上传永久素材
+ * @see com.foxinmy.weixin4j.type.MediaType
+ * @see com.foxinmy.weixin4j.mp.api.MediaApi
* @throws WeixinException
*/
- public String uploadMedia(String fileName, byte[] bytes, String mediaType,
+ public String uploadMedia(InputStream is, MediaType mediaType,
boolean isMaterial) throws WeixinException {
- if (",image,voice,video,thumb,".indexOf(String
- .format(",%s,", mediaType)) < 0) {
- throw new WeixinException(String.format(
- "unsupported media type:%s", mediaType));
- }
if (mediaType.equals(MediaType.video.name()) && isMaterial) {
throw new WeixinException(
"please invoke uploadMaterialVideo method");
}
Token token = tokenHolder.getToken();
WeixinResponse response = null;
- if (isMaterial) {
- String material_media_upload_uri = getRequestUri("material_media_upload_uri");
- try {
- response = weixinClient.post(String.format(
- material_media_upload_uri, token.getAccessToken()),
- new FormBodyPart("media", new ByteArrayBody(bytes,
- fileName)), new FormBodyPart("type",
- new StringBody(mediaType, Consts.UTF_8)));
- } catch (UnsupportedEncodingException e) {
- throw new WeixinException(e); // ignore
+ 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(),
+ ObjectId.get().toHexString())),
+ new FormBodyPart("type", new StringBody(mediaType
+ .name(), Consts.UTF_8)));
+ } else {
+ String file_upload_uri = getRequestUri("file_upload_uri");
+ response = weixinClient.post(String.format(file_upload_uri,
+ token.getAccessToken(), mediaType), new FormBodyPart(
+ "media", new InputStreamBody(is, mediaType
+ .getContentType().getMimeType(), ObjectId.get()
+ .toHexString())));
+ }
+ } catch (UnsupportedEncodingException e) {
+ ; // ignore
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ ;
}
- } else {
- String file_upload_uri = getRequestUri("file_upload_uri");
- response = weixinClient.post(String.format(file_upload_uri,
- token.getAccessToken(), mediaType), new FormBodyPart(
- "media", new ByteArrayBody(bytes, fileName)));
}
return response.getAsJson().getString("media_id");
}
@@ -154,27 +152,18 @@ public class MediaApi extends MpApi {
*
* @param mediaId
* 存储在微信服务器上的媒体标识
- * @param mediaType
- * 媒体文件类型:分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb)
- * @return 写入硬盘后的文件对象
+ * @return 写入硬盘后的文件对象,存储路径见weixin4j.properties配置
* @throws WeixinException
* @see 下载临时媒体文件
* @see 下载永久媒体素材
- * @see com.foxinmy.weixin4j.type.MediaType
* @see {@link com.foxinmy.weixin4j.mp.api.MediaApi#downloadMedia(String,boolean)}
*/
- public File downloadMedia(String mediaId, MediaType mediaType,
- boolean isMaterial) throws WeixinException {
- if (",image,voice,video,thumb,".indexOf(String.format(",%s,",
- mediaType.name())) < 0) {
- throw new WeixinException(String.format(
- "unsupported media type:%s", mediaType.name()));
- }
+ public File downloadMediaFile(String mediaId, boolean isMaterial)
+ throws WeixinException {
String media_path = ConfigUtil.getValue("media_path");
- File file = new File(media_path + File.separator + mediaId + "."
- + mediaType.getFormatName());
+ File file = new File(media_path + File.separator + mediaId);
if (file.exists()) {
return file;
}
@@ -195,7 +184,7 @@ public class MediaApi extends MpApi {
if (os != null) {
os.close();
}
- } catch (IOException ignore) {
+ } catch (IOException e) {
;
}
}
diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MassTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MassTest.java
index 80c84b8f..ca115f97 100644
--- a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MassTest.java
+++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MassTest.java
@@ -17,7 +17,6 @@ import com.foxinmy.weixin4j.tuple.Image;
import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.tuple.Text;
import com.foxinmy.weixin4j.tuple.Video;
-import com.foxinmy.weixin4j.type.MediaType;
/**
* 群发消息
@@ -42,7 +41,7 @@ public class MassTest extends TokenTest {
public void uploadArticle() throws IOException, WeixinException {
List articles = new ArrayList();
String thumbMediaId = mediaApi.uploadMedia(new File("/tmp/test.jpg"),
- MediaType.image, false);
+ false);
articles.add(new MpArticle(thumbMediaId, "title", "content"));
massApi.uploadArticle(articles);
}
@@ -71,7 +70,7 @@ public class MassTest extends TokenTest {
public void massArticleByGroup() throws IOException, WeixinException {
List articles = new ArrayList();
String thumbMediaId = mediaApi.uploadMedia(new File("/tmp/test.jpg"),
- MediaType.image, false);
+ false);
articles.add(new MpArticle(thumbMediaId, "title", "content"));
String massId = massApi.massArticleByGroupId(articles, 0);
Assert.assertTrue(massId != null);
@@ -81,7 +80,7 @@ public class MassTest extends TokenTest {
public void massArticleByOpenIds() throws IOException, WeixinException {
List articles = new ArrayList();
String thumbMediaId = mediaApi.uploadMedia(new File("/tmp/test.jpg"),
- MediaType.image, false);
+ false);
articles.add(new MpArticle(thumbMediaId, "title", "content"));
String massId = massApi.massArticleByOpenIds(articles,
"owGBft_vbBbOaQOmpEUE4xDLeRSU");
diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MediaTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MediaTest.java
index c6cfef76..9c0c09d1 100644
--- a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MediaTest.java
+++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MediaTest.java
@@ -39,7 +39,7 @@ public class MediaTest extends TokenTest {
@Test
public void upload1() throws IOException, WeixinException {
File file = new File("/Users/jy/Downloads/weixin4j.png");
- String mediaId = mediaApi.uploadMedia(file, MediaType.image, false);
+ String mediaId = mediaApi.uploadMedia(file, false);
// 1Vgd1R5DdznSc3rPxd-sNZ3pLt54cejhJ5ItuNcCgrqoQArNANWy5oxso_r9KNlE
Assert.assertNotNull(mediaId);
System.err.println(mediaId);
@@ -48,16 +48,16 @@ public class MediaTest extends TokenTest {
@Test
public void download1() throws WeixinException, IOException {
File file = mediaApi
- .downloadMedia(
+ .downloadMediaFile(
"1Vgd1R5DdznSc3rPxd-sNZ3pLt54cejhJ5ItuNcCgrqoQArNANWy5oxso_r9KNlE",
- MediaType.image, false);
+ false);
Assert.assertTrue(file.exists());
}
@Test
public void upload2() throws IOException, WeixinException {
File file = new File("/Users/jy/Downloads/test.jpg");
- String mediaId = mediaApi.uploadMedia(file, MediaType.image, true);
+ String mediaId = mediaApi.uploadMedia(file, true);
// 8790403529
Assert.assertNotNull(mediaId);
System.err.println(mediaId);
@@ -85,7 +85,7 @@ public class MediaTest extends TokenTest {
@Test
public void download2() throws WeixinException, IOException {
- File file = mediaApi.downloadMedia("8790403529", MediaType.image, true);
+ File file = mediaApi.downloadMediaFile("8790403529", true);
Assert.assertTrue(file.exists());
}
@@ -129,10 +129,11 @@ public class MediaTest extends TokenTest {
20);
System.err.println(mediaRecord);
}
-
+
@Test
public void listAllMaterialMedia() throws WeixinException {
- List mediaList = mediaApi.listAllMaterialMedia(MediaType.image);
+ List mediaList = mediaApi
+ .listAllMaterialMedia(MediaType.image);
System.err.println(mediaList);
}
}
diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/NotifyTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/NotifyTest.java
index 7b4d80db..babe6173 100644
--- a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/NotifyTest.java
+++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/NotifyTest.java
@@ -18,7 +18,6 @@ import com.foxinmy.weixin4j.tuple.News;
import com.foxinmy.weixin4j.tuple.Text;
import com.foxinmy.weixin4j.tuple.Video;
import com.foxinmy.weixin4j.tuple.Voice;
-import com.foxinmy.weixin4j.type.MediaType;
/**
* 客服消息测试
@@ -90,8 +89,7 @@ public class NotifyTest extends TokenTest {
@Test
public void send2() throws WeixinException, IOException {
- String mediaId = mediaApi.uploadMedia(new File("/tmp/test.jpg"),
- MediaType.image, false);
+ String mediaId = mediaApi.uploadMedia(new File("/tmp/test.jpg"), false);
NotifyMessage imageNotify = new NotifyMessage(
"owGBft_vbBbOaQOmpEUE4xDLeRSU", new Image(mediaId));
JsonResult result = notifyApi.sendNotify(imageNotify);
diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java
index 1a287f4f..b71042c2 100644
--- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java
+++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java
@@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.qy;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.util.List;
import com.alibaba.fastjson.JSONObject;
@@ -207,7 +208,7 @@ public class WeixinProxy {
* 媒体对象
* @return 上传到微信服务器返回的媒体标识
* @see com.foxinmy.weixin4j.qy.api.MediaApi
- * @see {@link com.foxinmy.weixin4j.qy.WeixinProxy.MediaApi#uploadMedia(File, MediaType)}
+ * @see {@link com.foxinmy.weixin4j.qy.WeixinProxy.MediaApi#uploadMedia(InputStream, MediaType)}
* @throws WeixinException
* @throws IOException
*/
@@ -215,25 +216,6 @@ public class WeixinProxy {
return mediaApi.uploadMedia(file);
}
- /**
- * 上传媒体文件
- *
- * @param file
- * 文件对象
- * @param mediaType
- * 媒体类型
- * @return 上传到微信服务器返回的媒体标识
- * @throws WeixinException
- * @throws IOException
- * @see com.foxinmy.weixin4j.qy.api.MediaApi
- * @see com.foxinmy.weixin4j.type.MediaType
- * @see {@link com.foxinmy.weixin4j.qy.WeixinProxy#uploadMedia(String, byte[],String)}
- */
- public String uploadMedia(File file, MediaType mediaType)
- throws WeixinException, IOException {
- return mediaApi.uploadMedia(file, mediaType);
- }
-
/**
* 上传媒体文件(完全公开。所有管理员均可调用,media_id可以共享)
*
@@ -241,19 +223,20 @@ public class WeixinProxy {
* 否则抛出异常.
*
*
- * @param bytes
- * 媒体数据包
+ * @param is
+ * 媒体数据流
* @param mediaType
* 媒体类型
- * @return 上传到微信服务器返回的媒体标识
* @see com.foxinmy.weixin4j.qy.api.MediaApi
+ * @see com.foxinmy.weixin4j.type.MediaType
+ * @return 上传到微信服务器返回的媒体标识
* @see 上传媒体文件说明
* @throws WeixinException
*/
- public String uploadMedia(String fileName, byte[] bytes, String mediaType)
+ public String uploadMedia(InputStream is, MediaType mediaType)
throws WeixinException {
- return mediaApi.uploadMedia(fileName, bytes, mediaType);
+ return mediaApi.uploadMedia(is, mediaType);
}
/**
@@ -279,9 +262,7 @@ public class WeixinProxy {
*
* @param mediaId
* 存储在微信服务器上的媒体标识
- * @param extension
- * 媒体后缀名
- * @return 写入硬盘后的文件对象
+ * @return 写入硬盘后的文件对象,存储路径见weixin4j.properties配置
* @throws WeixinException
* @throws IOException
* @see com.foxinmy.weixin4j.qy.api.MediaApi
@@ -290,9 +271,8 @@ public class WeixinProxy {
* @see com.foxinmy.weixin4j.type.MediaType
* @see {@link com.foxinmy.weixin4j.WeixinProxy.MediaApi#downloadMedia(String)}
*/
- public File downloadMedia(String mediaId, String extension)
- throws WeixinException {
- return mediaApi.downloadMedia(mediaId, extension);
+ public File downloadMediaFile(String mediaId) throws WeixinException {
+ return mediaApi.downloadMediaFile(mediaId);
}
/**
@@ -406,7 +386,8 @@ public class WeixinProxy {
* @return 处理结果
* @throws WeixinException
*/
- public JsonResult createUser(User user, File avatar) throws WeixinException {
+ public JsonResult createUser(User user, InputStream avatar)
+ throws WeixinException {
return userApi.createUser(user, avatar);
}
@@ -440,7 +421,8 @@ public class WeixinProxy {
* @return 处理结果
* @throws WeixinException
*/
- public JsonResult updateUser(User user, File avatar) throws WeixinException {
+ public JsonResult updateUser(User user, InputStream avatar)
+ throws WeixinException {
return userApi.updateUser(user, avatar);
}
diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/MediaApi.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/MediaApi.java
index 63802602..b3074429 100644
--- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/MediaApi.java
+++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/MediaApi.java
@@ -1,9 +1,11 @@
package com.foxinmy.weixin4j.qy.api;
+import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.LinkedHashMap;
@@ -15,8 +17,8 @@ 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.apache.ByteArrayBody;
import com.foxinmy.weixin4j.http.apache.FormBodyPart;
+import com.foxinmy.weixin4j.http.apache.InputStreamBody;
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.model.Token;
@@ -28,6 +30,7 @@ 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;
/**
@@ -55,7 +58,7 @@ public class MediaApi extends QyApi {
* @param file
* 媒体对象
* @return 上传到微信服务器返回的媒体标识
- * @see {@link com.foxinmy.weixin4j.qy.api.MediaApi#uploadMedia(File, MediaType)}
+ * @see {@link com.foxinmy.weixin4j.qy.api.MediaApi#uploadMedia(InputStream, MediaType)}
* @throws WeixinException
* @throws IOException
*/
@@ -64,27 +67,17 @@ public class MediaApi extends QyApi {
if (StringUtil.isBlank(mediaTypeKey)) {
mediaTypeKey = FileUtil.getFileType(file);
}
- MediaType mediaType = MediaType.getMediaType(mediaTypeKey);
- return uploadMedia(file, mediaType);
- }
-
- /**
- * 上传媒体文件
- *
- * @param file
- * 文件对象
- * @param mediaType
- * 媒体类型
- * @return 上传到微信服务器返回的媒体标识
- * @throws WeixinException
- * @throws IOException
- * @see com.foxinmy.weixin4j.type.MediaType
- * @see {@link com.foxinmy.weixin4j.qy.api.MediaApi#uploadMedia(String, byte[],String)}
- */
- public String uploadMedia(File file, MediaType mediaType)
- throws WeixinException, IOException {
- byte[] datas = IOUtil.toByteArray(new FileInputStream(file));
- return uploadMedia(file.getName(), datas, mediaType.name());
+ MediaType mediaType = null;
+ if (mediaTypeKey.equals("jpg")) {
+ mediaType = MediaType.image;
+ } else if ("amr/mp3".contains(mediaTypeKey)) {
+ mediaType = MediaType.voice;
+ } else if (mediaTypeKey.equals("mp4")) {
+ mediaType = MediaType.video;
+ } else {
+ mediaType = MediaType.file;
+ }
+ return uploadMedia(new FileInputStream(file), mediaType);
}
/**
@@ -94,8 +87,8 @@ public class MediaApi extends QyApi {
* 否则抛出异常.
*
*
- * @param bytes
- * 媒体数据包
+ * @param is
+ * 媒体数据流
* @param mediaType
* 媒体类型
* @return 上传到微信服务器返回的媒体标识
@@ -103,14 +96,25 @@ public class MediaApi extends QyApi {
* 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">上传媒体文件说明
* @throws WeixinException
*/
- public String uploadMedia(String fileName, byte[] bytes, String mediaType)
+ public String uploadMedia(InputStream is, MediaType mediaType)
throws WeixinException {
- Token token = tokenHolder.getToken();
String file_upload_uri = getRequestUri("file_upload_uri");
- WeixinResponse response = weixinClient.post(String.format(file_upload_uri,
- token.getAccessToken(), mediaType), new FormBodyPart("media",
- new ByteArrayBody(bytes, fileName)));
-
+ Token token = tokenHolder.getToken();
+ if (mediaType == null || mediaType == MediaType.news) {
+ mediaType = MediaType.file;
+ } else if (mediaType == MediaType.thumb) {
+ mediaType = MediaType.image;
+ }
+ 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) {
+ ;
+ }
return response.getAsJson().getString("media_id");
}
@@ -122,9 +126,7 @@ public class MediaApi extends QyApi {
*
* @param mediaId
* 存储在微信服务器上的媒体标识
- * @param extension
- * 媒体后缀名
- * @return 写入硬盘后的文件对象
+ * @return 写入硬盘后的文件对象,存储路径见weixin4j.properties配置
* @throws WeixinException
* @throws IOException
* @see