@@ -5,11 +5,12 @@ import java.io.IOException; | |||||
import java.io.InputStream; | import java.io.InputStream; | ||||
import chanjarster.weixin.bean.WxCustomMessage; | import chanjarster.weixin.bean.WxCustomMessage; | ||||
import chanjarster.weixin.bean.WxMassMessage; | |||||
import chanjarster.weixin.bean.WxMassGroupMessage; | |||||
import chanjarster.weixin.bean.WxMassNews; | import chanjarster.weixin.bean.WxMassNews; | ||||
import chanjarster.weixin.bean.WxMassOpenIdsMessage; | |||||
import chanjarster.weixin.bean.WxMassVideo; | import chanjarster.weixin.bean.WxMassVideo; | ||||
import chanjarster.weixin.bean.WxMenu; | import chanjarster.weixin.bean.WxMenu; | ||||
import chanjarster.weixin.bean.result.WxMassMaterialUploadResult; | |||||
import chanjarster.weixin.bean.result.WxMassUploadResult; | |||||
import chanjarster.weixin.bean.result.WxMassSendResult; | import chanjarster.weixin.bean.result.WxMassSendResult; | ||||
import chanjarster.weixin.bean.result.WxMediaUploadResult; | import chanjarster.weixin.bean.result.WxMediaUploadResult; | ||||
import chanjarster.weixin.exception.WxErrorException; | import chanjarster.weixin.exception.WxErrorException; | ||||
@@ -104,7 +105,7 @@ public interface WxService { | |||||
* @param news | * @param news | ||||
* @throws WxErrorException | * @throws WxErrorException | ||||
*/ | */ | ||||
public WxMassMaterialUploadResult uploadMassNews(WxMassNews news) throws WxErrorException; | |||||
public WxMassUploadResult uploadMassNews(WxMassNews news) throws WxErrorException; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
@@ -114,11 +115,11 @@ public interface WxService { | |||||
* @return | * @return | ||||
* @throws WxErrorException | * @throws WxErrorException | ||||
*/ | */ | ||||
public WxMassMaterialUploadResult uploadMassVideo(WxMassVideo video) throws WxErrorException; | |||||
public WxMassUploadResult uploadMassVideo(WxMassVideo video) throws WxErrorException; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 群发消息 | |||||
* 分组群发消息 | |||||
* 如果发送图文消息,必须先使用 {@link #uploadMassNews(WxMassNews)} 获得media_id,然后再发送 | * 如果发送图文消息,必须先使用 {@link #uploadMassNews(WxMassNews)} 获得media_id,然后再发送 | ||||
* 如果发送视频消息,必须先使用 {@link #uploadMassVideo(WxMassVideo)} 获得media_id,然后再发送 | * 如果发送视频消息,必须先使用 {@link #uploadMassVideo(WxMassVideo)} 获得media_id,然后再发送 | ||||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口 | * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口 | ||||
@@ -127,8 +128,21 @@ public interface WxService { | |||||
* @throws WxErrorException | * @throws WxErrorException | ||||
* @return | * @return | ||||
*/ | */ | ||||
public WxMassSendResult sendMassMessage(WxMassMessage message) throws WxErrorException; | |||||
public WxMassSendResult sendMassMessageByGroup(WxMassGroupMessage message) throws WxErrorException; | |||||
/** | |||||
* <pre> | |||||
* 按openId列表群发消息 | |||||
* 如果发送图文消息,必须先使用 {@link #uploadMassNews(WxMassNews)} 获得media_id,然后再发送 | |||||
* 如果发送视频消息,必须先使用 {@link #uploadMassVideo(WxMassVideo)} 获得media_id,然后再发送 | |||||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口 | |||||
* </pre> | |||||
* @param message | |||||
* @return | |||||
* @throws WxErrorException | |||||
*/ | |||||
public WxMassSendResult sendMassMessageByOpenIds(WxMassOpenIdsMessage message) throws WxErrorException; | |||||
/** | /** | ||||
* <pre> | * <pre> | ||||
* 自定义菜单创建接口 | * 自定义菜单创建接口 | ||||
@@ -18,13 +18,14 @@ import org.apache.http.impl.client.HttpClients; | |||||
import chanjarster.weixin.bean.WxAccessToken; | import chanjarster.weixin.bean.WxAccessToken; | ||||
import chanjarster.weixin.bean.WxCustomMessage; | import chanjarster.weixin.bean.WxCustomMessage; | ||||
import chanjarster.weixin.bean.WxMassMessage; | |||||
import chanjarster.weixin.bean.WxMassGroupMessage; | |||||
import chanjarster.weixin.bean.WxMassNews; | import chanjarster.weixin.bean.WxMassNews; | ||||
import chanjarster.weixin.bean.WxMassOpenIdsMessage; | |||||
import chanjarster.weixin.bean.WxMassVideo; | import chanjarster.weixin.bean.WxMassVideo; | ||||
import chanjarster.weixin.bean.WxMenu; | import chanjarster.weixin.bean.WxMenu; | ||||
import chanjarster.weixin.bean.result.WxError; | import chanjarster.weixin.bean.result.WxError; | ||||
import chanjarster.weixin.bean.result.WxMassMaterialUploadResult; | |||||
import chanjarster.weixin.bean.result.WxMassSendResult; | import chanjarster.weixin.bean.result.WxMassSendResult; | ||||
import chanjarster.weixin.bean.result.WxMassUploadResult; | |||||
import chanjarster.weixin.bean.result.WxMediaUploadResult; | import chanjarster.weixin.bean.result.WxMediaUploadResult; | ||||
import chanjarster.weixin.exception.WxErrorException; | import chanjarster.weixin.exception.WxErrorException; | ||||
import chanjarster.weixin.util.fs.FileUtil; | import chanjarster.weixin.util.fs.FileUtil; | ||||
@@ -47,6 +48,8 @@ public class WxServiceImpl implements WxService { | |||||
protected WxConfigStorage wxConfigStorage; | protected WxConfigStorage wxConfigStorage; | ||||
protected final ThreadLocal<Integer> retryTimes = new ThreadLocal<Integer>(); | |||||
public boolean checkSignature(String timestamp, String nonce, String signature) { | public boolean checkSignature(String timestamp, String nonce, String signature) { | ||||
try { | try { | ||||
String token = wxConfigStorage.getToken(); | String token = wxConfigStorage.getToken(); | ||||
@@ -156,24 +159,30 @@ public class WxServiceImpl implements WxService { | |||||
return execute(new MediaDownloadRequestExecutor(), url, "media_id=" + media_id); | return execute(new MediaDownloadRequestExecutor(), url, "media_id=" + media_id); | ||||
} | } | ||||
public WxMassMaterialUploadResult uploadMassNews(WxMassNews news) throws WxErrorException { | |||||
public WxMassUploadResult uploadMassNews(WxMassNews news) throws WxErrorException { | |||||
String url = "https://api.weixin.qq.com/cgi-bin/media/uploadnews"; | String url = "https://api.weixin.qq.com/cgi-bin/media/uploadnews"; | ||||
String responseContent = execute(new SimplePostRequestExecutor(), url, news.toJson()); | String responseContent = execute(new SimplePostRequestExecutor(), url, news.toJson()); | ||||
return WxMassMaterialUploadResult.fromJson(responseContent); | |||||
return WxMassUploadResult.fromJson(responseContent); | |||||
} | } | ||||
public WxMassMaterialUploadResult uploadMassVideo(WxMassVideo video) throws WxErrorException { | |||||
String url = " https://file.api.weixin.qq.com/cgi-bin/media/uploadvideo"; | |||||
public WxMassUploadResult uploadMassVideo(WxMassVideo video) throws WxErrorException { | |||||
String url = "http://file.api.weixin.qq.com/cgi-bin/media/uploadvideo"; | |||||
String responseContent = execute(new SimplePostRequestExecutor(), url, video.toJson()); | String responseContent = execute(new SimplePostRequestExecutor(), url, video.toJson()); | ||||
return WxMassMaterialUploadResult.fromJson(responseContent); | |||||
return WxMassUploadResult.fromJson(responseContent); | |||||
} | } | ||||
public WxMassSendResult sendMassMessage(WxMassMessage message) throws WxErrorException { | |||||
public WxMassSendResult sendMassMessageByGroup(WxMassGroupMessage message) throws WxErrorException { | |||||
String url = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall"; | String url = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall"; | ||||
String responseContent = execute(new SimplePostRequestExecutor(), url, message.toJson()); | String responseContent = execute(new SimplePostRequestExecutor(), url, message.toJson()); | ||||
return WxMassSendResult.fromJson(responseContent); | return WxMassSendResult.fromJson(responseContent); | ||||
} | } | ||||
public WxMassSendResult sendMassMessageByOpenIds(WxMassOpenIdsMessage message) throws WxErrorException { | |||||
String url = "https://api.weixin.qq.com/cgi-bin/message/mass/send"; | |||||
String responseContent = execute(new SimplePostRequestExecutor(), url, message.toJson()); | |||||
return WxMassSendResult.fromJson(responseContent); | |||||
} | |||||
/** | /** | ||||
* 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 | * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 | ||||
* @param executor | * @param executor | ||||
@@ -205,12 +214,21 @@ public class WxServiceImpl implements WxService { | |||||
return execute(executor, uri, data); | return execute(executor, uri, data); | ||||
} | } | ||||
/** | /** | ||||
* -1 系统繁忙, 500ms后重试 | |||||
* -1 系统繁忙, 1000ms后重试 | |||||
*/ | */ | ||||
if (error.getErrcode() == -1) { | if (error.getErrcode() == -1) { | ||||
if(retryTimes.get() == null) { | |||||
retryTimes.set(0); | |||||
} | |||||
if (retryTimes.get() > 5) { | |||||
retryTimes.set(0); | |||||
throw new RuntimeException("微信服务端异常,超出重试次数"); | |||||
} | |||||
int sleepMillis = 1000 * (1 >> (retryTimes.get() - 1)); | |||||
try { | try { | ||||
System.out.println("微信系统繁忙,500ms后重试"); | |||||
Thread.sleep(500); | |||||
System.out.println("微信系统繁忙," + sleepMillis + "ms后重试"); | |||||
Thread.sleep(sleepMillis); | |||||
retryTimes.set(retryTimes.get() + 1); | |||||
return execute(executor, uri, data); | return execute(executor, uri, data); | ||||
} catch (InterruptedException e1) { | } catch (InterruptedException e1) { | ||||
throw new RuntimeException(e1); | throw new RuntimeException(e1); | ||||
@@ -0,0 +1,69 @@ | |||||
package chanjarster.weixin.bean; | |||||
import chanjarster.weixin.api.WxConsts; | |||||
import chanjarster.weixin.util.json.WxGsonBuilder; | |||||
/** | |||||
* 分组群发的消息 | |||||
* | |||||
* @author chanjarster | |||||
*/ | |||||
public class WxMassGroupMessage { | |||||
protected String group_id; | |||||
protected String msgtype; | |||||
protected String content; | |||||
protected String media_id; | |||||
public WxMassGroupMessage() { | |||||
super(); | |||||
} | |||||
public String getMsgtype() { | |||||
return msgtype; | |||||
} | |||||
/** | |||||
* <pre> | |||||
* 请使用 | |||||
* {@link WxConsts#MASS_MSG_IMAGE} | |||||
* {@link WxConsts#MASS_MSG_NEWS} | |||||
* {@link WxConsts#MASS_MSG_TEXT} | |||||
* {@link WxConsts#MASS_MSG_VIDEO} | |||||
* {@link WxConsts#MASS_MSG_VOICE} | |||||
* </pre> | |||||
* @param msgtype | |||||
*/ | |||||
public void setMsgtype(String msgtype) { | |||||
this.msgtype = msgtype; | |||||
} | |||||
public String getContent() { | |||||
return content; | |||||
} | |||||
public void setContent(String content) { | |||||
this.content = content; | |||||
} | |||||
public String getMedia_id() { | |||||
return media_id; | |||||
} | |||||
public void setMedia_id(String media_id) { | |||||
this.media_id = media_id; | |||||
} | |||||
public String toJson() { | |||||
return WxGsonBuilder.INSTANCE.create().toJson(this); | |||||
} | |||||
public String getGroup_id() { | |||||
return group_id; | |||||
} | |||||
public void setGroup_id(String group_id) { | |||||
this.group_id = group_id; | |||||
} | |||||
} |
@@ -17,14 +17,29 @@ public class WxMassNews { | |||||
public List<WxMassNewsArticle> getArticles() { | public List<WxMassNewsArticle> getArticles() { | ||||
return articles; | return articles; | ||||
} | } | ||||
public void setArticles(List<WxMassNewsArticle> articles) { | |||||
this.articles = articles; | |||||
public void addArticle(WxMassNewsArticle article) { | |||||
this.articles.add(article); | |||||
} | } | ||||
public String toJson() { | public String toJson() { | ||||
return WxGsonBuilder.INSTANCE.create().toJson(this); | return WxGsonBuilder.INSTANCE.create().toJson(this); | ||||
} | } | ||||
/** | |||||
* <pre> | |||||
* 群发图文消息article | |||||
* 1. thumb_media_id (必填) 图文消息缩略图的media_id,可以在基础支持-上传多媒体文件接口中获得 | |||||
* 2. author 图文消息的作者 | |||||
* 3. title (必填) 图文消息的标题 | |||||
* 4. content_source_url 在图文消息页面点击“阅读原文”后的页面链接 | |||||
* 5. content (必填) 图文消息页面的内容,支持HTML标签 | |||||
* 6. digest 图文消息的描述 | |||||
* 7, show_cover_pic 是否显示封面,true为显示,false为不显示 | |||||
* </pre> | |||||
* @author chanjarster | |||||
* | |||||
*/ | |||||
public static class WxMassNewsArticle { | public static class WxMassNewsArticle { | ||||
/** | /** | ||||
* (必填) 图文消息缩略图的media_id,可以在基础支持-上传多媒体文件接口中获得 | * (必填) 图文消息缩略图的media_id,可以在基础支持-上传多媒体文件接口中获得 | ||||
@@ -39,7 +54,7 @@ public class WxMassNews { | |||||
*/ | */ | ||||
protected String title; | protected String title; | ||||
/** | /** | ||||
* 在图文消息页面点击“阅读原文”后的页面 | |||||
* 在图文消息页面点击“阅读原文”后的页面链接 | |||||
*/ | */ | ||||
protected String content_source_url; | protected String content_source_url; | ||||
/** | /** | ||||
@@ -51,7 +66,7 @@ public class WxMassNews { | |||||
*/ | */ | ||||
protected String digest; | protected String digest; | ||||
/** | /** | ||||
* 是否显示封面,1为显示,0为不显示 | |||||
* 是否显示封面,true为显示,false为不显示 | |||||
*/ | */ | ||||
protected boolean show_cover_pic; | protected boolean show_cover_pic; | ||||
@@ -4,40 +4,24 @@ import java.util.ArrayList; | |||||
import java.util.List; | import java.util.List; | ||||
import chanjarster.weixin.api.WxConsts; | import chanjarster.weixin.api.WxConsts; | ||||
import chanjarster.weixin.bean.result.WxMassMaterialUploadResult; | |||||
import chanjarster.weixin.util.json.WxGsonBuilder; | import chanjarster.weixin.util.json.WxGsonBuilder; | ||||
/** | /** | ||||
* 群发消息 | |||||
* OpenId列表群发的消息 | |||||
* | * | ||||
* @author chanjarster | * @author chanjarster | ||||
*/ | */ | ||||
public class WxMassMessage { | |||||
public class WxMassOpenIdsMessage { | |||||
protected List<String> touser = new ArrayList<String>(); | protected List<String> touser = new ArrayList<String>(); | ||||
protected String group_id; | |||||
protected String msgtype; | protected String msgtype; | ||||
protected String content; | protected String content; | ||||
protected String media_id; | protected String media_id; | ||||
public WxMassMessage() { | |||||
public WxMassOpenIdsMessage() { | |||||
super(); | super(); | ||||
} | } | ||||
/** | |||||
* 利用上传群发所用的素材的结果,构造群发消息 | |||||
* @param r | |||||
* @return | |||||
*/ | |||||
public WxMassMessage(WxMassMaterialUploadResult r) { | |||||
setMedia_id(r.getMedia_id()); | |||||
if("video".equals(r.getType())) { | |||||
setMsgtype(WxConsts.MASS_MSG_VIDEO); | |||||
} else { | |||||
setMsgtype(r.getType()); | |||||
} | |||||
} | |||||
public String getMsgtype() { | public String getMsgtype() { | ||||
return msgtype; | return msgtype; | ||||
} | } | ||||
@@ -77,20 +61,19 @@ public class WxMassMessage { | |||||
return WxGsonBuilder.INSTANCE.create().toJson(this); | return WxGsonBuilder.INSTANCE.create().toJson(this); | ||||
} | } | ||||
/** | |||||
* OpenId列表,最多支持10,000个 | |||||
* @return | |||||
*/ | |||||
public List<String> getTouser() { | public List<String> getTouser() { | ||||
return touser; | return touser; | ||||
} | } | ||||
public void setTouser(List<String> touser) { | |||||
this.touser = touser; | |||||
} | |||||
public String getGroup_id() { | |||||
return group_id; | |||||
} | |||||
public void setGroup_id(String group_id) { | |||||
this.group_id = group_id; | |||||
/** | |||||
* 添加OpenId,最多支持10,000个 | |||||
* @param openId | |||||
*/ | |||||
public void addUser(String openId) { | |||||
this.touser.add(openId); | |||||
} | } | ||||
} | } |
@@ -4,30 +4,40 @@ import chanjarster.weixin.util.json.WxGsonBuilder; | |||||
/** | /** | ||||
* 群发时用到的视频素材 | * 群发时用到的视频素材 | ||||
* | |||||
* @author chanjarster | * @author chanjarster | ||||
* | |||||
*/ | */ | ||||
public class WxMassVideo { | public class WxMassVideo { | ||||
protected String media_id; | protected String media_id; | ||||
protected String title; | protected String title; | ||||
protected String description; | protected String description; | ||||
public String getTitle() { | public String getTitle() { | ||||
return title; | return title; | ||||
} | } | ||||
public void setTitle(String title) { | public void setTitle(String title) { | ||||
this.title = title; | this.title = title; | ||||
} | } | ||||
public String getDescription() { | public String getDescription() { | ||||
return description; | return description; | ||||
} | } | ||||
public void setDescription(String description) { | public void setDescription(String description) { | ||||
this.description = description; | this.description = description; | ||||
} | } | ||||
public String getMedia_id() { | |||||
return media_id; | |||||
} | |||||
public void setMedia_id(String media_id) { | |||||
this.media_id = media_id; | |||||
} | |||||
public String toJson() { | public String toJson() { | ||||
return WxGsonBuilder.INSTANCE.create().toJson(this); | return WxGsonBuilder.INSTANCE.create().toJson(this); | ||||
} | } | ||||
} | } |
@@ -46,4 +46,10 @@ public class WxMassSendResult { | |||||
public static WxMassSendResult fromJson(String json) { | public static WxMassSendResult fromJson(String json) { | ||||
return WxGsonBuilder.create().fromJson(json, WxMassSendResult.class); | return WxGsonBuilder.create().fromJson(json, WxMassSendResult.class); | ||||
} | } | ||||
@Override | |||||
public String toString() { | |||||
return "WxMassSendResult [errcode=" + errcode + ", errmsg=" + errmsg + ", msg_id=" + msg_id + "]"; | |||||
} | |||||
} | } |
@@ -3,11 +3,14 @@ package chanjarster.weixin.bean.result; | |||||
import chanjarster.weixin.util.json.WxGsonBuilder; | import chanjarster.weixin.util.json.WxGsonBuilder; | ||||
/** | /** | ||||
* 上传群发所用的素材的结果 | |||||
* <pre> | |||||
* 上传群发用的素材的结果 | |||||
* 视频和图文消息需要在群发前上传素材 | |||||
* </pre> | |||||
* @author chanjarster | * @author chanjarster | ||||
* | * | ||||
*/ | */ | ||||
public class WxMassMaterialUploadResult { | |||||
public class WxMassUploadResult { | |||||
protected String type; | protected String type; | ||||
protected String media_id; | protected String media_id; | ||||
@@ -37,8 +40,8 @@ public class WxMassMaterialUploadResult { | |||||
this.created_at = created_at; | this.created_at = created_at; | ||||
} | } | ||||
public static WxMassMaterialUploadResult fromJson(String json) { | |||||
return WxGsonBuilder.create().fromJson(json, WxMassMaterialUploadResult.class); | |||||
public static WxMassUploadResult fromJson(String json) { | |||||
return WxGsonBuilder.create().fromJson(json, WxMassUploadResult.class); | |||||
} | } | ||||
@Override | @Override |
@@ -1,8 +1,9 @@ | |||||
package chanjarster.weixin.util.json; | package chanjarster.weixin.util.json; | ||||
import chanjarster.weixin.bean.WxCustomMessage; | import chanjarster.weixin.bean.WxCustomMessage; | ||||
import chanjarster.weixin.bean.WxMassMessage; | |||||
import chanjarster.weixin.bean.WxMassGroupMessage; | |||||
import chanjarster.weixin.bean.WxMassNews; | import chanjarster.weixin.bean.WxMassNews; | ||||
import chanjarster.weixin.bean.WxMassOpenIdsMessage; | |||||
import chanjarster.weixin.bean.WxMenu; | import chanjarster.weixin.bean.WxMenu; | ||||
import com.google.gson.Gson; | import com.google.gson.Gson; | ||||
@@ -17,7 +18,8 @@ public class WxGsonBuilder { | |||||
INSTANCE.registerTypeAdapter(WxCustomMessage.class, new WxCustomMessageGsonAdapter()); | INSTANCE.registerTypeAdapter(WxCustomMessage.class, new WxCustomMessageGsonAdapter()); | ||||
INSTANCE.registerTypeAdapter(WxMenu.class, new WxMenuGsonAdapter()); | INSTANCE.registerTypeAdapter(WxMenu.class, new WxMenuGsonAdapter()); | ||||
INSTANCE.registerTypeAdapter(WxMassNews.class, new WxMassNewsGsonAdapter()); | INSTANCE.registerTypeAdapter(WxMassNews.class, new WxMassNewsGsonAdapter()); | ||||
INSTANCE.registerTypeAdapter(WxMassMessage.class, new WxMassMessageGsonAdapter()); | |||||
INSTANCE.registerTypeAdapter(WxMassGroupMessage.class, new WxMassMessageGsonAdapter()); | |||||
INSTANCE.registerTypeAdapter(WxMassOpenIdsMessage.class, new WxMassOpenIdsMessageGsonAdapter()); | |||||
} | } | ||||
public static Gson create() { | public static Gson create() { | ||||
@@ -11,12 +11,10 @@ package chanjarster.weixin.util.json; | |||||
import java.lang.reflect.Type; | import java.lang.reflect.Type; | ||||
import chanjarster.weixin.api.WxConsts; | import chanjarster.weixin.api.WxConsts; | ||||
import chanjarster.weixin.bean.WxMassMessage; | |||||
import chanjarster.weixin.bean.WxMassGroupMessage; | |||||
import com.google.gson.JsonArray; | |||||
import com.google.gson.JsonElement; | import com.google.gson.JsonElement; | ||||
import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||
import com.google.gson.JsonPrimitive; | |||||
import com.google.gson.JsonSerializationContext; | import com.google.gson.JsonSerializationContext; | ||||
import com.google.gson.JsonSerializer; | import com.google.gson.JsonSerializer; | ||||
@@ -25,47 +23,39 @@ import com.google.gson.JsonSerializer; | |||||
* @author qianjia | * @author qianjia | ||||
* | * | ||||
*/ | */ | ||||
public class WxMassMessageGsonAdapter implements JsonSerializer<WxMassMessage> { | |||||
public class WxMassMessageGsonAdapter implements JsonSerializer<WxMassGroupMessage> { | |||||
public JsonElement serialize(WxMassMessage message, Type typeOfSrc, JsonSerializationContext context) { | |||||
public JsonElement serialize(WxMassGroupMessage message, Type typeOfSrc, JsonSerializationContext context) { | |||||
JsonObject messageJson = new JsonObject(); | JsonObject messageJson = new JsonObject(); | ||||
if (message.getTouser().size() > 0) { | |||||
JsonArray sub = new JsonArray(); | |||||
for(String openId : message.getTouser()) { | |||||
sub.add(new JsonPrimitive(openId)); | |||||
} | |||||
messageJson.add("touser", sub); | |||||
} else { | |||||
JsonObject sub = new JsonObject(); | |||||
sub.addProperty("group_id", message.getGroup_id()); | |||||
messageJson.add("filter", sub); | |||||
} | |||||
JsonObject filter = new JsonObject(); | |||||
filter.addProperty("group_id", message.getGroup_id()); | |||||
messageJson.add("filter", filter); | |||||
if (WxConsts.MASS_MSG_NEWS.equals(message.getMsgtype())) { | if (WxConsts.MASS_MSG_NEWS.equals(message.getMsgtype())) { | ||||
JsonObject sub = new JsonObject(); | JsonObject sub = new JsonObject(); | ||||
sub.addProperty("media_id", message.getMedia_id()); | sub.addProperty("media_id", message.getMedia_id()); | ||||
messageJson.add("mpnews", sub); | |||||
messageJson.add(WxConsts.MASS_MSG_NEWS, sub); | |||||
} | } | ||||
if (WxConsts.MASS_MSG_TEXT.equals(message.getMsgtype())) { | if (WxConsts.MASS_MSG_TEXT.equals(message.getMsgtype())) { | ||||
JsonObject sub = new JsonObject(); | JsonObject sub = new JsonObject(); | ||||
sub.addProperty("content", message.getContent()); | sub.addProperty("content", message.getContent()); | ||||
messageJson.add("text", sub); | |||||
messageJson.add(WxConsts.MASS_MSG_TEXT, sub); | |||||
} | } | ||||
if (WxConsts.MASS_MSG_VOICE.equals(message.getMsgtype())) { | if (WxConsts.MASS_MSG_VOICE.equals(message.getMsgtype())) { | ||||
JsonObject sub = new JsonObject(); | JsonObject sub = new JsonObject(); | ||||
sub.addProperty("media_id", message.getMedia_id()); | sub.addProperty("media_id", message.getMedia_id()); | ||||
messageJson.add("voice", sub); | |||||
messageJson.add(WxConsts.MASS_MSG_VOICE, sub); | |||||
} | } | ||||
if (WxConsts.MASS_MSG_IMAGE.equals(message.getMsgtype())) { | if (WxConsts.MASS_MSG_IMAGE.equals(message.getMsgtype())) { | ||||
JsonObject sub = new JsonObject(); | JsonObject sub = new JsonObject(); | ||||
sub.addProperty("media_id", message.getMedia_id()); | sub.addProperty("media_id", message.getMedia_id()); | ||||
messageJson.add("image", sub); | |||||
messageJson.add(WxConsts.MASS_MSG_IMAGE, sub); | |||||
} | } | ||||
if (WxConsts.MASS_MSG_VIDEO.equals(message.getMsgtype())) { | if (WxConsts.MASS_MSG_VIDEO.equals(message.getMsgtype())) { | ||||
JsonObject sub = new JsonObject(); | JsonObject sub = new JsonObject(); | ||||
sub.addProperty("media_id", message.getMedia_id()); | sub.addProperty("media_id", message.getMedia_id()); | ||||
messageJson.add("mpvideo", sub); | |||||
messageJson.add(WxConsts.MASS_MSG_VIDEO, sub); | |||||
} | } | ||||
messageJson.addProperty("msgtype", message.getMsgtype()); | messageJson.addProperty("msgtype", message.getMsgtype()); | ||||
return messageJson; | return messageJson; | ||||
@@ -0,0 +1,68 @@ | |||||
/* | |||||
* KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. | |||||
* | |||||
* This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended | |||||
* only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction | |||||
* arose from modification of the original source, or other redistribution of this source | |||||
* is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. | |||||
*/ | |||||
package chanjarster.weixin.util.json; | |||||
import java.lang.reflect.Type; | |||||
import chanjarster.weixin.api.WxConsts; | |||||
import chanjarster.weixin.bean.WxMassOpenIdsMessage; | |||||
import com.google.gson.JsonArray; | |||||
import com.google.gson.JsonElement; | |||||
import com.google.gson.JsonObject; | |||||
import com.google.gson.JsonPrimitive; | |||||
import com.google.gson.JsonSerializationContext; | |||||
import com.google.gson.JsonSerializer; | |||||
/** | |||||
* | |||||
* @author qianjia | |||||
* | |||||
*/ | |||||
public class WxMassOpenIdsMessageGsonAdapter implements JsonSerializer<WxMassOpenIdsMessage> { | |||||
public JsonElement serialize(WxMassOpenIdsMessage message, Type typeOfSrc, JsonSerializationContext context) { | |||||
JsonObject messageJson = new JsonObject(); | |||||
JsonArray touser = new JsonArray(); | |||||
for (String openId : message.getTouser()) { | |||||
touser.add(new JsonPrimitive(openId)); | |||||
} | |||||
messageJson.add("touser", touser); | |||||
if (WxConsts.MASS_MSG_NEWS.equals(message.getMsgtype())) { | |||||
JsonObject sub = new JsonObject(); | |||||
sub.addProperty("media_id", message.getMedia_id()); | |||||
messageJson.add(WxConsts.MASS_MSG_NEWS, sub); | |||||
} | |||||
if (WxConsts.MASS_MSG_TEXT.equals(message.getMsgtype())) { | |||||
JsonObject sub = new JsonObject(); | |||||
sub.addProperty("content", message.getContent()); | |||||
messageJson.add(WxConsts.MASS_MSG_TEXT, sub); | |||||
} | |||||
if (WxConsts.MASS_MSG_VOICE.equals(message.getMsgtype())) { | |||||
JsonObject sub = new JsonObject(); | |||||
sub.addProperty("media_id", message.getMedia_id()); | |||||
messageJson.add(WxConsts.MASS_MSG_VOICE, sub); | |||||
} | |||||
if (WxConsts.MASS_MSG_IMAGE.equals(message.getMsgtype())) { | |||||
JsonObject sub = new JsonObject(); | |||||
sub.addProperty("media_id", message.getMedia_id()); | |||||
messageJson.add(WxConsts.MASS_MSG_IMAGE, sub); | |||||
} | |||||
if (WxConsts.MASS_MSG_VIDEO.equals(message.getMsgtype())) { | |||||
JsonObject sub = new JsonObject(); | |||||
sub.addProperty("media_id", message.getMedia_id()); | |||||
messageJson.add(WxConsts.MASS_MSG_VIDEO, sub); | |||||
} | |||||
messageJson.addProperty("msgtype", message.getMsgtype()); | |||||
return messageJson; | |||||
} | |||||
} |
@@ -3,8 +3,10 @@ package chanjarster.weixin.api; | |||||
import java.io.InputStream; | import java.io.InputStream; | ||||
import javax.xml.bind.JAXBException; | import javax.xml.bind.JAXBException; | ||||
import javax.xml.bind.annotation.XmlAccessType; | |||||
import javax.xml.bind.annotation.XmlAccessorType; | |||||
import javax.xml.bind.annotation.XmlRootElement; | |||||
import chanjarster.weixin.api.WxBaseAPITest.WxXmlConfigStorage; | |||||
import chanjarster.weixin.util.xml.XmlTransformer; | import chanjarster.weixin.util.xml.XmlTransformer; | ||||
import com.google.inject.Binder; | import com.google.inject.Binder; | ||||
@@ -26,4 +28,24 @@ public class ApiTestModule implements Module { | |||||
} | } | ||||
} | } | ||||
@XmlRootElement(name = "xml") | |||||
@XmlAccessorType(XmlAccessType.FIELD) | |||||
public static class WxXmlConfigStorage extends WxInMemoryConfigStorage { | |||||
protected String openId; | |||||
public String getOpenId() { | |||||
return openId; | |||||
} | |||||
public void setOpenId(String openId) { | |||||
this.openId = openId; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "SimpleWxConfigProvider [appId=" + appId + ", secret=" + secret + ", accessToken=" + accessToken | |||||
+ ", expiresIn=" + expiresIn + ", token=" + token + ", openId=" + openId + "]"; | |||||
} | |||||
} | |||||
} | } |
@@ -1,113 +1,42 @@ | |||||
package chanjarster.weixin.api; | package chanjarster.weixin.api; | ||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import javax.xml.bind.annotation.XmlAccessType; | |||||
import javax.xml.bind.annotation.XmlAccessorType; | |||||
import javax.xml.bind.annotation.XmlRootElement; | |||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.testng.Assert; | import org.testng.Assert; | ||||
import org.testng.annotations.DataProvider; | |||||
import org.testng.annotations.Guice; | import org.testng.annotations.Guice; | ||||
import org.testng.annotations.Test; | import org.testng.annotations.Test; | ||||
import chanjarster.weixin.bean.result.WxMediaUploadResult; | |||||
import chanjarster.weixin.exception.WxErrorException; | import chanjarster.weixin.exception.WxErrorException; | ||||
import com.google.inject.Inject; | import com.google.inject.Inject; | ||||
@Test(groups="baseAPI") | |||||
/** | |||||
* 基础API测试 | |||||
* @author chanjarster | |||||
* | |||||
*/ | |||||
@Test(groups = "baseAPI") | |||||
@Guice(modules = ApiTestModule.class) | @Guice(modules = ApiTestModule.class) | ||||
public class WxBaseAPITest { | public class WxBaseAPITest { | ||||
@Inject | @Inject | ||||
protected WxServiceImpl wxService; | protected WxServiceImpl wxService; | ||||
private List<String> media_ids = new ArrayList<String>(); | |||||
@Test | |||||
public void testRefreshAccessToken() throws WxErrorException { | public void testRefreshAccessToken() throws WxErrorException { | ||||
WxConfigStorage configStorage = wxService.wxConfigStorage; | WxConfigStorage configStorage = wxService.wxConfigStorage; | ||||
String before = configStorage.getAccessToken(); | String before = configStorage.getAccessToken(); | ||||
wxService.refreshAccessToken(); | wxService.refreshAccessToken(); | ||||
String after = configStorage.getAccessToken(); | String after = configStorage.getAccessToken(); | ||||
Assert.assertNotEquals(before, after); | Assert.assertNotEquals(before, after); | ||||
Assert.assertTrue(StringUtils.isNotBlank(after)); | Assert.assertTrue(StringUtils.isNotBlank(after)); | ||||
} | } | ||||
@Test(dependsOnMethods = { "testRefreshAccessToken" }, dataProvider="uploadMedia", enabled = true) | |||||
public void testUploadMedia(String mediaType, String fileType, String fileName) throws WxErrorException, IOException { | |||||
InputStream inputStream = ClassLoader.getSystemResourceAsStream(fileName); | |||||
WxMediaUploadResult res = wxService.uploadMedia(mediaType, fileType, inputStream); | |||||
Assert.assertNotNull(res.getType()); | |||||
Assert.assertNotNull(res.getCreated_at()); | |||||
Assert.assertTrue(res.getMedia_id() != null || res.getThumb_media_id() != null); | |||||
if (res.getMedia_id() != null) { | |||||
media_ids.add(res.getMedia_id()); | |||||
} | |||||
if (res.getThumb_media_id() != null) { | |||||
media_ids.add(res.getThumb_media_id()); | |||||
} | |||||
} | |||||
@DataProvider | |||||
public Object[][] uploadMedia() { | |||||
return new Object[][] { | |||||
new Object[] { WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, "mm.jpeg" }, | |||||
new Object[] { WxConsts.MEDIA_VOICE, WxConsts.FILE_MP3, "mm.mp3" }, | |||||
new Object[] { WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, "mm.mp4" }, | |||||
new Object[] { WxConsts.MEDIA_THUMB, WxConsts.FILE_JPG, "mm.jpeg" } | |||||
}; | |||||
} | |||||
@Test(dependsOnMethods = { "testUploadMedia" }, dataProvider="downloadMedia") | |||||
public void testDownloadMedia(String media_id) throws WxErrorException { | |||||
wxService.downloadMedia(media_id); | |||||
} | |||||
@DataProvider | |||||
public Object[][] downloadMedia() { | |||||
Object[][] params = new Object[this.media_ids.size()][]; | |||||
for (int i = 0; i < this.media_ids.size(); i++) { | |||||
params[i] = new Object[] { this.media_ids.get(i) }; | |||||
} | |||||
return params; | |||||
} | |||||
@Test(enabled = true) | |||||
public void testCheckSignature() throws WxErrorException { | public void testCheckSignature() throws WxErrorException { | ||||
String timestamp = "23234235423246"; | String timestamp = "23234235423246"; | ||||
String nonce = "y7didfkcmvnbd90sdofjkiefhsd"; | String nonce = "y7didfkcmvnbd90sdofjkiefhsd"; | ||||
String signature = "77b6651628dfb9a64bfb0d3432ee053ac566a459"; | String signature = "77b6651628dfb9a64bfb0d3432ee053ac566a459"; | ||||
Assert.assertTrue(wxService.checkSignature(timestamp, nonce, signature)); | Assert.assertTrue(wxService.checkSignature(timestamp, nonce, signature)); | ||||
} | } | ||||
@XmlRootElement(name = "xml") | |||||
@XmlAccessorType(XmlAccessType.FIELD) | |||||
public static class WxXmlConfigStorage extends WxInMemoryConfigStorage { | |||||
protected String openId; | |||||
public String getOpenId() { | |||||
return openId; | |||||
} | |||||
public void setOpenId(String openId) { | |||||
this.openId = openId; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "SimpleWxConfigProvider [appId=" + appId + ", secret=" + secret + ", accessToken=" + accessToken | |||||
+ ", expiresIn=" + expiresIn + ", token=" + token + ", openId=" + openId + "]"; | |||||
} | |||||
} | |||||
} | } |
@@ -3,20 +3,24 @@ package chanjarster.weixin.api; | |||||
import org.testng.annotations.Guice; | import org.testng.annotations.Guice; | ||||
import org.testng.annotations.Test; | import org.testng.annotations.Test; | ||||
import com.google.inject.Inject; | |||||
import chanjarster.weixin.api.WxBaseAPITest.WxXmlConfigStorage; | |||||
import chanjarster.weixin.api.ApiTestModule.WxXmlConfigStorage; | |||||
import chanjarster.weixin.bean.WxCustomMessage; | import chanjarster.weixin.bean.WxCustomMessage; | ||||
import chanjarster.weixin.exception.WxErrorException; | import chanjarster.weixin.exception.WxErrorException; | ||||
@Test(dependsOnGroups="baseAPI") | |||||
import com.google.inject.Inject; | |||||
/*** | |||||
* 测试发送客服消息 | |||||
* @author chanjarster | |||||
* | |||||
*/ | |||||
@Test(groups="customMessageAPI", dependsOnGroups = "baseAPI") | |||||
@Guice(modules = ApiTestModule.class) | @Guice(modules = ApiTestModule.class) | ||||
public class WxCustomMessageAPITest { | public class WxCustomMessageAPITest { | ||||
@Inject | @Inject | ||||
protected WxServiceImpl wxService; | protected WxServiceImpl wxService; | ||||
@Test(enabled = true) | |||||
public void testSendCustomMessage() throws WxErrorException { | public void testSendCustomMessage() throws WxErrorException { | ||||
WxXmlConfigStorage configProvider = (WxXmlConfigStorage) wxService.wxConfigStorage; | WxXmlConfigStorage configProvider = (WxXmlConfigStorage) wxService.wxConfigStorage; | ||||
WxCustomMessage message = new WxCustomMessage(); | WxCustomMessage message = new WxCustomMessage(); | ||||
@@ -26,5 +30,5 @@ public class WxCustomMessageAPITest { | |||||
wxService.sendCustomMessage(message); | wxService.sendCustomMessage(message); | ||||
} | } | ||||
} | } |
@@ -0,0 +1,142 @@ | |||||
package chanjarster.weixin.api; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import org.testng.Assert; | |||||
import org.testng.annotations.DataProvider; | |||||
import org.testng.annotations.Guice; | |||||
import org.testng.annotations.Test; | |||||
import chanjarster.weixin.api.ApiTestModule.WxXmlConfigStorage; | |||||
import chanjarster.weixin.bean.WxMassNews; | |||||
import chanjarster.weixin.bean.WxMassNews.WxMassNewsArticle; | |||||
import chanjarster.weixin.bean.WxMassOpenIdsMessage; | |||||
import chanjarster.weixin.bean.WxMassVideo; | |||||
import chanjarster.weixin.bean.result.WxMassSendResult; | |||||
import chanjarster.weixin.bean.result.WxMassUploadResult; | |||||
import chanjarster.weixin.bean.result.WxMediaUploadResult; | |||||
import chanjarster.weixin.exception.WxErrorException; | |||||
import com.google.inject.Inject; | |||||
/** | |||||
* 测试群发消息 | |||||
* @author chanjarster | |||||
* | |||||
*/ | |||||
@Test(groups = "massAPI", dependsOnGroups = { "baseAPI", "mediaAPI"}) | |||||
@Guice(modules = ApiTestModule.class) | |||||
public class WxMassMessageAPITest { | |||||
@Inject | |||||
protected WxServiceImpl wxService; | |||||
@Test(enabled = false) | |||||
public void testSendMassTextByOpenIds() throws WxErrorException { | |||||
// 发送群发消息 | |||||
WxXmlConfigStorage configProvider = (WxXmlConfigStorage) wxService.wxConfigStorage; | |||||
WxMassOpenIdsMessage massMessage = new WxMassOpenIdsMessage(); | |||||
massMessage.setMsgtype(WxConsts.MASS_MSG_TEXT); | |||||
massMessage.setContent("测试群发消息\n欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); | |||||
massMessage.getTouser().add(configProvider.getOpenId()); | |||||
WxMassSendResult massResult = wxService.sendMassMessageByOpenIds(massMessage); | |||||
Assert.assertNotNull(massResult); | |||||
Assert.assertNotNull(massResult.getMsg_id()); | |||||
} | |||||
@Test(enabled = true, dataProvider="massMessages") | |||||
public void testSendMassByOpenIds(String massMsgType, String mediaId) throws WxErrorException, IOException { | |||||
// 发送群发消息 | |||||
WxXmlConfigStorage configProvider = (WxXmlConfigStorage) wxService.wxConfigStorage; | |||||
WxMassOpenIdsMessage massMessage = new WxMassOpenIdsMessage(); | |||||
massMessage.setMsgtype(massMsgType); | |||||
massMessage.setMedia_id(mediaId); | |||||
massMessage.getTouser().add(configProvider.getOpenId()); | |||||
WxMassSendResult massResult = wxService.sendMassMessageByOpenIds(massMessage); | |||||
Assert.assertNotNull(massResult); | |||||
Assert.assertNotNull(massResult.getMsg_id()); | |||||
} | |||||
@DataProvider | |||||
public Object[][] massMessages() throws WxErrorException, IOException { | |||||
Object[][] messages = new Object[4][]; | |||||
/* | |||||
* 视频素材 | |||||
*/ | |||||
{ | |||||
// 上传视频到媒体库 | |||||
InputStream inputStream = ClassLoader.getSystemResourceAsStream("mm.mp4"); | |||||
WxMediaUploadResult uploadMediaRes = wxService.uploadMedia(WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, inputStream); | |||||
Assert.assertNotNull(uploadMediaRes); | |||||
Assert.assertNotNull(uploadMediaRes.getMedia_id()); | |||||
// 把视频变成可被群发的媒体 | |||||
WxMassVideo video = new WxMassVideo(); | |||||
video.setTitle("测试标题"); | |||||
video.setDescription("测试描述"); | |||||
video.setMedia_id(uploadMediaRes.getMedia_id()); | |||||
WxMassUploadResult uploadResult = wxService.uploadMassVideo(video); | |||||
Assert.assertNotNull(uploadResult); | |||||
Assert.assertNotNull(uploadResult.getMedia_id()); | |||||
messages[0] = new Object[] { WxConsts.MASS_MSG_VIDEO, uploadResult.getMedia_id() }; | |||||
} | |||||
/** | |||||
* 图片素材 | |||||
*/ | |||||
{ | |||||
InputStream inputStream = ClassLoader.getSystemResourceAsStream("mm.jpeg"); | |||||
WxMediaUploadResult uploadMediaRes = wxService.uploadMedia(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, inputStream); | |||||
Assert.assertNotNull(uploadMediaRes); | |||||
Assert.assertNotNull(uploadMediaRes.getMedia_id()); | |||||
messages[1] = new Object[] { WxConsts.MASS_MSG_IMAGE, uploadMediaRes.getMedia_id() }; | |||||
} | |||||
/** | |||||
* 语音素材 | |||||
*/ | |||||
{ | |||||
InputStream inputStream = ClassLoader.getSystemResourceAsStream("mm.mp3"); | |||||
WxMediaUploadResult uploadMediaRes = wxService.uploadMedia(WxConsts.MEDIA_VOICE, WxConsts.FILE_MP3, inputStream); | |||||
Assert.assertNotNull(uploadMediaRes); | |||||
Assert.assertNotNull(uploadMediaRes.getMedia_id()); | |||||
messages[2] = new Object[] { WxConsts.MASS_MSG_VOICE, uploadMediaRes.getMedia_id() }; | |||||
} | |||||
/** | |||||
* 图文素材 | |||||
*/ | |||||
{ | |||||
// 上传照片到媒体库 | |||||
InputStream inputStream = ClassLoader.getSystemResourceAsStream("mm.jpeg"); | |||||
WxMediaUploadResult uploadMediaRes = wxService.uploadMedia(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, inputStream); | |||||
Assert.assertNotNull(uploadMediaRes); | |||||
Assert.assertNotNull(uploadMediaRes.getMedia_id()); | |||||
// 上传图文消息 | |||||
WxMassNews news = new WxMassNews(); | |||||
WxMassNewsArticle article1 = new WxMassNewsArticle(); | |||||
article1.setTitle("标题1"); | |||||
article1.setContent("内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1内容1"); | |||||
article1.setThumb_media_id(uploadMediaRes.getMedia_id()); | |||||
news.addArticle(article1); | |||||
WxMassNewsArticle article2 = new WxMassNewsArticle(); | |||||
article2.setTitle("标题2"); | |||||
article2.setContent("内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2内容2"); | |||||
article2.setThumb_media_id(uploadMediaRes.getMedia_id()); | |||||
article2.setShow_cover_pic(true); | |||||
article2.setAuthor("作者2"); | |||||
article2.setContent_source_url("www.baidu.com"); | |||||
article2.setDigest("摘要2"); | |||||
news.addArticle(article2); | |||||
WxMassUploadResult massUploadResult = wxService.uploadMassNews(news); | |||||
Assert.assertNotNull(massUploadResult); | |||||
Assert.assertNotNull(uploadMediaRes.getMedia_id()); | |||||
messages[3] = new Object[] { WxConsts.MASS_MSG_VIDEO, massUploadResult.getMedia_id() }; | |||||
} | |||||
return messages; | |||||
} | |||||
} |
@@ -0,0 +1,72 @@ | |||||
package chanjarster.weixin.api; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import org.testng.Assert; | |||||
import org.testng.annotations.DataProvider; | |||||
import org.testng.annotations.Guice; | |||||
import org.testng.annotations.Test; | |||||
import chanjarster.weixin.bean.result.WxMediaUploadResult; | |||||
import chanjarster.weixin.exception.WxErrorException; | |||||
import com.google.inject.Inject; | |||||
/** | |||||
* 测试多媒体文件上传下载 | |||||
* @author chanjarster | |||||
* | |||||
*/ | |||||
@Test(groups="mediaAPI", dependsOnGroups="baseAPI") | |||||
@Guice(modules = ApiTestModule.class) | |||||
public class WxMediaAPITest { | |||||
@Inject | |||||
protected WxServiceImpl wxService; | |||||
private List<String> media_ids = new ArrayList<String>(); | |||||
@Test(dataProvider="uploadMedia", enabled = true) | |||||
public void testUploadMedia(String mediaType, String fileType, String fileName) throws WxErrorException, IOException { | |||||
InputStream inputStream = ClassLoader.getSystemResourceAsStream(fileName); | |||||
WxMediaUploadResult res = wxService.uploadMedia(mediaType, fileType, inputStream); | |||||
Assert.assertNotNull(res.getType()); | |||||
Assert.assertNotNull(res.getCreated_at()); | |||||
Assert.assertTrue(res.getMedia_id() != null || res.getThumb_media_id() != null); | |||||
if (res.getMedia_id() != null) { | |||||
media_ids.add(res.getMedia_id()); | |||||
} | |||||
if (res.getThumb_media_id() != null) { | |||||
media_ids.add(res.getThumb_media_id()); | |||||
} | |||||
} | |||||
@DataProvider | |||||
public Object[][] uploadMedia() { | |||||
return new Object[][] { | |||||
new Object[] { WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, "mm.jpeg" }, | |||||
new Object[] { WxConsts.MEDIA_VOICE, WxConsts.FILE_MP3, "mm.mp3" }, | |||||
new Object[] { WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, "mm.mp4" }, | |||||
new Object[] { WxConsts.MEDIA_THUMB, WxConsts.FILE_JPG, "mm.jpeg" } | |||||
}; | |||||
} | |||||
@Test(dependsOnMethods = { "testUploadMedia" }, dataProvider="downloadMedia") | |||||
public void testDownloadMedia(String media_id) throws WxErrorException { | |||||
wxService.downloadMedia(media_id); | |||||
} | |||||
@DataProvider | |||||
public Object[][] downloadMedia() { | |||||
Object[][] params = new Object[this.media_ids.size()][]; | |||||
for (int i = 0; i < this.media_ids.size(); i++) { | |||||
params[i] = new Object[] { this.media_ids.get(i) }; | |||||
} | |||||
return params; | |||||
} | |||||
} |
@@ -13,6 +13,11 @@ import chanjarster.weixin.bean.WxMenu; | |||||
import chanjarster.weixin.bean.WxMenu.WxMenuButton; | import chanjarster.weixin.bean.WxMenu.WxMenuButton; | ||||
import chanjarster.weixin.exception.WxErrorException; | import chanjarster.weixin.exception.WxErrorException; | ||||
/** | |||||
* 测试菜单 | |||||
* @author chanjarster | |||||
* | |||||
*/ | |||||
@Test(dependsOnGroups="baseAPI") | @Test(dependsOnGroups="baseAPI") | ||||
@Guice(modules = ApiTestModule.class) | @Guice(modules = ApiTestModule.class) | ||||
public class WxMenuAPITest { | public class WxMenuAPITest { | ||||
@@ -9,6 +9,11 @@ import org.testng.annotations.Test; | |||||
import chanjarster.weixin.bean.WxXmlMessage; | import chanjarster.weixin.bean.WxXmlMessage; | ||||
/** | |||||
* 测试消息路由器 | |||||
* @author chanjarster | |||||
* | |||||
*/ | |||||
@Test | @Test | ||||
public class WxMessageRouterTest { | public class WxMessageRouterTest { | ||||
@@ -7,10 +7,13 @@ | |||||
<class name="chanjarster.weixin.api.WxCustomMessageAPITest" /> | <class name="chanjarster.weixin.api.WxCustomMessageAPITest" /> | ||||
<class name="chanjarster.weixin.api.WxMenuAPITest" /> | <class name="chanjarster.weixin.api.WxMenuAPITest" /> | ||||
<class name="chanjarster.weixin.api.WxMessageRouterTest" /> | <class name="chanjarster.weixin.api.WxMessageRouterTest" /> | ||||
<class name="chanjarster.weixin.api.WxMassMessageAPITest" /> | |||||
<class name="chanjarster.weixin.api.WxMediaAPITest" /> | |||||
<class name="chanjarster.weixin.api.WxMassMessageAPITest" /> | |||||
</classes> | </classes> | ||||
</test> | </test> | ||||
<test name="Util_Test"> | |||||
<test name="Bean_Test"> | |||||
<classes> | <classes> | ||||
<class name="chanjarster.weixin.bean.WxAccessTokenTest" /> | <class name="chanjarster.weixin.bean.WxAccessTokenTest" /> | ||||
<class name="chanjarster.weixin.bean.WxCustomMessageTest" /> | <class name="chanjarster.weixin.bean.WxCustomMessageTest" /> | ||||