mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-04-24 18:04:38 +08:00
添加群发消息单元测试
This commit is contained in:
parent
771ddef37e
commit
328b3d373a
@ -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 {
|
public WxMassUploadResult uploadMassVideo(WxMassVideo video) throws WxErrorException {
|
||||||
String url = " https://file.api.weixin.qq.com/cgi-bin/media/uploadvideo";
|
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后重试");
|
System.out.println("微信系统繁忙," + sleepMillis + "ms后重试");
|
||||||
Thread.sleep(500);
|
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;
|
* 添加OpenId,最多支持10,000个
|
||||||
|
* @param openId
|
||||||
|
*/
|
||||||
|
public void addUser(String openId) {
|
||||||
|
this.touser.add(openId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getGroup_id() {
|
|
||||||
return group_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGroup_id(String group_id) {
|
|
||||||
this.group_id = group_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -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) {
|
public static WxMassUploadResult fromJson(String json) {
|
||||||
return WxGsonBuilder.create().fromJson(json, WxMassMaterialUploadResult.class);
|
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) {
|
JsonObject filter = new JsonObject();
|
||||||
JsonArray sub = new JsonArray();
|
filter.addProperty("group_id", message.getGroup_id());
|
||||||
for(String openId : message.getTouser()) {
|
messageJson.add("filter", filter);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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.ApiTestModule.WxXmlConfigStorage;
|
||||||
|
|
||||||
import chanjarster.weixin.api.WxBaseAPITest.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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
142
src/test/java/chanjarster/weixin/api/WxMassMessageAPITest.java
Normal file
142
src/test/java/chanjarster/weixin/api/WxMassMessageAPITest.java
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
72
src/test/java/chanjarster/weixin/api/WxMediaAPITest.java
Normal file
72
src/test/java/chanjarster/weixin/api/WxMediaAPITest.java
Normal file
@ -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" />
|
||||||
|
Loading…
Reference in New Issue
Block a user