netty服务 & 消息分发

This commit is contained in:
jy.hu 2014-10-27 11:16:45 +08:00
parent 9d9e97f767
commit 0cc69cff01
44 changed files with 1060 additions and 992 deletions

View File

@ -29,10 +29,14 @@ tencent weixin platform java sdk 微信公众平台开发工具包 http://mp.wei
> 如果不想使用这种方式可以去掉pom.xml的resources节点最后一个子节点 > 如果不想使用这种方式可以去掉pom.xml的resources节点最后一个子节点
> 并修改src/main/java/com/foxinmy/weixin4j/util/WeixinConfig类相关代码以便正确获取api的uri. > 并修改src/main/java/com/foxinmy/weixin4j/util/ConfigUtil类相关代码以便正确获取api的uri.
接下来 更新LOG
------ -------
> netty服务. 2014-10-27
1).用netty构建http服务器并支持消息分发
> 消息分发.
接下来
-----
maven多模块分离
微信支付模块引入

11
pom.xml
View File

@ -32,14 +32,15 @@
<resource> <resource>
<directory>src/main/resources</directory> <directory>src/main/resources</directory>
<excludes> <excludes>
<exclude>*.*</exclude> <exclude>logback.xml</exclude>
</excludes> </excludes>
</resource> </resource>
<resource> <resource>
<directory>src/main/java</directory> <directory>src/main/java</directory>
<includes> <includes>
<include>**/config.properties</include> <include>**/*.properties</include>
<include>**/error.xml</include> <include>**/error.xml</include>
<include>**/README.md</include>
</includes> </includes>
</resource> </resource>
</resources> </resources>
@ -145,6 +146,11 @@
<artifactId>jedis</artifactId> <artifactId>jedis</artifactId>
<version>${jedis.version}</version> <version>${jedis.version}</version>
</dependency> </dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>${netty.version}</version>
</dependency>
</dependencies> </dependencies>
<properties> <properties>
@ -160,6 +166,7 @@
<jsoup.version>1.7.3</jsoup.version> <jsoup.version>1.7.3</jsoup.version>
<jaxen.version>1.1.6</jaxen.version> <jaxen.version>1.1.6</jaxen.version>
<jedis.version>2.6.0</jedis.version> <jedis.version>2.6.0</jedis.version>
<netty.version>4.0.23.Final</netty.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<profiles> <profiles>

View File

@ -1,6 +1,7 @@
package com.foxinmy.weixin4j; package com.foxinmy.weixin4j;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.List; import java.util.List;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
@ -15,6 +16,7 @@ import com.foxinmy.weixin4j.api.UserApi;
import com.foxinmy.weixin4j.api.token.FileTokenApi; import com.foxinmy.weixin4j.api.token.FileTokenApi;
import com.foxinmy.weixin4j.api.token.TokenApi; import com.foxinmy.weixin4j.api.token.TokenApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.model.Button; import com.foxinmy.weixin4j.model.Button;
import com.foxinmy.weixin4j.model.CustomRecord; import com.foxinmy.weixin4j.model.CustomRecord;
import com.foxinmy.weixin4j.model.Following; import com.foxinmy.weixin4j.model.Following;
@ -23,7 +25,6 @@ import com.foxinmy.weixin4j.model.MpArticle;
import com.foxinmy.weixin4j.model.QRParameter; import com.foxinmy.weixin4j.model.QRParameter;
import com.foxinmy.weixin4j.model.User; import com.foxinmy.weixin4j.model.User;
import com.foxinmy.weixin4j.model.UserToken; import com.foxinmy.weixin4j.model.UserToken;
import com.foxinmy.weixin4j.msg.BaseResult;
import com.foxinmy.weixin4j.msg.model.Article; import com.foxinmy.weixin4j.msg.model.Article;
import com.foxinmy.weixin4j.msg.model.BaseMsg; import com.foxinmy.weixin4j.msg.model.BaseMsg;
import com.foxinmy.weixin4j.msg.notify.BaseNotify; import com.foxinmy.weixin4j.msg.notify.BaseNotify;
@ -47,7 +48,7 @@ public class WeixinProxy {
private final GroupApi groupApi; private final GroupApi groupApi;
private final MenuApi menuApi; private final MenuApi menuApi;
private final QrApi qrApi; private final QrApi qrApi;
private final TmplApi templApi; private final TmplApi tmplApi;
/** /**
* 默认采用文件存放Token跟配置文件中的appi信息 * 默认采用文件存放Token跟配置文件中的appi信息
@ -74,7 +75,7 @@ public class WeixinProxy {
this.groupApi = new GroupApi(tokenApi); this.groupApi = new GroupApi(tokenApi);
this.menuApi = new MenuApi(tokenApi); this.menuApi = new MenuApi(tokenApi);
this.qrApi = new QrApi(tokenApi); this.qrApi = new QrApi(tokenApi);
this.templApi = new TmplApi(tokenApi); this.tmplApi = new TmplApi(tokenApi);
} }
/** /**
@ -90,12 +91,13 @@ public class WeixinProxy {
* 媒体类型 * 媒体类型
* @return 上传到微信服务器返回的媒体标识 * @return 上传到微信服务器返回的媒体标识
* @throws WeixinException * @throws WeixinException
* @throws IOException
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD%E5%A4%9A%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">上传下载说明</a> * href="http://mp.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD%E5%A4%9A%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">上传下载说明</a>
* @see com.foxinmy.weixin4j.type.MediaType * @see com.foxinmy.weixin4j.type.MediaType
*/ */
public String uploadMedia(File file, MediaType mediaType) public String uploadMedia(File file, MediaType mediaType)
throws WeixinException { throws WeixinException, IOException {
return mediaApi.uploadMedia(file, mediaType); return mediaApi.uploadMedia(file, mediaType);
} }
@ -127,12 +129,13 @@ public class WeixinProxy {
* 媒体类型 * 媒体类型
* @return 写入硬盘后的文件对象 * @return 写入硬盘后的文件对象
* @throws WeixinException * @throws WeixinException
* @throws IOException
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD%E5%A4%9A%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">上传下载说明</a> * href="http://mp.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD%E5%A4%9A%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">上传下载说明</a>
* @see com.foxinmy.weixin4j.type.MediaType * @see com.foxinmy.weixin4j.type.MediaType
*/ */
public File downloadMedia(String mediaId, MediaType mediaType) public File downloadMedia(String mediaId, MediaType mediaType)
throws WeixinException { throws WeixinException, IOException {
return mediaApi.downloadMedia(mediaId, mediaType); return mediaApi.downloadMedia(mediaId, mediaType);
} }
@ -464,9 +467,9 @@ public class WeixinProxy {
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%AE%BE%E7%BD%AE%E7%94%A8%E6%88%B7%E5%A4%87%E6%B3%A8%E5%90%8D%E6%8E%A5%E5%8F%A3">设置用户备注名</a> * href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%AE%BE%E7%BD%AE%E7%94%A8%E6%88%B7%E5%A4%87%E6%B3%A8%E5%90%8D%E6%8E%A5%E5%8F%A3">设置用户备注名</a>
*/ */
public BaseResult updateUserRemark(String openId, String remark) public BaseResult remarkUserName(String openId, String remark)
throws WeixinException { throws WeixinException {
return userApi.updateUserRemark(openId, remark); return userApi.remarkUserName(openId, remark);
} }
/** /**
@ -625,11 +628,12 @@ public class WeixinProxy {
* 二维码参数 * 二维码参数
* @return 硬盘存储的文件对象 * @return 硬盘存储的文件对象
* @throws WeixinException * @throws WeixinException
* @throws IOException
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E7%94%9F%E6%88%90%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E4%BA%8C%E7%BB%B4%E7%A0%81">二维码</a> * href="http://mp.weixin.qq.com/wiki/index.php?title=%E7%94%9F%E6%88%90%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E4%BA%8C%E7%BB%B4%E7%A0%81">二维码</a>
* @see com.foxinmy.weixin4j.model.QRParameter * @see com.foxinmy.weixin4j.model.QRParameter
*/ */
public File getQR(QRParameter parameter) throws WeixinException { public File getQR(QRParameter parameter) throws WeixinException, IOException {
return qrApi.getQR(parameter); return qrApi.getQR(parameter);
} }
@ -644,8 +648,8 @@ public class WeixinProxy {
* @see com.foxinmy.weixin4j.msg.out.TemplateMessage * @see com.foxinmy.weixin4j.msg.out.TemplateMessage
* @seee com.foxinmy.weixin4j.msg.event.TemplatesendjobfinishMessage * @seee com.foxinmy.weixin4j.msg.event.TemplatesendjobfinishMessage
*/ */
public BaseResult sendTplMessage(TemplateMessage tplMessage) public BaseResult sendTmplMessage(TemplateMessage tplMessage)
throws WeixinException { throws WeixinException {
return templApi.sendTplMessage(tplMessage); return tmplApi.sendTmplMessage(tplMessage);
} }
} }

View File

@ -5,10 +5,10 @@ import java.util.List;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.api.token.TokenApi; import com.foxinmy.weixin4j.api.token.TokenApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.http.Response;
import com.foxinmy.weixin4j.model.Group; import com.foxinmy.weixin4j.model.Group;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.msg.BaseResult;
import com.foxinmy.weixin4j.util.ConfigUtil; import com.foxinmy.weixin4j.util.ConfigUtil;
/** /**

View File

@ -6,10 +6,10 @@ import java.util.List;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.api.token.TokenApi; import com.foxinmy.weixin4j.api.token.TokenApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.http.Response;
import com.foxinmy.weixin4j.model.MpArticle; import com.foxinmy.weixin4j.model.MpArticle;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.msg.BaseResult;
import com.foxinmy.weixin4j.type.MediaType; import com.foxinmy.weixin4j.type.MediaType;
import com.foxinmy.weixin4j.util.ConfigUtil; import com.foxinmy.weixin4j.util.ConfigUtil;

View File

@ -1,6 +1,5 @@
package com.foxinmy.weixin4j.api; package com.foxinmy.weixin4j.api;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -49,37 +48,16 @@ public class MediaApi extends BaseApi {
* 媒体类型 * 媒体类型
* @return 上传到微信服务器返回的媒体标识 * @return 上传到微信服务器返回的媒体标识
* @throws WeixinException * @throws WeixinException
* @throws IOException
* @throws
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD%E5%A4%9A%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">上传下载说明</a> * href="http://mp.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD%E5%A4%9A%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">上传下载说明</a>
* @see com.foxinmy.weixin4j.type.MediaType * @see com.foxinmy.weixin4j.type.MediaType
*/ */
public String uploadMedia(File file, MediaType mediaType) public String uploadMedia(File file, MediaType mediaType)
throws WeixinException { throws WeixinException, IOException {
byte[] b = null; byte[] datas = IOUtil.toByteArray(new FileInputStream(file));
ByteArrayOutputStream out = null; return uploadMedia(file.getName(), datas, mediaType);
FileInputStream in = null;
try {
in = new FileInputStream(file);
b = IOUtil.toByteArray(in);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
;
}
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
;
}
}
}
return uploadMedia(file.getName(), b, mediaType);
} }
/** /**
@ -116,40 +94,30 @@ public class MediaApi extends BaseApi {
* 媒体类型 * 媒体类型
* @return 写入硬盘后的文件对象 * @return 写入硬盘后的文件对象
* @throws WeixinException * @throws WeixinException
* @throws IOException
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD%E5%A4%9A%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">上传下载说明</a> * href="http://mp.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD%E5%A4%9A%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6">上传下载说明</a>
* @see com.foxinmy.weixin4j.type.MediaType * @see com.foxinmy.weixin4j.type.MediaType
*/ */
public File downloadMedia(String mediaId, MediaType mediaType) public File downloadMedia(String mediaId, MediaType mediaType)
throws WeixinException { throws WeixinException, IOException {
String media_path = ConfigUtil.getValue("media_path"); String media_path = ConfigUtil.getValue("media_path");
String filename = mediaId + mediaType.getFormatType(); byte[] datas = downloadMediaData(mediaId, mediaType);
String filename = mediaId + "." + mediaType.getFormatType();
File file = new File(media_path + File.separator + filename); File file = new File(media_path + File.separator + filename);
if (file.exists()) { if (file.exists()) {
return file; return file;
} }
FileOutputStream out = null; FileOutputStream out = null;
try { try {
try { file.createNewFile();
file.createNewFile();
} catch (IOException e) {
file.getParentFile().mkdirs();
file.createNewFile();
}
out = new FileOutputStream(file);
byte[] b = downloadMediaData(mediaId, mediaType);
out.write(b);
} catch (IOException e) { } catch (IOException e) {
file.getParentFile().mkdirs();
} finally { file.createNewFile();
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
}
} }
out = new FileOutputStream(file);
out.write(datas);
out.close();
return file; return file;
} }

View File

@ -6,10 +6,10 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.api.token.TokenApi; import com.foxinmy.weixin4j.api.token.TokenApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.http.Response;
import com.foxinmy.weixin4j.model.Button; import com.foxinmy.weixin4j.model.Button;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.msg.BaseResult;
import com.foxinmy.weixin4j.util.ConfigUtil; import com.foxinmy.weixin4j.util.ConfigUtil;
/** /**

View File

@ -6,10 +6,10 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.api.token.TokenApi; import com.foxinmy.weixin4j.api.token.TokenApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.http.Response;
import com.foxinmy.weixin4j.model.CustomRecord; import com.foxinmy.weixin4j.model.CustomRecord;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.msg.BaseResult;
import com.foxinmy.weixin4j.msg.model.Article; import com.foxinmy.weixin4j.msg.model.Article;
import com.foxinmy.weixin4j.msg.model.BaseMsg; import com.foxinmy.weixin4j.msg.model.BaseMsg;
import com.foxinmy.weixin4j.msg.notify.ArticleNotify; import com.foxinmy.weixin4j.msg.notify.ArticleNotify;

View File

@ -1,6 +1,7 @@
package com.foxinmy.weixin4j.api; package com.foxinmy.weixin4j.api;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
@ -19,7 +20,8 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
* @author jy.hu * @author jy.hu
* @date 2014年9月25日 * @date 2014年9月25日
* @since JDK 1.7 * @since JDK 1.7
* @see <a href="http://mp.weixin.qq.com/wiki/index.php?title=%E7%94%9F%E6%88%90%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E4%BA%8C%E7%BB%B4%E7%A0%81">二维码支持</a> * @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E7%94%9F%E6%88%90%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E4%BA%8C%E7%BB%B4%E7%A0%81">二维码支持</a>
*/ */
public class QrApi extends BaseApi { public class QrApi extends BaseApi {
@ -40,7 +42,9 @@ public class QrApi extends BaseApi {
public byte[] getQRData(QRParameter parameter) throws WeixinException { public byte[] getQRData(QRParameter parameter) throws WeixinException {
Token token = tokenApi.getToken(); Token token = tokenApi.getToken();
String qr_uri = ConfigUtil.getValue("qr_ticket_uri"); String qr_uri = ConfigUtil.getValue("qr_ticket_uri");
Response response = request.post(String.format(qr_uri, token.getAccessToken()), parameter.toJson()); Response response = request.post(
String.format(qr_uri, token.getAccessToken()),
parameter.toJson());
String ticket = response.getAsJson().getString("ticket"); String ticket = response.getAsJson().getString("ticket");
qr_uri = ConfigUtil.getValue("qr_image_uri"); qr_uri = ConfigUtil.getValue("qr_image_uri");
response = request.get(String.format(qr_uri, ticket)); response = request.get(String.format(qr_uri, ticket));
@ -59,8 +63,10 @@ public class QrApi extends BaseApi {
* @throws WeixinException * @throws WeixinException
* @see {@link com.foxinmy.weixin4j.api.QrApi#getQR(QRParameter)} * @see {@link com.foxinmy.weixin4j.api.QrApi#getQR(QRParameter)}
*/ */
public byte[] getQRData(int sceneId, int expireSeconds) throws WeixinException { public byte[] getQRData(int sceneId, int expireSeconds)
QRParameter parameter = new QRParameter(sceneId, QRType.TEMPORARY, expireSeconds); throws WeixinException {
QRParameter parameter = new QRParameter(sceneId, QRType.TEMPORARY,
expireSeconds);
if (expireSeconds <= 0) { if (expireSeconds <= 0) {
parameter.setQrType(QRType.PERMANENCE); parameter.setQrType(QRType.PERMANENCE);
} }
@ -77,39 +83,31 @@ public class QrApi extends BaseApi {
* 二维码参数 * 二维码参数
* @return 硬盘存储的文件对象 * @return 硬盘存储的文件对象
* @throws WeixinException * @throws WeixinException
* @throws FileNotFoundException
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E7%94%9F%E6%88%90%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E4%BA%8C%E7%BB%B4%E7%A0%81">二维码</a> * href="http://mp.weixin.qq.com/wiki/index.php?title=%E7%94%9F%E6%88%90%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E4%BA%8C%E7%BB%B4%E7%A0%81">二维码</a>
* @see com.foxinmy.weixin4j.model.QRParameter * @see com.foxinmy.weixin4j.model.QRParameter
*/ */
public File getQR(QRParameter parameter) throws WeixinException { public File getQR(QRParameter parameter) throws WeixinException,
IOException {
String qr_path = ConfigUtil.getValue("qr_path"); String qr_path = ConfigUtil.getValue("qr_path");
String filename = String.format("%s_%d_%d.jpg", parameter.getQrType().name(), parameter.getSceneId(), parameter.getExpireSeconds()); String filename = String.format("%s_%d_%d.jpg", parameter.getQrType()
.name(), parameter.getSceneId(), parameter.getExpireSeconds());
File file = new File(qr_path + File.separator + filename); File file = new File(qr_path + File.separator + filename);
if (parameter.getQrType() == QRType.PERMANENCE && file.exists()) { if (parameter.getQrType() == QRType.PERMANENCE && file.exists()) {
return file; return file;
} }
byte[] datas = getQRData(parameter);
FileOutputStream out = null; FileOutputStream out = null;
try { try {
try { file.createNewFile();
file.createNewFile();
} catch (IOException e) {
file.getParentFile().mkdirs();
file.createNewFile();
}
out = new FileOutputStream(file);
byte[] b = getQRData(parameter);
out.write(b);
} catch (IOException e) { } catch (IOException e) {
; file.getParentFile().mkdirs();
} finally { file.createNewFile();
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
;
}
} }
out = new FileOutputStream(file);
out.write(datas);
out.close();
return file; return file;
} }
} }

View File

@ -2,9 +2,9 @@ package com.foxinmy.weixin4j.api;
import com.foxinmy.weixin4j.api.token.TokenApi; import com.foxinmy.weixin4j.api.token.TokenApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.http.Response;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.msg.BaseResult;
import com.foxinmy.weixin4j.msg.out.TemplateMessage; import com.foxinmy.weixin4j.msg.out.TemplateMessage;
import com.foxinmy.weixin4j.util.ConfigUtil; import com.foxinmy.weixin4j.util.ConfigUtil;
@ -36,7 +36,7 @@ public class TmplApi extends BaseApi {
* @see com.foxinmy.weixin4j.msg.out.TemplateMessage * @see com.foxinmy.weixin4j.msg.out.TemplateMessage
* @seee com.foxinmy.weixin4j.msg.event.TemplatesendjobfinishMessage * @seee com.foxinmy.weixin4j.msg.event.TemplatesendjobfinishMessage
*/ */
public BaseResult sendTplMessage(TemplateMessage tplMessage) public BaseResult sendTmplMessage(TemplateMessage tplMessage)
throws WeixinException { throws WeixinException {
Token token = tokenApi.getToken(); Token token = tokenApi.getToken();
String template_send_uri = ConfigUtil.getValue("template_send_uri"); String template_send_uri = ConfigUtil.getValue("template_send_uri");

View File

@ -7,12 +7,12 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.api.token.TokenApi; import com.foxinmy.weixin4j.api.token.TokenApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.http.Response;
import com.foxinmy.weixin4j.model.Following; import com.foxinmy.weixin4j.model.Following;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.model.User; import com.foxinmy.weixin4j.model.User;
import com.foxinmy.weixin4j.model.UserToken; import com.foxinmy.weixin4j.model.UserToken;
import com.foxinmy.weixin4j.msg.BaseResult;
import com.foxinmy.weixin4j.util.ConfigUtil; import com.foxinmy.weixin4j.util.ConfigUtil;
/** /**
@ -166,7 +166,7 @@ public class UserApi extends BaseApi {
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%AE%BE%E7%BD%AE%E7%94%A8%E6%88%B7%E5%A4%87%E6%B3%A8%E5%90%8D%E6%8E%A5%E5%8F%A3">设置用户备注名</a> * href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%AE%BE%E7%BD%AE%E7%94%A8%E6%88%B7%E5%A4%87%E6%B3%A8%E5%90%8D%E6%8E%A5%E5%8F%A3">设置用户备注名</a>
*/ */
public BaseResult updateUserRemark(String openId, String remark) public BaseResult remarkUserName(String openId, String remark)
throws WeixinException { throws WeixinException {
String updateremark_uri = ConfigUtil.getValue("updateremark_uri"); String updateremark_uri = ConfigUtil.getValue("updateremark_uri");
Token token = tokenApi.getToken(); Token token = tokenApi.getToken();

View File

@ -2,7 +2,7 @@
app_id=wx4ab8f8de58159a57 app_id=wx4ab8f8de58159a57
app_secret=1d4eb0f4bf556aaed539f30ed05ca795 app_secret=1d4eb0f4bf556aaed539f30ed05ca795
app_openId=gh_22b350df957b app_openId=gh_22b350df957b
app_token=carsonliu13450438112 app_token=wexintoken
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# api\u9996\u9875 # api\u9996\u9875
@ -15,7 +15,6 @@ api_base_url=https://api.weixin.qq.com/cgi-bin
mp_base_url=https://mp.weixin.qq.com/cgi-bin mp_base_url=https://mp.weixin.qq.com/cgi-bin
file_base_url=http://file.api.weixin.qq.com/cgi-bin file_base_url=http://file.api.weixin.qq.com/cgi-bin
# \u7f51\u9875\u6388\u6743\u83b7\u53d6\u7528\u6237\u4fe1\u606f # \u7f51\u9875\u6388\u6743\u83b7\u53d6\u7528\u6237\u4fe1\u606f
user_auth_uri=https://open.weixin.qq.com/connect/oauth2/authorize?appid={app_id}&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect user_auth_uri=https://open.weixin.qq.com/connect/oauth2/authorize?appid={app_id}&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect
sns_user_token_uri=https://api.weixin.qq.com/sns/oauth2/access_token?appid={app_id}&secret={app_secret}&code=%s&grant_type=authorization_code sns_user_token_uri=https://api.weixin.qq.com/sns/oauth2/access_token?appid={app_id}&secret={app_secret}&code=%s&grant_type=authorization_code
@ -25,15 +24,13 @@ sns_user_info_uri=https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=
api_user_info_uri={api_base_url}/user/info?access_token=%s&openid=%s&lang=zh_CN api_user_info_uri={api_base_url}/user/info?access_token=%s&openid=%s&lang=zh_CN
# \u83b7\u53d6\u6211\u7684token # \u83b7\u53d6\u6211\u7684token
api_token_uri={api_base_url}/token?grant_type=client_credential&appid=%s&secret=%s api_token_uri={api_base_url}/token?grant_type=client_credential&appid=%s&secret=%s
# \u83b7\u53d6\u4e8c\u7ef4\u7801 # \u83b7\u53d6\u4e8c\u7ef4\u7801
qr_ticket_uri={api_base_url}/qrcode/create?access_token=%s qr_ticket_uri={api_base_url}/qrcode/create?access_token=%s
qr_image_uri={mp_base_url}/showqrcode?ticket=%s qr_image_uri={mp_base_url}/showqrcode?ticket=%s
# \u4e0a\u4f20\u5a92\u4f53\u6587\u4ef6 # \u4e0a\u4f20\u5a92\u4f53\u6587\u4ef6
file_upload_uri={file_base_url}/media/upload?access_token=%s&type=%s file_upload_uri={file_base_url}/media/upload?access_token=%s&type=%s
# \u4e0b\u8f7d\u5a92\u4f53\u6587\u4ef6
file_download_uri={file_base_url}/media/get?access_token=%s&media_id=%s file_download_uri={file_base_url}/media/get?access_token=%s&media_id=%s
# \u53d1\u9001\u5ba2\u670d\u6d88\u606f # \u53d1\u9001\u5ba2\u670d\u6d88\u606f
custom_notify_uri={api_base_url}/message/custom/send?access_token=%s custom_notify_uri={api_base_url}/message/custom/send?access_token=%s
# \u521b\u5efa\u5206\u7ec4 # \u521b\u5efa\u5206\u7ec4
@ -73,10 +70,9 @@ updateremark_uri={api_base_url}/user/info/updateremark?access_token=%s
# \u6a21\u677f\u6d88\u606f # \u6a21\u677f\u6d88\u606f
template_send_uri={api_base_url}/message/template/send?access_token=%s template_send_uri={api_base_url}/message/template/send?access_token=%s
# token\u5b58\u653e\u8def\u5f84 # token\u5b58\u653e\u8def\u5f84
token_path=/tmp/weixin/token token_path=/tmp/weixin/token
# \u4e8c\u7ef4\u7801\u4fdd\u5b58\u8def\u5f84 # \u4e8c\u7ef4\u7801\u4fdd\u5b58\u8def\u5f84
qr_path=/tmp/weixin/qr qr_path=/tmp/weixin/qr
# \u5a92\u4f53\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 # \u5a92\u4f53\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84
media_path=/tmp/weixin/media media_path=/tmp/weixin/media

View File

@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.exception;
/** /**
* 调用微信接口抛出的异常 * 调用微信接口抛出的异常
*
* @className WeixinException * @className WeixinException
* @author jy.hu * @author jy.hu
* @date 2014年4月10日 * @date 2014年4月10日
@ -29,10 +30,15 @@ public class WeixinException extends Exception {
} }
public int getErrorCode() { public int getErrorCode() {
return this.errorCode; return errorCode;
} }
public String getErrorMsg() { public String getErrorMsg() {
return this.errorMsg; return errorMsg;
}
@Override
public String getMessage() {
return this.errorCode + "," + this.errorMsg;
} }
} }

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.msg; package com.foxinmy.weixin4j.http;
import java.io.Serializable; import java.io.Serializable;

View File

@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.http;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -33,7 +34,6 @@ import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.msg.BaseResult;
/** /**
* 调用微信相关接口的HttpRequest,对于其他请求可能并不试用 * 调用微信相关接口的HttpRequest,对于其他请求可能并不试用
@ -51,7 +51,8 @@ public class HttpRequest {
this(150, 100, 10000, 10000); this(150, 100, 10000, 10000);
} }
public HttpRequest(int maxConPerRoute, int maxTotal, int socketTimeout, int connectionTimeout) { public HttpRequest(int maxConPerRoute, int maxTotal, int socketTimeout,
int connectionTimeout) {
PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager(); PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
// 指定IP并发最大数 // 指定IP并发最大数
connectionManager.setDefaultMaxPerRoute(maxConPerRoute); connectionManager.setDefaultMaxPerRoute(maxConPerRoute);
@ -59,25 +60,35 @@ public class HttpRequest {
connectionManager.setMaxTotal(maxTotal); connectionManager.setMaxTotal(maxTotal);
client = new DefaultHttpClient(connectionManager); client = new DefaultHttpClient(connectionManager);
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, socketTimeout); client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,
client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connectionTimeout); socketTimeout);
client.getParams().setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, false); client.getParams().setParameter(
client.getParams().setParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 1024 * 1024); CoreConnectionPNames.CONNECTION_TIMEOUT, connectionTimeout);
client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.IGNORE_COOKIES); client.getParams().setBooleanParameter(
client.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, Consts.UTF_8); CoreConnectionPNames.TCP_NODELAY, false);
client.getParams().setParameter(HttpHeaders.CONTENT_ENCODING, Consts.UTF_8); client.getParams().setParameter(
client.getParams().setParameter(HttpHeaders.ACCEPT_CHARSET, Consts.UTF_8); CoreConnectionPNames.SOCKET_BUFFER_SIZE, 1024 * 1024);
client.getParams().setParameter(ClientPNames.COOKIE_POLICY,
CookiePolicy.IGNORE_COOKIES);
client.getParams().setParameter(
CoreProtocolPNames.HTTP_CONTENT_CHARSET, Consts.UTF_8);
client.getParams().setParameter(HttpHeaders.CONTENT_ENCODING,
Consts.UTF_8);
client.getParams().setParameter(HttpHeaders.ACCEPT_CHARSET,
Consts.UTF_8);
} }
public Response get(String url) throws WeixinException { public Response get(String url) throws WeixinException {
return get(url, (Parameter[]) null); return get(url, (Parameter[]) null);
} }
public Response get(String url, Parameter... parameters) throws WeixinException { public Response get(String url, Parameter... parameters)
throws WeixinException {
StringBuilder sb = new StringBuilder(url); StringBuilder sb = new StringBuilder(url);
if (parameters != null && parameters.length > 0) { if (parameters != null && parameters.length > 0) {
if (url.indexOf("?") < 0) { if (url.indexOf("?") < 0) {
sb.append(String.format("?%s=%s", parameters[0].getName(), parameters[0].getValue())); sb.append(String.format("?%s=%s", parameters[0].getName(),
parameters[0].getValue()));
} }
for (int i = 0; i < parameters.length; i++) { for (int i = 0; i < parameters.length; i++) {
sb.append(parameters[i].toGetPara()); sb.append(parameters[i].toGetPara());
@ -90,7 +101,8 @@ public class HttpRequest {
return post(url, (Parameter[]) null); return post(url, (Parameter[]) null);
} }
public Response post(String url, Parameter... parameters) throws WeixinException { public Response post(String url, Parameter... parameters)
throws WeixinException {
HttpPost method = new HttpPost(url); HttpPost method = new HttpPost(url);
List<NameValuePair> params = new ArrayList<NameValuePair>(); List<NameValuePair> params = new ArrayList<NameValuePair>();
for (Parameter parameter : parameters) { for (Parameter parameter : parameters) {
@ -102,23 +114,28 @@ public class HttpRequest {
public Response post(String url, String body) throws WeixinException { public Response post(String url, String body) throws WeixinException {
HttpPost method = new HttpPost(url); HttpPost method = new HttpPost(url);
method.setEntity(new StringEntity(body, ContentType.create(ContentType.APPLICATION_JSON.getMimeType(), Consts.UTF_8))); method.setEntity(new StringEntity(body, ContentType.create(
ContentType.APPLICATION_JSON.getMimeType(), Consts.UTF_8)));
return doRequest(method); return doRequest(method);
} }
public Response post(String url, byte[] bytes) throws WeixinException { public Response post(String url, byte[] bytes) throws WeixinException {
HttpPost method = new HttpPost(url); HttpPost method = new HttpPost(url);
method.setEntity(new ByteArrayEntity(bytes, ContentType.create(ContentType.MULTIPART_FORM_DATA.getMimeType(), Consts.UTF_8))); method.setEntity(new ByteArrayEntity(bytes, ContentType.create(
ContentType.MULTIPART_FORM_DATA.getMimeType(), Consts.UTF_8)));
return doRequest(method); return doRequest(method);
} }
public Response post(String url, File file) throws WeixinException { public Response post(String url, File file) throws WeixinException {
HttpPost method = new HttpPost(url); HttpPost method = new HttpPost(url);
method.setEntity(new FileEntity(file, ContentType.create(ContentType.APPLICATION_OCTET_STREAM.getMimeType(), Consts.UTF_8))); method.setEntity(new FileEntity(file, ContentType.create(
ContentType.APPLICATION_OCTET_STREAM.getMimeType(),
Consts.UTF_8)));
return doRequest(method); return doRequest(method);
} }
public Response post(String url, PartParameter... paramters) throws WeixinException { public Response post(String url, PartParameter... paramters)
throws WeixinException {
HttpPost method = new HttpPost(url); HttpPost method = new HttpPost(url);
MultipartEntity entity = new MultipartEntity(); MultipartEntity entity = new MultipartEntity();
for (PartParameter paramter : paramters) { for (PartParameter paramter : paramters) {
@ -129,7 +146,8 @@ public class HttpRequest {
return doRequest(method); return doRequest(method);
} }
protected Response doRequest(HttpRequestBase request) throws WeixinException { protected Response doRequest(HttpRequestBase request)
throws WeixinException {
try { try {
HttpResponse httpResponse = client.execute(request); HttpResponse httpResponse = client.execute(request);
StatusLine statusLine = httpResponse.getStatusLine(); StatusLine statusLine = httpResponse.getStatusLine();
@ -140,8 +158,11 @@ public class HttpRequest {
throw new WeixinException(status, "request fail"); throw new WeixinException(status, "request fail");
} }
// 301或者302 // 301或者302
if (status == HttpStatus.SC_MOVED_PERMANENTLY || status == HttpStatus.SC_MOVED_TEMPORARILY) { if (status == HttpStatus.SC_MOVED_PERMANENTLY
throw new WeixinException(status, String.format("the page was redirected to %s", httpResponse.getFirstHeader("location"))); || status == HttpStatus.SC_MOVED_TEMPORARILY) {
throw new WeixinException(status, String.format(
"the page was redirected to %s",
httpResponse.getFirstHeader("location")));
} }
byte[] data = EntityUtils.toByteArray(httpEntity); byte[] data = EntityUtils.toByteArray(httpEntity);
Response response = new Response(); Response response = new Response();
@ -151,16 +172,21 @@ public class HttpRequest {
response.setStream(new ByteArrayInputStream(data)); response.setStream(new ByteArrayInputStream(data));
response.setText(StringUtils.newStringUtf8(data)); response.setText(StringUtils.newStringUtf8(data));
Header contentType = httpResponse.getFirstHeader(HttpHeaders.CONTENT_TYPE); Header contentType = httpResponse
if (contentType.getValue().contains(ContentType.APPLICATION_JSON.getMimeType())) { .getFirstHeader(HttpHeaders.CONTENT_TYPE);
if (contentType.getValue().contains(
ContentType.APPLICATION_JSON.getMimeType())
|| contentType.getValue().contains(
ContentType.TEXT_PLAIN.getMimeType())) {
BaseResult result = response.getAsResult(); BaseResult result = response.getAsResult();
if (result.getErrcode() != 0) { if (result.getErrcode() != 0) {
throw new WeixinException(result.getErrcode(), result.getErrmsg()); throw new WeixinException(result.getErrcode(),
result.getErrmsg());
} }
} }
EntityUtils.consume(httpEntity); EntityUtils.consume(httpEntity);
return response; return response;
} catch (Exception e) { } catch (IOException e) {
throw new WeixinException(e.getMessage()); throw new WeixinException(e.getMessage());
} finally { } finally {
request.releaseConnection(); request.releaseConnection();

View File

@ -11,7 +11,6 @@ import org.dom4j.io.SAXReader;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.WeixinProxy; import com.foxinmy.weixin4j.WeixinProxy;
import com.foxinmy.weixin4j.msg.BaseResult;
import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.XStream;
public class Response { public class Response {

View File

@ -4,6 +4,7 @@ import java.io.Serializable;
import java.io.Writer; import java.io.Writer;
import com.foxinmy.weixin4j.type.MessageType; import com.foxinmy.weixin4j.type.MessageType;
import com.foxinmy.weixin4j.util.ClassUtil;
import com.foxinmy.weixin4j.xml.XStream; import com.foxinmy.weixin4j.xml.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
@ -25,8 +26,14 @@ import com.thoughtworks.xstream.io.json.JsonWriter;
public class BaseMessage implements Serializable { public class BaseMessage implements Serializable {
private static final long serialVersionUID = 7761192742840031607L; private static final long serialVersionUID = 7761192742840031607L;
private static XStream xstream; private final static XStream xmlStream = new XStream();
private final static XStream jsonStream = new XStream(
new JsonHierarchicalStreamDriver() {
public HierarchicalStreamWriter createWriter(Writer writer) {
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
}
});
@XStreamAlias("ToUserName") @XStreamAlias("ToUserName")
private String toUserName; // 开发者微信号 private String toUserName; // 开发者微信号
@XStreamAlias("FromUserName") @XStreamAlias("FromUserName")
@ -38,10 +45,21 @@ public class BaseMessage implements Serializable {
@XStreamAlias("MsgId") @XStreamAlias("MsgId")
private long msgId; // 消息ID private long msgId; // 消息ID
static{ static {
xstream = new XStream(); Class<?>[] classes = ClassUtil.getClasses(
TextMessage.class.getPackage()).toArray(new Class[0]);
xmlStream.ignoreUnknownElements();
xmlStream.autodetectAnnotations(true);
xmlStream.processAnnotations(classes);
xmlStream.omitField(BaseMessage.class, "msgId");
jsonStream.setMode(XStream.NO_REFERENCES);
jsonStream.autodetectAnnotations(true);
jsonStream.processAnnotations(classes);
jsonStream.omitField(BaseMessage.class, "msgId");
} }
public BaseMessage(MessageType msgType) { public BaseMessage(MessageType msgType) {
this.msgType = msgType; this.msgType = msgType;
} }
@ -108,11 +126,8 @@ public class BaseMessage implements Serializable {
protected XStream getXStream() { protected XStream getXStream() {
Class<? extends BaseMessage> targetClass = getMsgType() Class<? extends BaseMessage> targetClass = getMsgType()
.getMessageClass(); .getMessageClass();
xstream.alias("xml", targetClass); xmlStream.alias("xml", targetClass);
xstream.autodetectAnnotations(true); return xmlStream;
xstream.processAnnotations(targetClass);
xstream.omitField(BaseMessage.class, "msgId");
return xstream;
} }
/** /**
@ -121,13 +136,7 @@ public class BaseMessage implements Serializable {
* @return xml字符串 * @return xml字符串
*/ */
public String toXml() { public String toXml() {
Class<? extends BaseMessage> targetClass = getMsgType() return getXStream().toXML(this);
.getMessageClass();
xstream.alias("xml", targetClass);
xstream.autodetectAnnotations(true);
xstream.processAnnotations(targetClass);
xstream.omitField(BaseMessage.class, "msgId");
return xstream.toXML(this);
} }
/** /**
@ -136,15 +145,6 @@ public class BaseMessage implements Serializable {
* @return json字符串 * @return json字符串
*/ */
public String toJson() { public String toJson() {
XStream xstream = new XStream(new JsonHierarchicalStreamDriver() { return jsonStream.toXML(this);
public HierarchicalStreamWriter createWriter(Writer writer) {
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
}
});
xstream.setMode(XStream.NO_REFERENCES);
xstream.autodetectAnnotations(true);
xstream.processAnnotations(getMsgType().getMessageClass());
xstream.omitField(BaseMessage.class, "msgId");
return xstream.toXML(this);
} }
} }

View File

@ -3,7 +3,9 @@ package com.foxinmy.weixin4j.msg.model;
import java.io.Serializable; import java.io.Serializable;
import java.io.Writer; import java.io.Writer;
import com.foxinmy.weixin4j.msg.notify.BaseNotify;
import com.foxinmy.weixin4j.type.MediaType; import com.foxinmy.weixin4j.type.MediaType;
import com.foxinmy.weixin4j.util.ClassUtil;
import com.foxinmy.weixin4j.xml.XStream; import com.foxinmy.weixin4j.xml.XStream;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver; import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
@ -11,6 +13,18 @@ import com.thoughtworks.xstream.io.json.JsonWriter;
public abstract class BaseMsg implements Serializable { public abstract class BaseMsg implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final static XStream xstream = new XStream(
new JsonHierarchicalStreamDriver() {
public HierarchicalStreamWriter createWriter(Writer writer) {
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
}
});
static {
xstream.setMode(XStream.NO_REFERENCES);
xstream.autodetectAnnotations(true);
xstream.processAnnotations(ClassUtil.getClasses(
BaseNotify.class.getPackage()).toArray(new Class[0]));
}
public abstract MediaType getMediaType(); public abstract MediaType getMediaType();
@ -20,14 +34,6 @@ public abstract class BaseMsg implements Serializable {
* @return {"touser": "to","msgtype": "text","text": {"content": "123"}} * @return {"touser": "to","msgtype": "text","text": {"content": "123"}}
*/ */
public String toNotifyJson() { public String toNotifyJson() {
XStream xstream = new XStream(new JsonHierarchicalStreamDriver() {
public HierarchicalStreamWriter createWriter(Writer writer) {
return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
}
});
xstream.setMode(XStream.NO_REFERENCES);
xstream.autodetectAnnotations(true);
xstream.processAnnotations(this.getClass());
return xstream.toXML(this); return xstream.toXML(this);
} }
} }

View File

@ -1,7 +1,6 @@
package com.foxinmy.weixin4j.msg.out; package com.foxinmy.weixin4j.msg.out;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List;
import com.foxinmy.weixin4j.msg.BaseMessage; import com.foxinmy.weixin4j.msg.BaseMessage;
import com.foxinmy.weixin4j.msg.model.Article; import com.foxinmy.weixin4j.msg.model.Article;
@ -35,19 +34,14 @@ public class ArticleMessage extends BaseMessage {
@XStreamAlias("Articles") @XStreamAlias("Articles")
private LinkedList<Article> articles; private LinkedList<Article> articles;
public List<Article> getArticles() {
return this.articles;
}
public void pushArticle(String title, String desc, String picUrl, String url) { public void pushArticle(String title, String desc, String picUrl, String url) {
if ((count + 1) > MAX_ARTICLE_COUNT) {
return;
}
if (this.articles == null) { if (this.articles == null) {
this.articles = new LinkedList<Article>(); this.articles = new LinkedList<Article>();
} }
if ((articles.size() + 1) > MAX_ARTICLE_COUNT) {
return;
}
this.articles.add(new Article(title, desc, picUrl, url)); this.articles.add(new Article(title, desc, picUrl, url));
count++;
} }
public void pushFirstArticle(String title, String desc, String picUrl, public void pushFirstArticle(String title, String desc, String picUrl,
@ -67,10 +61,11 @@ public class ArticleMessage extends BaseMessage {
} }
public Article removeLastArticle() { public Article removeLastArticle() {
Article article = null;
if (this.articles != null) { if (this.articles != null) {
return this.articles.removeLast(); article = this.articles.removeLast();
} }
return null; return article;
} }
public Article removeFirstArticle() { public Article removeFirstArticle() {
@ -86,6 +81,7 @@ public class ArticleMessage extends BaseMessage {
@Override @Override
public String toXml() { public String toXml() {
this.count = articles.size();
XStream xstream = getXStream(); XStream xstream = getXStream();
xstream.alias("item", Article.class); xstream.alias("item", Article.class);
xstream.aliasField("Title", Article.class, "title"); xstream.aliasField("Title", Article.class, "title");
@ -101,7 +97,7 @@ public class ArticleMessage extends BaseMessage {
sb.append("[ArticleMessage ,toUserName=").append(super.getToUserName()); sb.append("[ArticleMessage ,toUserName=").append(super.getToUserName());
sb.append(" ,fromUserName=").append(super.getFromUserName()); sb.append(" ,fromUserName=").append(super.getFromUserName());
sb.append(" ,msgType=").append(super.getMsgType().name()); sb.append(" ,msgType=").append(super.getMsgType().name());
sb.append(" ,articles=").append(getArticles().toString()); sb.append(" ,articles=").append(this.articles.toString());
sb.append(" ,createTime=").append(super.getCreateTime()); sb.append(" ,createTime=").append(super.getCreateTime());
sb.append(" ,msgId=").append(super.getMsgId()).append("]"); sb.append(" ,msgId=").append(super.getMsgId()).append("]");
return sb.toString(); return sb.toString();

View File

@ -23,8 +23,7 @@ public class ImageMessage extends BaseMessage {
private static final long serialVersionUID = 6998255203997554731L; private static final long serialVersionUID = 6998255203997554731L;
public ImageMessage(BaseMessage inMessage) { public ImageMessage(BaseMessage inMessage) {
super(MessageType.image, inMessage); this(null, inMessage);
super.getMsgType().setMessageClass(ImageMessage.class);
} }
public ImageMessage(String mediaId, BaseMessage inMessage) { public ImageMessage(String mediaId, BaseMessage inMessage) {

View File

@ -5,6 +5,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
/** /**
* 模板消息 * 模板消息
@ -13,7 +14,7 @@ import com.alibaba.fastjson.JSON;
* @author jy * @author jy
* @date 2014年9月29日 * @date 2014年9月29日
* @since JDK 1.7 * @since JDK 1.7
* @see * @see <a href="http://mp.weixin.qq.com/wiki/index.php?title=%E6%A8%A1%E6%9D%BF%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3">模板消息</a>
*/ */
public class TemplateMessage implements Serializable { public class TemplateMessage implements Serializable {
@ -29,11 +30,13 @@ public class TemplateMessage implements Serializable {
this.data.put(key, new Item(value)); this.data.put(key, new Item(value));
} }
public TemplateMessage(String touser, String template_id, String url) { public TemplateMessage(String touser, String template_id, String title,
String url) {
this.touser = touser; this.touser = touser;
this.template_id = template_id; this.template_id = template_id;
this.url = url; this.url = url;
this.data = new HashMap<String, Item>(); this.data = new HashMap<String, Item>();
pushData("first", title);
} }
private static class Item implements Serializable { private static class Item implements Serializable {
@ -111,6 +114,7 @@ public class TemplateMessage implements Serializable {
+ ", data=" + data + "]"; + ", data=" + data + "]";
} }
@JSONField(serialize = false)
public String toJson() { public String toJson() {
return JSON.toJSONString(this); return JSON.toJSONString(this);
} }

View File

@ -24,8 +24,7 @@ public class VoiceMessage extends BaseMessage {
private static final long serialVersionUID = -7944926238652243793L; private static final long serialVersionUID = -7944926238652243793L;
public VoiceMessage(BaseMessage inMessage) { public VoiceMessage(BaseMessage inMessage) {
super(MessageType.voice, inMessage); this(null, inMessage);
super.getMsgType().setMessageClass(VoiceMessage.class);
} }
public VoiceMessage(String mediaId, BaseMessage inMessage) { public VoiceMessage(String mediaId, BaseMessage inMessage) {

View File

@ -1,8 +1,9 @@
package com.foxinmy.weixin4j; package com.foxinmy.weixin4j.spider;
import java.io.Serializable; import java.io.Serializable;
import java.net.URI; import java.net.URI;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -37,11 +38,16 @@ import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.util.IOUtil; import com.foxinmy.weixin4j.util.IOUtil;
import com.foxinmy.weixin4j.util.RandomUtil;
/** /**
* 用于微信公众号绑定(模拟登录|启用开发者模式|修改服务器配置|修改回调地址|创建自定义菜单) * 模拟微信WEB登陆
* *
* @className WeixinBind * <p>
* (模拟登录|启用开发者模式|修改服务器配置|修改回调地址|创建自定义菜单....more)
* </p>
*
* @className WeixinExecutor
* @author jy * @author jy
* @date 2014年8月15日 * @date 2014年8月15日
* @since JDK 1.7 * @since JDK 1.7
@ -53,7 +59,8 @@ public class WeixinExecutor implements Serializable {
private final Logger logger = LoggerFactory.getLogger(getClass()); private final Logger logger = LoggerFactory.getLogger(getClass());
private final static Charset charset = Charset.forName("utf-8"); private final static Charset charset = StandardCharsets.UTF_8;
private final static Map<String, String> accountMap = new HashMap<String, String>() { private final static Map<String, String> accountMap = new HashMap<String, String>() {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -65,6 +72,7 @@ public class WeixinExecutor implements Serializable {
put("微信号", "weixinNo"); put("微信号", "weixinNo");
put("类型", "accountType"); put("类型", "accountType");
put("认证情况", "weixinVerify"); put("认证情况", "weixinVerify");
put("主体信息", "bodyInfo");
put("介绍", "introduce"); put("介绍", "introduce");
put("所在地址", "address"); put("所在地址", "address");
put("二维码", "qrcodeUrl"); put("二维码", "qrcodeUrl");
@ -91,7 +99,8 @@ public class WeixinExecutor implements Serializable {
// 当要求输入验证码时,cookie需带上 // 当要求输入验证码时,cookie需带上
private String sig; private String sig;
public WeixinExecutor(String backurl, String pushurl, String token, String uname, String pwd, String imgcode, String sig) { public WeixinExecutor(String backurl, String pushurl, String token,
String uname, String pwd, String imgcode, String sig) {
this.backurl = backurl; this.backurl = backurl;
this.pushurl = pushurl; this.pushurl = pushurl;
this.token = token; this.token = token;
@ -105,19 +114,31 @@ public class WeixinExecutor implements Serializable {
weixin.put("host", "mp.weixin.qq.com"); weixin.put("host", "mp.weixin.qq.com");
weixin.put("base", "https://mp.weixin.qq.com"); weixin.put("base", "https://mp.weixin.qq.com");
weixin.put("auth", "https://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN"); weixin.put("auth", "https://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN");
weixin.put("call", "https://mp.weixin.qq.com/advanced/callbackprofile?t=ajax-response&token=%s&lang=zh_CN"); weixin.put(
weixin.put("start", "https://mp.weixin.qq.com/misc/skeyform?form=advancedswitchform"); "call",
weixin.put("back", "https://mp.weixin.qq.com/merchant/myservice?action=set_oauth_domain&f=json"); "https://mp.weixin.qq.com/advanced/callbackprofile?t=ajax-response&token=%s&lang=zh_CN");
weixin.put("verifycode", "https://mp.weixin.qq.com/cgi-bin/verifycode?username=" + uname + "&r=%s"); weixin.put("start",
"https://mp.weixin.qq.com/misc/skeyform?form=advancedswitchform");
weixin.put("back",
"https://mp.weixin.qq.com/merchant/myservice?action=set_oauth_domain&f=json");
weixin.put("verifycode",
"https://mp.weixin.qq.com/cgi-bin/verifycode?username=" + uname
+ "&r=%s");
weixin.put("bedeveloper",
"https://mp.weixin.qq.com/advanced/advanced?action=agreement");
List<BasicHeader> headers = new ArrayList<BasicHeader>(); List<BasicHeader> headers = new ArrayList<BasicHeader>();
headers.add(new BasicHeader("Origin", weixin.getString("base"))); headers.add(new BasicHeader("Origin", weixin.getString("base")));
headers.add(new BasicHeader("Connection", "keep-alive")); headers.add(new BasicHeader("Connection", "keep-alive"));
headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36")); headers.add(new BasicHeader(
"User-Agent",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36"));
client = new DefaultHttpClient(); client = new DefaultHttpClient();
client.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY); client.getParams().setParameter(ClientPNames.COOKIE_POLICY,
client.getParams().setBooleanParameter("http.protocol.single-cookie-header", true); CookiePolicy.BROWSER_COMPATIBILITY);
client.getParams().setBooleanParameter(
"http.protocol.single-cookie-header", true);
client.getParams().setParameter(ClientPNames.DEFAULT_HEADERS, headers); client.getParams().setParameter(ClientPNames.DEFAULT_HEADERS, headers);
host = new HttpHost(weixin.getString("host"), -1, "https"); host = new HttpHost(weixin.getString("host"), -1, "https");
@ -158,7 +179,8 @@ public class WeixinExecutor implements Serializable {
try { try {
List<NameValuePair> parameters = new ArrayList<NameValuePair>(); List<NameValuePair> parameters = new ArrayList<NameValuePair>();
parameters.add(new BasicNameValuePair("username", uname)); parameters.add(new BasicNameValuePair("username", uname));
parameters.add(new BasicNameValuePair("pwd", DigestUtils.md5Hex(pwd.getBytes()))); parameters.add(new BasicNameValuePair("pwd", DigestUtils.md5Hex(pwd
.getBytes())));
parameters.add(new BasicNameValuePair("f", "json")); parameters.add(new BasicNameValuePair("f", "json"));
parameters.add(new BasicNameValuePair("imgcode", imgcode)); parameters.add(new BasicNameValuePair("imgcode", imgcode));
if (!StringUtil.isBlank(imgcode)) { if (!StringUtil.isBlank(imgcode)) {
@ -169,15 +191,18 @@ public class WeixinExecutor implements Serializable {
HttpResponse response = client.execute(host, method); HttpResponse response = client.execute(host, method);
HttpEntity entity = response.getEntity(); HttpEntity entity = response.getEntity();
Document root = Jsoup.parse(entity.getContent(), charset.name(), weixin.getString("base")); Document root = Jsoup.parse(entity.getContent(), charset.name(),
weixin.getString("base"));
StatusLine line = response.getStatusLine(); StatusLine line = response.getStatusLine();
logger.info("step1_login--->status={},body=\n{}", line, root.toString()); logger.info("step1_login--->status={},body=\n{}", line,
root.toString());
if (line.getStatusCode() == HttpStatus.SC_OK) { if (line.getStatusCode() == HttpStatus.SC_OK) {
JSONObject body = JSON.parseObject(root.body().text()); JSONObject body = JSON.parseObject(root.body().text());
String msg = ""; String msg = "";
int code = 0; int code = 0;
switch (body.getJSONObject("base_resp").getIntValue("ret")) { switch (body.getIntValue("ret")
+ body.getJSONObject("base_resp").getIntValue("ret")) {
case -1: case -1:
msg = "系统错误,请稍候再试。"; msg = "系统错误,请稍候再试。";
code = -1; code = -1;
@ -223,20 +248,32 @@ public class WeixinExecutor implements Serializable {
break; break;
} }
if (code == 0) { if (code == 0) {
weixin.put("urlToken", getQueryMap(body.getString("redirect_url")).get("token")); weixin.put(
weixin.put("indexUrl", String.format("%s%s", weixin.getString("base"), body.getString("redirect_url"))); "urlToken",
getQueryMap(body.getString("redirect_url")).get(
"token"));
weixin.put("indexUrl", String.format("%s%s",
weixin.getString("base"),
body.getString("redirect_url")));
weixin.put("step", "1"); weixin.put("step", "1");
} else { } else {
if (code == 104 || code == 105) { if (code == 104 || code == 105) {
// 下载验证码 // 下载验证码
HttpGet get = new HttpGet(String.format(weixin.getString("verifycode"), System.currentTimeMillis())); HttpGet get = new HttpGet(String.format(
weixin.getString("verifycode"),
System.currentTimeMillis()));
get.setHeaders(method.getAllHeaders()); get.setHeaders(method.getAllHeaders());
response = client.execute(host, get); response = client.execute(host, get);
StringBuffer base64 = new StringBuffer(); StringBuffer base64 = new StringBuffer();
base64.append("data:").append(response.getFirstHeader("Content-Type").getValue()).append(";base64,"); base64.append("data:")
base64.append(new String(Base64.encodeBase64(IOUtil.toByteArray(response.getEntity().getContent())), charset)); .append(response.getFirstHeader("Content-Type")
.getValue()).append(";base64,");
base64.append(new String(
Base64.encodeBase64(IOUtil.toByteArray(response
.getEntity().getContent())), charset));
weixin.put("verifydata", base64.toString()); weixin.put("verifydata", base64.toString());
List<Cookie> cookieList = client.getCookieStore().getCookies(); List<Cookie> cookieList = client.getCookieStore()
.getCookies();
for (Cookie cookie : cookieList) { for (Cookie cookie : cookieList) {
if (cookie.getName().equals("sig")) { if (cookie.getName().equals("sig")) {
weixin.put("sig", cookie.getValue()); weixin.put("sig", cookie.getValue());
@ -274,38 +311,46 @@ public class WeixinExecutor implements Serializable {
HttpResponse response = client.execute(host, method); HttpResponse response = client.execute(host, method);
HttpEntity entity = response.getEntity(); HttpEntity entity = response.getEntity();
Document root = Jsoup.parse(entity.getContent(), charset.name(), weixin.getString("base")); Document root = Jsoup.parse(entity.getContent(), charset.name(),
weixin.getString("base"));
StatusLine line = response.getStatusLine(); StatusLine line = response.getStatusLine();
logger.info("step2_setting--->status={},body=\n{}", line, root.toString()); logger.info("step2_setting--->status={},body=\n{}", line,
root.toString());
if (line.getStatusCode() == HttpStatus.SC_OK) { if (line.getStatusCode() == HttpStatus.SC_OK) {
Element ele = root.getElementById("menuBar").getElementsByTag("dl").last(); Element ele = root.getElementById("menuBar")
.getElementsByTag("dl").last();
url = ele.getElementsByTag("a").last().absUrl("href"); url = ele.getElementsByTag("a").last().absUrl("href");
weixin.put("developerUrl", url); weixin.put("developerUrl", url);
method.addHeader("Referer", url); method.addHeader("Referer", url);
url = ele.previousElementSibling().getElementsByTag("a").first().absUrl("href"); url = ele.previousElementSibling().getElementsByTag("a")
.first().absUrl("href");
weixin.put("settingUrl", url); weixin.put("settingUrl", url);
method.setURI(URI.create(url)); method.setURI(URI.create(url));
response = client.execute(host, method); response = client.execute(host, method);
entity = response.getEntity(); entity = response.getEntity();
root = Jsoup.parse(entity.getContent(), charset.name(), weixin.getString("base")); root = Jsoup.parse(entity.getContent(), charset.name(),
weixin.getString("base"));
line = response.getStatusLine(); line = response.getStatusLine();
weixin.put("step", "2-1"); weixin.put("step", "2-1");
// 公众号配置页面 // 公众号配置页面
if (line.getStatusCode() == HttpStatus.SC_OK) { if (line.getStatusCode() == HttpStatus.SC_OK) {
Elements eles = root.getElementById("settingArea").getElementsByTag("li"); Elements eles = root.getElementById("settingArea")
.getElementsByTag("li");
String key, value; String key, value;
for (Element element : eles) { for (Element element : eles) {
key = element.getElementsByTag("h4").first().text(); key = element.getElementsByTag("h4").first().text();
ele = element.getElementsByClass("meta_content").first(); ele = element.getElementsByClass("meta_content")
.first();
if (ele.children().isEmpty()) { if (ele.children().isEmpty()) {
value = ele.text(); value = ele.text();
} else { } else {
if (ele.child(0).tagName().equalsIgnoreCase("a")) { if (ele.child(0).tagName().equalsIgnoreCase("a")) {
value = ele.child(0).absUrl("href"); value = ele.child(0).absUrl("href");
} else if (ele.child(0).tagName().equalsIgnoreCase("img")) { } else if (ele.child(0).tagName()
.equalsIgnoreCase("img")) {
value = ele.child(0).absUrl("src"); value = ele.child(0).absUrl("src");
} else { } else {
value = ele.text(); value = ele.text();
@ -313,14 +358,18 @@ public class WeixinExecutor implements Serializable {
} }
weixin.put(accountMap.get(key), value); weixin.put(accountMap.get(key), value);
} }
weixin.put("isVerify", weixin.getString("weixinVerify").contains("微信认证")); weixin.put("isVerify", weixin.getString("weixinVerify")
weixin.put("isService", weixin.getString("accountType").contains("服务号")); .contains("微信认证"));
weixin.put("isSubscribe", weixin.getString("accountType").contains("订阅号")); weixin.put("isService", weixin.getString("accountType")
.contains("服务号"));
weixin.put("isSubscribe", weixin.getString("accountType")
.contains("订阅号"));
value = weixin.getString("qrcodeUrl"); value = weixin.getString("qrcodeUrl");
method.setURI(URI.create(value)); method.setURI(URI.create(value));
response = client.execute(host, method); response = client.execute(host, method);
weixin.put("qrcodeData", IOUtil.toByteArray(response.getEntity().getContent())); weixin.put("qrcodeData", IOUtil.toByteArray(response
.getEntity().getContent()));
weixin.put("step", "2-2"); weixin.put("step", "2-2");
// 开发者页面 // 开发者页面
@ -329,26 +378,83 @@ public class WeixinExecutor implements Serializable {
response = client.execute(host, method); response = client.execute(host, method);
entity = response.getEntity(); entity = response.getEntity();
root = Jsoup.parse(entity.getContent(), charset.name(), weixin.getString("base")); root = Jsoup.parse(entity.getContent(), charset.name(),
weixin.getString("base"));
line = response.getStatusLine(); line = response.getStatusLine();
if (line.getStatusCode() == HttpStatus.SC_OK) { if (line.getStatusCode() == HttpStatus.SC_OK) {
// 还没有成为开发者 2014.10-06 jy.hu
// 触发成为开发者动作
ele = root.getElementById("js_toBeDeveloper");
if (ele != null && ele.hasText()) {
HttpPost post = new HttpPost(URI.create(weixin
.getString("bedeveloper")));
post.addHeader("Referer", url);
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
parameters = new ArrayList<NameValuePair>();
parameters.add(new BasicNameValuePair("token",
weixin.getString("urlToken")));
parameters.add(new BasicNameValuePair("f", "json"));
parameters.add(new BasicNameValuePair("ajax", "1"));
parameters.add(new BasicNameValuePair("lang",
"zh_CN"));
parameters.add(new BasicNameValuePair("random",
System.currentTimeMillis() + ""));
post.setEntity(new UrlEncodedFormEntity(parameters,
charset));
response = client.execute(host, post);
entity = response.getEntity();
root = Jsoup.parse(entity.getContent(),
charset.name(), weixin.getString("base"));
line = response.getStatusLine();
logger.info(
"step2_bedeveloper--->status={},body=\n{}",
line, root.toString());
if (line.getStatusCode() == HttpStatus.SC_OK) {
JSONObject body = JSON.parseObject(root.body()
.text());
if (body.getIntValue("ret") == 0) {
method.addHeader("Referer", url);
method.setURI(URI.create(weixin
.getString("developerUrl")));
response = client.execute(host, method);
entity = response.getEntity();
root = Jsoup.parse(entity.getContent(),
charset.name(),
weixin.getString("base"));
} else {
weixin.put("code", "-100");
weixin.put("msg", "成为开发者失败!");
return;
}
}
}
// 初始化状态 // 初始化状态
// 配置未启用状态 // 配置未启用状态
// 配置已启用状态 // 配置已启用状态
eles = root.getElementsByClass("developer_info_opr"); eles = root.getElementsByClass("developer_info_opr");
if (eles != null && eles.hasText()) { if (eles != null && eles.hasText()) {
weixin.put("developerModifyUrl", eles.first().children().last().absUrl("href")); weixin.put("developerModifyUrl", eles.first()
weixin.put("status", eles.first().children().first().text().contains("启用") ? "READY" : "RUNNING"); .children().first().absUrl("href"));
weixin.put("status",
eles.text().contains("启用") ? "READY"
: "RUNNING");
} else { } else {
weixin.put("status", "INIT"); weixin.put("status", "INIT");
} }
// appid&appsecret // appid&appsecret
if (weixin.getBooleanValue("isService") || (weixin.getBooleanValue("isSubscribe") && weixin.getBooleanValue("isVerify"))) { if (weixin.getBooleanValue("isService")
eles = root.getElementsByClass("developer_info_item").first().children().last().getElementsByClass("frm_controls"); || (weixin.getBooleanValue("isSubscribe") && weixin
.getBooleanValue("isVerify"))) {
eles = root
.getElementsByClass("developer_info_item")
.first().children().last()
.getElementsByClass("frm_controls");
weixin.put("appId", eles.first().text()); weixin.put("appId", eles.first().text());
weixin.put("appSecret", eles.last().text().replace("重置", "").trim()); weixin.put("appSecret",
eles.last().text().replace("重置", "").trim());
} }
weixin.put("step", "2-3"); weixin.put("step", "2-3");
} }
@ -376,24 +482,35 @@ public class WeixinExecutor implements Serializable {
* step3:填写配置 * step3:填写配置
*/ */
private void step3_setting() { private void step3_setting() {
HttpPost method = new HttpPost(String.format(weixin.getString("call"), weixin.getString("urlToken"))); HttpPost method = new HttpPost(String.format(weixin.getString("call"),
weixin.getString("urlToken")));
try { try {
List<NameValuePair> parameters = new ArrayList<NameValuePair>(); List<NameValuePair> parameters = new ArrayList<NameValuePair>();
parameters.add(new BasicNameValuePair("url", pushurl)); parameters.add(new BasicNameValuePair("url", pushurl));
parameters.add(new BasicNameValuePair("callback_token", token)); parameters.add(new BasicNameValuePair("callback_token", token));
// EncodingAESKey | 消息加解密方式(明文0,兼容1,安全2)
parameters.add(new BasicNameValuePair("encoding_aeskey", RandomUtil
.generateString(43)));
parameters
.add(new BasicNameValuePair("callback_encrypt_mode", "0"));
parameters.add(new BasicNameValuePair("operation_seq", RandomUtil
.generateStringByNumberChar(9)));
method.setEntity(new UrlEncodedFormEntity(parameters, charset)); method.setEntity(new UrlEncodedFormEntity(parameters, charset));
method.addHeader("Referer", weixin.getString("developerModifyUrl")); method.addHeader("Referer", weixin.getString("developerModifyUrl"));
HttpResponse response = client.execute(host, method); HttpResponse response = client.execute(host, method);
HttpEntity entity = response.getEntity(); HttpEntity entity = response.getEntity();
Document root = Jsoup.parse(entity.getContent(), charset.name(), weixin.getString("base")); Document root = Jsoup.parse(entity.getContent(), charset.name(),
weixin.getString("base"));
StatusLine line = response.getStatusLine(); StatusLine line = response.getStatusLine();
logger.info("step3_setting--->status={},body=\n{}", line, root.toString()); logger.info("step3_setting--->status={},body=\n{}", line,
root.toString());
if (line.getStatusCode() == HttpStatus.SC_OK) { if (line.getStatusCode() == HttpStatus.SC_OK) {
JSONObject body = JSON.parseObject(root.body().text()); JSONObject body = JSON.parseObject(root.body().text());
String msg = ""; String msg = "";
int code = 0; int code = 0;
switch (body.getIntValue("ret")) { switch (body.getIntValue("ret")
+ body.getJSONObject("base_resp").getIntValue("ret")) {
case -201: case -201:
msg = "无效的URL"; msg = "无效的URL";
code = 200; code = 200;
@ -437,25 +554,32 @@ public class WeixinExecutor implements Serializable {
// 触发启用按钮 // 触发启用按钮
if (!weixin.getString("status").equals("RUNNING")) { if (!weixin.getString("status").equals("RUNNING")) {
parameters = new ArrayList<NameValuePair>(); parameters = new ArrayList<NameValuePair>();
parameters.add(new BasicNameValuePair("token", weixin.getString("urlToken"))); parameters.add(new BasicNameValuePair("token", weixin
.getString("urlToken")));
parameters.add(new BasicNameValuePair("f", "json")); parameters.add(new BasicNameValuePair("f", "json"));
parameters.add(new BasicNameValuePair("ajax", "1")); parameters.add(new BasicNameValuePair("ajax", "1"));
parameters.add(new BasicNameValuePair("flag", "1")); parameters.add(new BasicNameValuePair("flag", "1"));
parameters.add(new BasicNameValuePair("type", "2")); parameters.add(new BasicNameValuePair("type", "2"));
parameters.add(new BasicNameValuePair("lang", "zh_CN")); parameters.add(new BasicNameValuePair("lang", "zh_CN"));
parameters.add(new BasicNameValuePair("random", System.currentTimeMillis() + "")); parameters.add(new BasicNameValuePair("random", System
.currentTimeMillis() + ""));
method.setEntity(new UrlEncodedFormEntity(parameters, charset)); method.setEntity(new UrlEncodedFormEntity(parameters,
charset));
method.setURI(URI.create(weixin.getString("start"))); method.setURI(URI.create(weixin.getString("start")));
response = client.execute(host, method); response = client.execute(host, method);
entity = response.getEntity(); entity = response.getEntity();
root = Jsoup.parse(entity.getContent(), charset.name(), weixin.getString("base")); root = Jsoup.parse(entity.getContent(), charset.name(),
weixin.getString("base"));
line = response.getStatusLine(); line = response.getStatusLine();
logger.info("step3_setting--->status={},body=\n{}", line, root.toString()); logger.info("step3_setting--->status={},body=\n{}",
line, root.toString());
if (line.getStatusCode() == HttpStatus.SC_OK) { if (line.getStatusCode() == HttpStatus.SC_OK) {
body = JSON.parseObject(root.body().text()); body = JSON.parseObject(root.body().text());
if (body.getIntValue("ret") != 0 || body.getJSONObject("base_resp").getIntValue("ret") != 0) { if (body.getIntValue("ret")
+ body.getJSONObject("base_resp")
.getIntValue("ret") != 0) {
weixin.put("code", 300); weixin.put("code", 300);
weixin.put("msg", "启用开发者模式失败,请稍后再试!"); weixin.put("msg", "启用开发者模式失败,请稍后再试!");
} }
@ -492,23 +616,29 @@ public class WeixinExecutor implements Serializable {
List<NameValuePair> parameters = new ArrayList<NameValuePair>(); List<NameValuePair> parameters = new ArrayList<NameValuePair>();
parameters.add(new BasicNameValuePair("domain", backurl)); parameters.add(new BasicNameValuePair("domain", backurl));
parameters.add(new BasicNameValuePair("token", weixin.getString("urlToken"))); parameters.add(new BasicNameValuePair("token", weixin
.getString("urlToken")));
parameters.add(new BasicNameValuePair("f", "json")); parameters.add(new BasicNameValuePair("f", "json"));
parameters.add(new BasicNameValuePair("ajax", "1")); parameters.add(new BasicNameValuePair("ajax", "1"));
parameters.add(new BasicNameValuePair("flag", "1")); parameters.add(new BasicNameValuePair("flag", "1"));
parameters.add(new BasicNameValuePair("lang", "zh_CN")); parameters.add(new BasicNameValuePair("lang", "zh_CN"));
parameters.add(new BasicNameValuePair("random", System.currentTimeMillis() + "")); parameters.add(new BasicNameValuePair("random", System
.currentTimeMillis() + ""));
method.setEntity(new UrlEncodedFormEntity(parameters, charset)); method.setEntity(new UrlEncodedFormEntity(parameters, charset));
method.addHeader("Referer", weixin.getString("developerUrl")); method.addHeader("Referer", weixin.getString("developerUrl"));
HttpResponse response = client.execute(host, method); HttpResponse response = client.execute(host, method);
HttpEntity entity = response.getEntity(); HttpEntity entity = response.getEntity();
Document root = Jsoup.parse(entity.getContent(), charset.name(), weixin.getString("base")); Document root = Jsoup.parse(entity.getContent(),
charset.name(), weixin.getString("base"));
StatusLine line = response.getStatusLine(); StatusLine line = response.getStatusLine();
logger.info("step4_back--->status={},body=\n{}", line, root.toString()); logger.info("step4_back--->status={},body=\n{}", line,
root.toString());
if (line.getStatusCode() == HttpStatus.SC_OK) { if (line.getStatusCode() == HttpStatus.SC_OK) {
JSONObject body = JSON.parseObject(root.body().text()); JSONObject body = JSON.parseObject(root.body().text());
if (body.getIntValue("ret") != 0 || body.getJSONObject("base_resp").getIntValue("ret") != 0) { if (body.getIntValue("ret")
+ body.getJSONObject("base_resp")
.getIntValue("ret") != 0) {
weixin.put("code", "400"); weixin.put("code", "400");
weixin.put("msg", "修改授权回调地址失败!"); weixin.put("msg", "修改授权回调地址失败!");
} }

View File

@ -27,7 +27,9 @@ public enum MessageType {
EventMessage.class), EventMessage.class),
// 发送的消息类型 // 发送的消息类型
music(MusicMessage.class), news(ArticleMessage.class), transfer_customer_service( music(MusicMessage.class), news(ArticleMessage.class), transfer_customer_service(
TransferMessage.class); TransferMessage.class),
// 微信消息认证
signature(null);
private Class<? extends BaseMessage> messageClass; private Class<? extends BaseMessage> messageClass;
MessageType(Class<? extends BaseMessage> messageClass) { MessageType(Class<? extends BaseMessage> messageClass) {

View File

@ -18,12 +18,15 @@ import com.foxinmy.weixin4j.type.MessageType;
import com.foxinmy.weixin4j.xml.XStream; import com.foxinmy.weixin4j.xml.XStream;
public class MessageUtil { public class MessageUtil {
private final static Logger log = LoggerFactory.getLogger(MessageUtil.class); private final static Logger log = LoggerFactory
.getLogger(MessageUtil.class);
/** /**
* 验证微信签名 * 验证微信签名
* *
* @param token
* 开发者填写的token
* @param echostr * @param echostr
* 随机字符串 * 随机字符串
* @param timestamp * @param timestamp
@ -37,19 +40,20 @@ public class MessageUtil {
* @see <a * @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97">接入指南</a> * href="http://mp.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97">接入指南</a>
*/ */
public static String signature(String echostr, String timestamp, String nonce, String signature) { public static String signature(String token, String echostr,
String app_token = ConfigUtil.getValue("app_token"); String timestamp, String nonce, String signature) {
if (StringUtil.isBlank(app_token)) { if (StringUtil.isBlank(token)) {
log.error("signature fail : token is null!"); log.error("signature fail : token is null!");
return null; return null;
} }
if (StringUtil.isBlank(echostr) || StringUtil.isBlank(timestamp) || StringUtil.isBlank(nonce)) { if (StringUtil.isBlank(echostr) || StringUtil.isBlank(timestamp)
|| StringUtil.isBlank(nonce)) {
log.error("signature fail : invalid parameter!"); log.error("signature fail : invalid parameter!");
return null; return null;
} }
String _signature = null; String _signature = null;
try { try {
String[] a = { app_token, timestamp, nonce }; String[] a = { token, timestamp, nonce };
Arrays.sort(a); Arrays.sort(a);
StringBuilder sb = new StringBuilder(3); StringBuilder sb = new StringBuilder(3);
for (String str : a) { for (String str : a) {
@ -67,13 +71,27 @@ public class MessageUtil {
} }
} }
/**
* 获取对应的mapping key
* @param xmlMsg
* @return
* @throws DocumentException
* @see com.foxinmy.weixin4j.server.WeixinActionMapping
*/
public static String getMappingKey(String xmlMsg) throws DocumentException {
Document doc = DocumentHelper.parseText(xmlMsg);
String msgType = doc.selectSingleNode("/xml/MsgType").getStringValue();
if (msgType.equalsIgnoreCase(MessageType.event.name())) {
msgType += "_"
+ doc.selectSingleNode("/xml/Event").getStringValue();
}
return msgType;
}
/** /**
* xml消息转换为消息对象 * xml消息转换为消息对象
* <p>
* 微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次
* </p>
* *
* @param xml * @param xmlMsg
* 消息字符串 * 消息字符串
* @return 消息对象 * @return 消息对象
* @throws DocumentException * @throws DocumentException
@ -96,26 +114,26 @@ public class MessageUtil {
* @see com.foxinmy.weixin4j.msg.event.LocationEventMessage * @see com.foxinmy.weixin4j.msg.event.LocationEventMessage
* @see com.foxinmy.weixin4j.msg.event.menu.MenuEventMessage * @see com.foxinmy.weixin4j.msg.event.menu.MenuEventMessage
*/ */
public static BaseMessage xml2msg(String xml) throws DocumentException { public static BaseMessage xml2msg(String xmlMsg) throws DocumentException {
if (StringUtil.isBlank(xml)) Document doc = DocumentHelper.parseText(xmlMsg);
return null;
Document doc = DocumentHelper.parseText(xml);
String type = doc.selectSingleNode("/xml/MsgType").getStringValue(); String type = doc.selectSingleNode("/xml/MsgType").getStringValue();
if (StringUtil.isBlank(type)) { if (StringUtil.isBlank(type)) {
return null; return null;
} }
XStream xstream = new XStream();
MessageType messageType = MessageType.valueOf(type.toLowerCase()); MessageType messageType = MessageType.valueOf(type.toLowerCase());
Class<? extends BaseMessage> messageClass = messageType.getMessageClass(); Class<? extends BaseMessage> messageClass = messageType
.getMessageClass();
if (messageType == MessageType.event) { if (messageType == MessageType.event) {
type = doc.selectSingleNode("/xml/Event").getStringValue(); type = doc.selectSingleNode("/xml/Event").getStringValue();
messageClass = EventType.valueOf(type.toLowerCase()).getEventClass(); messageClass = EventType.valueOf(type.toLowerCase())
.getEventClass();
} }
xstream.alias("xml", messageClass); XStream xstream = new XStream();
xstream.ignoreUnknownElements(); xstream.ignoreUnknownElements();
xstream.autodetectAnnotations(true); xstream.autodetectAnnotations(true);
xstream.processAnnotations(messageClass); xstream.processAnnotations(messageClass);
return xstream.fromXML(doc.asXML(), messageClass); xstream.alias("xml", messageClass);
return xstream.fromXML(xmlMsg, messageClass);
} }
/** /**
@ -125,9 +143,10 @@ public class MessageUtil {
* 带消息字符串的输入流 * 带消息字符串的输入流
* @return 消息对象 * @return 消息对象
* @throws DocumentException * @throws DocumentException
* @see {@link com.foxinmy.weixin4j.WeixinProxy#xml2msg(String)} * @see {@link com.foxinmy.weixin4j.util.MessageUtil#xml2msg(String)}
*/ */
public static BaseMessage xml2msg(InputStream inputStream) throws DocumentException { public static BaseMessage xml2msg(InputStream inputStream)
throws DocumentException {
SAXReader reader = new SAXReader(); SAXReader reader = new SAXReader();
Document doc = reader.read(inputStream); Document doc = reader.read(inputStream);
return xml2msg(doc.asXML()); return xml2msg(doc.asXML());

View File

@ -25,12 +25,11 @@
<!--for further documentation --> <!--for further documentation -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/tmp/weixin/log/%d{yyyy-MM-dd}.log <fileNamePattern>/tmp/weixin/weixin.%d{yyyy-MM-dd}.log
</fileNamePattern> </fileNamePattern>
<maxHistory>30</maxHistory> <maxHistory>30</maxHistory>
</rollingPolicy> </rollingPolicy>
<encoder> <encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern> </pattern>
@ -55,7 +54,7 @@
<appender-ref ref="stdout" /> <appender-ref ref="stdout" />
</logger> </logger>
<logger name="com.foxinmy.weixin" level="INFO"> <logger name="com.foxinmy.weixin4j" level="INFO">
<appender-ref ref="async" /> <appender-ref ref="async" />
</logger> </logger>

View File

@ -1,71 +0,0 @@
package com.foxinmy.weixin4j.test;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import com.foxinmy.weixin4j.WeixinProxy;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Button;
import com.foxinmy.weixin4j.type.ButtonType;
/**
* 自定义菜单测试
* @className ButtonTest
* @author jy.hu
* @date 2014年4月10日
* @since JDK 1.7
*/
public class ButtonTest {
private WeixinProxy weixinProxy;
@Before
public void init() {
weixinProxy = new WeixinProxy();
}
@Test
public void create() {
List<Button> btnList = new ArrayList<Button>();
Button b = new Button("test");
b.setType(ButtonType.click);
b.setKey("123");
btnList.add(b);
b = new Button("news","http://xxx");
btnList.add(b);
try {
weixinProxy.createMenu(btnList);
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
}
@Test
public void get() {
try {
List<Button> btnList = weixinProxy.getMenu();
for (Button btn : btnList) {
System.out.println(btn.toString());
}
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
}
@Test
public void delete() {
try {
weixinProxy.deleteMenu();
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
}
}

View File

@ -2,77 +2,62 @@ package com.foxinmy.weixin4j.test;
import java.util.List; import java.util.List;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import com.foxinmy.weixin4j.WeixinProxy; import com.foxinmy.weixin4j.api.GroupApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.model.Group; import com.foxinmy.weixin4j.model.Group;
/** /**
* 用户分组测试 * 用户分组测试
*
* @className GroupTest * @className GroupTest
* @author jy.hu * @author jy.hu
* @date 2014年4月10日 * @date 2014年4月10日
* @since JDK 1.7 * @since JDK 1.7
*/ */
public class GroupTest { public class GroupTest extends TokenTest {
private WeixinProxy weixinProxy; private GroupApi groupApi;
@Before @Before
public void init() { public void init() {
weixinProxy = new WeixinProxy(); groupApi = new GroupApi(tokenApi);
} }
@Test @Test
public void create() { public void create() throws WeixinException {
try { Group group = groupApi.createGroup("my");
System.out.println(weixinProxy.createGroup("test")); Assert.assertNotNull(group);
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
} }
@Test @Test
public void get() { public void get() throws WeixinException {
try { List<Group> groups = groupApi.getGroups();
List<Group> groups = weixinProxy.getGroups(); for (Group group : groups) {
for (Group group : groups) { System.out.println(group);
System.out.println(group);
}
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
} }
Assert.assertEquals(1, groups.size());
} }
@Test @Test
public void getid() { public void getid() throws WeixinException {
try { int gid = groupApi.getGroupByOpenId("owGBft_vbBbOaQOmpEUE4xDLeRSU");
System.out.println(weixinProxy.getGroupByOpenId("owGBft_vbBbOaQOmpEUE4xDLeRSU")); Assert.assertTrue(gid >= 0);
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
} }
@Test @Test
public void modify() { public void modify() throws WeixinException {
try { BaseResult result = groupApi.modifyGroup(100, "my1");
weixinProxy.modifyGroup(100, "test1"); Assert.assertEquals(0, result.getErrcode());
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
} }
@Test @Test
public void move() { public void move() throws WeixinException {
try { BaseResult result = groupApi.moveGroup("owGBft_vbBbOaQOmpEUE4xDLeRSU",
weixinProxy.moveGroup("owGBft_vbBbOaQOmpEUE4xDLeRSU",100); 100);
} catch (WeixinException e) { Assert.assertEquals(0, result.getErrcode());
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
} }
} }

View File

@ -1,22 +0,0 @@
package com.foxinmy.weixin4j.test;
import org.junit.Test;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.HttpRequest;
public class HttpTest {
private static HttpRequest request;
static {
request = new HttpRequest();
}
@Test
public void test(){
try {
System.out.println(request.get("http://www.baidu.com"));
} catch (WeixinException e) {
e.printStackTrace();
}
}
}

View File

@ -1,48 +1,48 @@
package com.foxinmy.weixin4j.test; package com.foxinmy.weixin4j.test;
import java.io.File; import java.io.File;
import java.io.IOException;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import com.foxinmy.weixin4j.WeixinProxy; import com.foxinmy.weixin4j.api.MediaApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.type.MediaType; import com.foxinmy.weixin4j.type.MediaType;
/** /**
* 媒体上传下载测试 * 媒体上传下载测试
*
* @className MediaTest * @className MediaTest
* @author jy.hu * @author jy.hu
* @date 2014年4月10日 * @date 2014年4月10日
* @since JDK 1.7 * @since JDK 1.7
* @see * @see
*/ */
public class MediaTest { public class MediaTest extends TokenTest {
private WeixinProxy weixinProxy; private MediaApi mediaApi;
@Before @Before
public void init() { public void init() {
weixinProxy = new WeixinProxy(); mediaApi = new MediaApi(tokenApi);
} }
@Test @Test
public void upload() { public void upload() throws IOException, WeixinException {
File file = new File("D:\\test.jpg"); File file = new File("/tmp/test.jpg");
try { String mediaId = mediaApi.uploadMedia(file, MediaType.image);
System.out.println(weixinProxy.uploadMedia(file, MediaType.image)); // vvU_AUtovWyfAxQ8J1DsCoNMtK6U_bUmTpe6lpINUOVRLvt_7rtO4zxzBpPgkmay
//vvU_AUtovWyfAxQ8J1DsCoNMtK6U_bUmTpe6lpINUOVRLvt_7rtO4zxzBpPgkmay Assert.assertNotNull(mediaId);
} catch (WeixinException e) {
System.out.println(e.getErrorMsg());
}
} }
@Test @Test
public void download() { public void download() throws WeixinException, IOException {
try { File file = mediaApi
System.out.println(weixinProxy.downloadMedia("vvU_AUtovWyfAxQ8J1DsCoNMtK6U_bUmTpe6lpINUOVRLvt_7rtO4zxzBpPgkmay", MediaType.image)); .downloadMedia(
} catch (WeixinException e) { "vvU_AUtovWyfAxQ8J1DsCoNMtK6U_bUmTpe6lpINUOVRLvt_7rtO4zxzBpPgkmay",
System.out.println(e.getErrorMsg()); MediaType.image);
} Assert.assertTrue(file.exists());
} }
} }

View File

@ -0,0 +1,64 @@
package com.foxinmy.weixin4j.test;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.foxinmy.weixin4j.api.MenuApi;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.model.Button;
import com.foxinmy.weixin4j.type.ButtonType;
/**
* 自定义菜单测试
*
* @className MenuTest
* @author jy.hu
* @date 2014年4月10日
* @since JDK 1.7
*/
public class MenuTest extends TokenTest {
private MenuApi menuApi;
private List<Button> btnList;
@Before
public void init() {
menuApi = new MenuApi(tokenApi);
}
@Test
public void create() throws WeixinException {
btnList = new ArrayList<Button>();
Button b = new Button("click");
b.setType(ButtonType.click);
b.setKey("click");
btnList.add(b);
b = new Button("qq", "http://www.qq.com");
btnList.add(b);
BaseResult result = menuApi.createMenu(btnList);
Assert.assertEquals(0, result.getErrcode());
}
@Test
public void get() throws WeixinException {
btnList = menuApi.getMenu();
for (Button btn : btnList) {
System.out.println(btn);
}
Assert.assertEquals(1, btnList.size());
}
@Test
public void delete() throws WeixinException {
BaseResult result = menuApi.deleteMenu();
Assert.assertEquals(0, result.getErrcode());
}
}

View File

@ -1,194 +0,0 @@
package com.foxinmy.weixin4j.test;
import org.junit.Test;
import com.foxinmy.weixin4j.util.MessageUtil;
/**
* 接收事件消息格式测试
*
* @author jy.hu
* @date 2014年3月24日
* @since JDK 1.7
*/
public class MessageEventInTest {
private StringBuilder xmlSb = new StringBuilder();
/***************** event message *********************/
@Test
public void scribe() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[subscribe]]></Event>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void scan() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[SCAN]]></Event>");
xmlSb.append("<EventKey><![CDATA[SCENE_VALUE]]></EventKey>");
xmlSb.append("<Ticket><![CDATA[TICKET]]></Ticket>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void scan_scribe() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml><ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[subscribe]]></Event>");
xmlSb.append("<EventKey><![CDATA[qrscene_123123]]></EventKey>");
xmlSb.append("<Ticket><![CDATA[TICKET]]></Ticket>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void location1() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[fromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[LOCATION]]></Event>");
xmlSb.append("<Latitude>23.137466</Latitude>");
xmlSb.append("<Longitude>113.352425</Longitude>");
xmlSb.append("<Precision>119.385040</Precision>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void menu_click() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[CLICK]]></Event>");
xmlSb.append("<EventKey><![CDATA[EVENTKEY]]></EventKey>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void menu_link() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[VIEW]]></Event>");
xmlSb.append("<EventKey><![CDATA[www.qq.com]]></EventKey>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void menu_scan() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[scancode_waitmsg]]></Event>");
xmlSb.append("<EventKey><![CDATA[www.qq.com]]></EventKey>");
xmlSb.append("<ScanCodeInfo><ScanType><![CDATA[qrcode]]></ScanType>");
xmlSb.append("<ScanResult><![CDATA[1]]></ScanResult>");
xmlSb.append("</ScanCodeInfo>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void menu_photo() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[pic_weixin]]></Event>");
xmlSb.append("<EventKey><![CDATA[www.qq.com]]></EventKey>");
xmlSb.append("<SendPicsInfo><Count>1</Count>");
xmlSb.append("<PicList><item><PicMd5Sum><![CDATA[1b5f7c23b5bf75682a53e7b6d163e185]]></PicMd5Sum>");
xmlSb.append("</item></PicList></SendPicsInfo>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void menu_location() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[location_select]]></Event>");
xmlSb.append("<EventKey><![CDATA[www.qq.com]]></EventKey>");
xmlSb.append("<SendLocationInfo><Location_X><![CDATA[23]]></Location_X>");
xmlSb.append("<Location_Y><![CDATA[113]]></Location_Y>");
xmlSb.append("<Scale><![CDATA[15]]></Scale>");
xmlSb.append("<Label><![CDATA[ 广州市海珠区客村艺苑路 106号]]></Label>");
xmlSb.append("<Poiname><![CDATA[]]></Poiname></SendLocationInfo>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -1,155 +0,0 @@
package com.foxinmy.weixin4j.test;
import org.junit.Test;
import com.foxinmy.weixin4j.util.MessageUtil;
/**
* 接受一般消息格式测试
*
* @author jy.hu
* @date 2014年3月24日
* @since JDK 1.7
*/
public class MessageInTest {
private StringBuilder xmlSb = new StringBuilder();
/***************** common message *********************/
@Test
public void text() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[fromUser]]></FromUserName>");
xmlSb.append("<CreateTime>1348831860</CreateTime>");
xmlSb.append("<MsgType><![CDATA[text]]></MsgType>");
xmlSb.append("<Content><![CDATA[this is a test]]></Content>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void image() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[image]]></MsgType>");
xmlSb.append("<PicUrl><![CDATA[this is a url]]></PicUrl>");
xmlSb.append("<MediaId><![CDATA[media_id]]></MediaId>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void voice() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[voice]]></MsgType>");
xmlSb.append("<MediaId><![CDATA[media_id]]></MediaId>");
xmlSb.append("<Format><![CDATA[Format]]></Format>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void re_voice() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[voice]]></MsgType>");
xmlSb.append("<MediaId><![CDATA[media_id]]></MediaId>");
xmlSb.append("<Format><![CDATA[Format]]></Format>");
xmlSb.append("<Recognition><![CDATA[腾讯微信团队]]></Recognition>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void video() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[video]]></MsgType>");
xmlSb.append("<MediaId><![CDATA[media_id]]></MediaId>");
xmlSb.append("<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void location2() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[location]]></MsgType>");
xmlSb.append("<Location_X>23.134521</Location_X>");
xmlSb.append("<Location_Y>113.358803</Location_Y>");
xmlSb.append("<Scale>20</Scale>");
xmlSb.append("<Label><![CDATA[位置信息]]></Label>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void link() {
try {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[link]]></MsgType>");
xmlSb.append("<Title><![CDATA[公众平台官网链接]]></Title>");
xmlSb.append("<Description><![CDATA[公众平台官网链接]]></Description>");
xmlSb.append("<Url><![CDATA[url]]></Url>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
System.out.println(MessageUtil.xml2msg(xmlSb.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -1,114 +0,0 @@
package com.foxinmy.weixin4j.test;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import com.foxinmy.weixin4j.WeixinProxy;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.MpArticle;
import com.foxinmy.weixin4j.type.MediaType;
/**
* 群发消息
*
* @className MpNewsTest
* @author jy
* @date 2014年4月27日
* @since JDK 1.7
* @see
*/
public class MessageMassTest {
private WeixinProxy weixinProxy;
@Before
public void init() {
this.weixinProxy = new WeixinProxy();
}
@Test
public void uploadArticle() {
List<MpArticle> articles = new ArrayList<MpArticle>();
try {
String thumbMediaId = weixinProxy.uploadMedia(new File(
"/tmp/test.jpg"), MediaType.image);
articles.add(new MpArticle(thumbMediaId, "title", "content"));
weixinProxy.uploadArticle(articles);
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
}
@Test
public void uploadVideo() {
try {
weixinProxy.uploadVideo("mediaId", "title", "desc");
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
}
@Test
public void massByGroup() {
try {
weixinProxy.massByGroup("123", MediaType.image, "groupId");
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
}
@Test
public void massByOpenIds() {
try {
weixinProxy.massByOpenIds("123", MediaType.image, "openIds");
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
}
@Test
public void massArticleByGroup() {
List<MpArticle> articles = new ArrayList<MpArticle>();
try {
String thumbMediaId = weixinProxy.uploadMedia(new File(
"/tmp/test.jpg"), MediaType.image);
articles.add(new MpArticle(thumbMediaId, "title", "content"));
weixinProxy.massArticleByGroup(articles, "0");
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
}
@Test
public void massArticleByOpenIds() {
List<MpArticle> articles = new ArrayList<MpArticle>();
try {
String thumbMediaId = weixinProxy.uploadMedia(new File(
"/tmp/test.jpg"), MediaType.image);
articles.add(new MpArticle(thumbMediaId, "title", "content"));
weixinProxy.massArticleByOpenIds(articles,
"owGBft_vbBbOaQOmpEUE4xDLeRSU");
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
}
@Test
public void deleteMass() {
try {
weixinProxy.deleteMassNews("34182");
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
}
}

View File

@ -1,30 +0,0 @@
package com.foxinmy.weixin4j.test;
import org.junit.Before;
import org.junit.Test;
import com.foxinmy.weixin4j.WeixinProxy;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.msg.out.TemplateMessage;
public class MessageTemplTest {
private WeixinProxy weixinProxy;
@Before
public void init() {
this.weixinProxy = new WeixinProxy();
}
@Test
public void test() {
TemplateMessage tplMessage = new TemplateMessage("touser",
"template_id", "url");
tplMessage.pushData("name", "fox");
System.out.print(tplMessage.toJson());
try {
System.out.print(weixinProxy.sendTplMessage(tplMessage));
} catch (WeixinException e) {
System.out.println(e.getErrorMsg());
}
}
}

View File

@ -1,48 +1,44 @@
package com.foxinmy.weixin4j.test; package com.foxinmy.weixin4j.test;
import java.io.File;
import java.io.IOException;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import com.foxinmy.weixin4j.WeixinProxy; import com.foxinmy.weixin4j.api.QrApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.QRParameter; import com.foxinmy.weixin4j.model.QRParameter;
import com.foxinmy.weixin4j.model.QRParameter.QRType; import com.foxinmy.weixin4j.model.QRParameter.QRType;
/** /**
* 二维码相关测试 * 二维码相关测试
*
* @className QRTest * @className QRTest
* @author jy.hu * @author jy.hu
* @date 2014年4月10日 * @date 2014年4月10日
* @since JDK 1.7 * @since JDK 1.7
*/ */
public class QRTest { public class QRTest extends TokenTest {
private WeixinProxy weixinProxy; private QrApi qrApi;
@Before @Before
public void init() { public void init() {
weixinProxy = new WeixinProxy(); qrApi = new QrApi(tokenApi);
} }
@Test @Test
public void temp_qr() { public void temp_qr() throws WeixinException, IOException {
QRParameter qr = new QRParameter(1200, QRType.TEMPORARY, 2); QRParameter qr = new QRParameter(1200, QRType.TEMPORARY, 2);
try { File file = qrApi.getQR(qr);
System.out.println(qr.toJson()); Assert.assertTrue(file.exists());
System.out.println(weixinProxy.getQR(qr));
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
} }
@Test @Test
public void forever_qr() { public void forever_qr() throws WeixinException, IOException {
QRParameter qr = new QRParameter(QRType.PERMANENCE, 1); QRParameter qr = new QRParameter(QRType.PERMANENCE, 1);
try { File file = qrApi.getQR(qr);
System.out.println(qr.toJson()); Assert.assertTrue(file.exists());
System.out.println(weixinProxy.getQR(qr));
} catch (Exception e) {
e.printStackTrace();
}
} }
} }

View File

@ -1,5 +1,6 @@
package com.foxinmy.weixin4j.test; package com.foxinmy.weixin4j.test;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -8,26 +9,24 @@ import com.foxinmy.weixin4j.api.token.TokenApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
/** /**
* token相关测试 * token测试
*
* @className TokenTest * @className TokenTest
* @author jy.hu * @author jy.hu
* @date 2014年4月10日 * @date 2014年4月10日
* @since JDK 1.7 * @since JDK 1.7
*/ */
public class TokenTest { public class TokenTest {
private TokenApi tokenApi;
protected TokenApi tokenApi;
@Before @Before
public void init() { public void setUp() {
tokenApi = new FileTokenApi(); tokenApi = new FileTokenApi();
} }
@Test @Test
public void getToken() { public void test() throws WeixinException {
try { Assert.assertNotNull(tokenApi.getToken());
System.out.println(tokenApi.getToken());
} catch (WeixinException e) {
e.printStackTrace();
}
} }
} }

View File

@ -2,49 +2,50 @@ package com.foxinmy.weixin4j.test;
import java.util.List; import java.util.List;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import com.foxinmy.weixin4j.WeixinProxy; import com.foxinmy.weixin4j.api.UserApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.model.User; import com.foxinmy.weixin4j.model.User;
/** /**
* 用户相关测试 * 用户相关测试
*
* @className UserTest * @className UserTest
* @author jy.hu * @author jy.hu
* @date 2014年4月10日 * @date 2014年4月10日
* @since JDK 1.7 * @since JDK 1.7
*/ */
public class UserTest { public class UserTest extends TokenTest {
private WeixinProxy weixinProxy; private UserApi userApi;
@Before @Before
public void init() { public void init() {
weixinProxy = new WeixinProxy(); userApi = new UserApi(tokenApi);
} }
@Test @Test
public void getUser() { public void getUser() throws WeixinException {
try { User user = userApi.getUser("owGBft_vbBbOaQOmpEUE4xDLeRSU");
System.out.println(weixinProxy.getUser("owGBft_vbBbOaQOmpEUE4xDLeRSU")); Assert.assertNotNull(user);
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
} }
@Test @Test
public void following() { public void following() throws WeixinException {
try { List<User> userList = userApi.getAllFollowing();
System.out.println(weixinProxy.getFollowing(null)); for (User user : userList) {
List<User> userList = weixinProxy.getAllFollowing(); System.out.println(user);
for (User user : userList) {
System.out.println(user);
}
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
} }
Assert.assertTrue(!userList.isEmpty());
}
@Test
public void remark() throws WeixinException {
BaseResult result = userApi.remarkUserName(
"owGBft_vbBbOaQOmpEUE4xDLeRSU", "foo");
Assert.assertEquals(0, result.getErrcode());
} }
} }

View File

@ -0,0 +1,179 @@
package com.foxinmy.weixin4j.test.msg;
import java.io.IOException;
import org.junit.Assert;
import org.junit.Test;
import com.foxinmy.weixin4j.exception.WeixinException;
/**
* 接收事件消息格式测试
*
* @author jy.hu
* @date 2014年3月24日
* @since JDK 1.7
*/
public class EventMsgTest extends MessagePush {
private StringBuilder xmlSb = new StringBuilder();
/***************** event message *********************/
@Test
public void scribe() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[subscribe]]></Event>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void scan() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[SCAN]]></Event>");
xmlSb.append("<EventKey><![CDATA[SCENE_VALUE]]></EventKey>");
xmlSb.append("<Ticket><![CDATA[TICKET]]></Ticket>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void scan_scribe() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml><ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[subscribe]]></Event>");
xmlSb.append("<EventKey><![CDATA[qrscene_123123]]></EventKey>");
xmlSb.append("<Ticket><![CDATA[TICKET]]></Ticket>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void location() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[fromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[LOCATION]]></Event>");
xmlSb.append("<Latitude>23.137466</Latitude>");
xmlSb.append("<Longitude>113.352425</Longitude>");
xmlSb.append("<Precision>119.385040</Precision>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void menu_click() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[CLICK]]></Event>");
xmlSb.append("<EventKey><![CDATA[EVENTKEY]]></EventKey>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void menu_link() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[VIEW]]></Event>");
xmlSb.append("<EventKey><![CDATA[www.qq.com]]></EventKey>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void menu_scan() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[scancode_waitmsg]]></Event>");
xmlSb.append("<EventKey><![CDATA[www.qq.com]]></EventKey>");
xmlSb.append("<ScanCodeInfo><ScanType><![CDATA[qrcode]]></ScanType>");
xmlSb.append("<ScanResult><![CDATA[1]]></ScanResult>");
xmlSb.append("</ScanCodeInfo>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void menu_photo() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[pic_weixin]]></Event>");
xmlSb.append("<EventKey><![CDATA[www.qq.com]]></EventKey>");
xmlSb.append("<SendPicsInfo><Count>1</Count>");
xmlSb.append("<PicList><item><PicMd5Sum><![CDATA[1b5f7c23b5bf75682a53e7b6d163e185]]></PicMd5Sum>");
xmlSb.append("</item></PicList></SendPicsInfo>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void menu_location() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[event]]></MsgType>");
xmlSb.append("<Event><![CDATA[location_select]]></Event>");
xmlSb.append("<EventKey><![CDATA[www.qq.com]]></EventKey>");
xmlSb.append("<SendLocationInfo><Location_X><![CDATA[23]]></Location_X>");
xmlSb.append("<Location_Y><![CDATA[113]]></Location_Y>");
xmlSb.append("<Scale><![CDATA[15]]></Scale>");
xmlSb.append("<Label><![CDATA[ 广州市海珠区客村艺苑路 106号]]></Label>");
xmlSb.append("<Poiname><![CDATA[]]></Poiname></SendLocationInfo>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
}

View File

@ -0,0 +1,144 @@
package com.foxinmy.weixin4j.test.msg;
import java.io.IOException;
import org.junit.Assert;
import org.junit.Test;
import com.foxinmy.weixin4j.exception.WeixinException;
/**
* 接受一般消息格式测试
*
* @author jy.hu
* @date 2014年3月24日
* @since JDK 1.7
*/
public class InMsgTest extends MessagePush {
private StringBuilder xmlSb = new StringBuilder();
/***************** common message *********************/
@Test
public void text() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[fromUser]]></FromUserName>");
xmlSb.append("<CreateTime>1348831860</CreateTime>");
xmlSb.append("<MsgType><![CDATA[text]]></MsgType>");
xmlSb.append("<Content><![CDATA[this is a test]]></Content>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void image() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[image]]></MsgType>");
xmlSb.append("<PicUrl><![CDATA[this is a url]]></PicUrl>");
xmlSb.append("<MediaId><![CDATA[media_id]]></MediaId>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void voice() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[voice]]></MsgType>");
xmlSb.append("<MediaId><![CDATA[media_id]]></MediaId>");
xmlSb.append("<Format><![CDATA[Format]]></Format>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void re_voice() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[voice]]></MsgType>");
xmlSb.append("<MediaId><![CDATA[media_id]]></MediaId>");
xmlSb.append("<Format><![CDATA[Format]]></Format>");
xmlSb.append("<Recognition><![CDATA[腾讯微信团队]]></Recognition>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void video() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[video]]></MsgType>");
xmlSb.append("<MediaId><![CDATA[media_id]]></MediaId>");
xmlSb.append("<ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void location() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[location]]></MsgType>");
xmlSb.append("<Location_X>23.134521</Location_X>");
xmlSb.append("<Location_Y>113.358803</Location_Y>");
xmlSb.append("<Scale>20</Scale>");
xmlSb.append("<Label><![CDATA[位置信息]]></Label>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
@Test
public void link() throws WeixinException, IOException {
xmlSb.delete(0, xmlSb.length());
xmlSb.append("<xml>");
xmlSb.append("<ToUserName><![CDATA[toUser]]></ToUserName>");
xmlSb.append("<FromUserName><![CDATA[FromUser]]></FromUserName>");
xmlSb.append("<CreateTime>123456789</CreateTime>");
xmlSb.append("<MsgType><![CDATA[link]]></MsgType>");
xmlSb.append("<Title><![CDATA[公众平台官网链接]]></Title>");
xmlSb.append("<Description><![CDATA[公众平台官网链接]]></Description>");
xmlSb.append("<Url><![CDATA[url]]></Url>");
xmlSb.append("<MsgId>1234567890123456</MsgId>");
xmlSb.append("</xml>");
String response = push(xmlSb.toString());
Assert.assertNotNull(response);
System.out.println(response);
}
}

View File

@ -0,0 +1,93 @@
package com.foxinmy.weixin4j.test.msg;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.foxinmy.weixin4j.api.MassApi;
import com.foxinmy.weixin4j.api.MediaApi;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.model.MpArticle;
import com.foxinmy.weixin4j.test.TokenTest;
import com.foxinmy.weixin4j.type.MediaType;
/**
* 群发消息
*
* @className MpNewsTest
* @author jy
* @date 2014年4月27日
* @since JDK 1.7
* @see
*/
public class MassMsgTest extends TokenTest {
private MassApi massApi;
private MediaApi mediaApi;
@Before
public void init() {
this.massApi = new MassApi(tokenApi);
this.mediaApi = new MediaApi(tokenApi);
}
@Test
public void uploadArticle() throws IOException, WeixinException {
List<MpArticle> articles = new ArrayList<MpArticle>();
String thumbMediaId = mediaApi.uploadMedia(new File("/tmp/test.jpg"),
MediaType.image);
articles.add(new MpArticle(thumbMediaId, "title", "content"));
massApi.uploadArticle(articles);
}
@Test
public void uploadVideo() throws WeixinException {
String massId = massApi.uploadVideo("mediaId", "title", "desc");
Assert.assertTrue(massId != null);
}
@Test
public void massByGroup() throws WeixinException {
String massId = massApi.massByGroup("123", MediaType.image, "groupId");
Assert.assertTrue(massId != null);
}
@Test
public void massByOpenIds() throws WeixinException {
String massId = massApi
.massByOpenIds("123", MediaType.image, "openIds");
Assert.assertTrue(massId != null);
}
@Test
public void massArticleByGroup() throws IOException, WeixinException {
List<MpArticle> articles = new ArrayList<MpArticle>();
String thumbMediaId = mediaApi.uploadMedia(new File("/tmp/test.jpg"),
MediaType.image);
articles.add(new MpArticle(thumbMediaId, "title", "content"));
String massId = massApi.massArticleByGroup(articles, "0");
Assert.assertTrue(massId != null);
}
@Test
public void massArticleByOpenIds() throws IOException, WeixinException {
List<MpArticle> articles = new ArrayList<MpArticle>();
String thumbMediaId = mediaApi.uploadMedia(new File("/tmp/test.jpg"),
MediaType.image);
articles.add(new MpArticle(thumbMediaId, "title", "content"));
String massId = massApi.massArticleByOpenIds(articles,
"owGBft_vbBbOaQOmpEUE4xDLeRSU");
Assert.assertTrue(massId != null);
}
@Test
public void deleteMass() throws WeixinException {
BaseResult result = massApi.deleteMassNews("34182");
Assert.assertEquals(0, result.getErrcode());
}
}

View File

@ -1,13 +1,16 @@
package com.foxinmy.weixin4j.test; package com.foxinmy.weixin4j.test.msg;
import java.io.File; import java.io.File;
import java.io.IOException;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import com.foxinmy.weixin4j.WeixinProxy; import com.foxinmy.weixin4j.api.MediaApi;
import com.foxinmy.weixin4j.api.NotifyApi;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.msg.model.Music; import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.msg.notify.ArticleNotify; import com.foxinmy.weixin4j.msg.notify.ArticleNotify;
import com.foxinmy.weixin4j.msg.notify.BaseNotify; import com.foxinmy.weixin4j.msg.notify.BaseNotify;
import com.foxinmy.weixin4j.msg.notify.ImageNotify; import com.foxinmy.weixin4j.msg.notify.ImageNotify;
@ -15,23 +18,27 @@ import com.foxinmy.weixin4j.msg.notify.MusicNotify;
import com.foxinmy.weixin4j.msg.notify.TextNotify; import com.foxinmy.weixin4j.msg.notify.TextNotify;
import com.foxinmy.weixin4j.msg.notify.VideoNotify; import com.foxinmy.weixin4j.msg.notify.VideoNotify;
import com.foxinmy.weixin4j.msg.notify.VoiceNotify; import com.foxinmy.weixin4j.msg.notify.VoiceNotify;
import com.foxinmy.weixin4j.test.TokenTest;
import com.foxinmy.weixin4j.type.MediaType; import com.foxinmy.weixin4j.type.MediaType;
/** /**
* 客服消息测试 * 客服消息测试
*
* @className MessageNotifyTest * @className MessageNotifyTest
* @author jy.hu * @author jy.hu
* @date 2014年4月10日 * @date 2014年4月10日
* @since JDK 1.7 * @since JDK 1.7
* @see * @see
*/ */
public class MessageNotifyTest { public class NotifyMsgTest extends TokenTest {
private WeixinProxy weixinProxy; private NotifyApi notifyApi;
private MediaApi mediaApi;
@Before @Before
public void init() { public void init() {
weixinProxy = new WeixinProxy(); notifyApi = new NotifyApi(tokenApi);
mediaApi = new MediaApi(tokenApi);
} }
@Test @Test
@ -57,7 +64,7 @@ public class MessageNotifyTest {
@Test @Test
public void video() { public void video() {
VideoNotify notify = new VideoNotify("to"); VideoNotify notify = new VideoNotify("to");
notify.pushVideo("123","m123"); notify.pushVideo("123", "m123");
System.out.println(notify.toJson()); System.out.println(notify.toJson());
} }
@ -77,27 +84,21 @@ public class MessageNotifyTest {
} }
@Test @Test
public void send1() { public void send1() throws IOException, WeixinException {
BaseNotify notify = new TextNotify("哈哈哈哈", "owGBft_vbBbOaQOmpEUE4xDLeRSU"); BaseNotify notify = new TextNotify("this is a notify message!",
try { "owGBft_vbBbOaQOmpEUE4xDLeRSU");
weixinProxy.sendNotify(notify); BaseResult result = notifyApi.sendNotify(notify);
String mediaId = weixinProxy.uploadMedia(new File("D:\\test.jpg"), MediaType.image); Assert.assertEquals(0, result.getErrcode());
ImageNotify t = new ImageNotify("owGBft_vbBbOaQOmpEUE4xDLeRSU");
t.pushMediaId(mediaId);
weixinProxy.sendNotify(t);
} catch (WeixinException e) {
System.out.println(e.getErrorCode());
System.out.println(e.getErrorMsg());
}
} }
@Test @Test
public void send2() { public void send2() throws WeixinException, IOException {
try { String mediaId = mediaApi.uploadMedia(new File(
weixinProxy.sendNotify("to",new Music("thumbMediaId")); "/tmp/test.jpg"), MediaType.image);
} catch (WeixinException e) { ImageNotify imageNotify = new ImageNotify(
System.out.println(e.getErrorCode()); "owGBft_vbBbOaQOmpEUE4xDLeRSU");
System.out.println(e.getErrorMsg()); imageNotify.pushMediaId(mediaId);
} BaseResult result = notifyApi.sendNotify(imageNotify);
Assert.assertEquals(0, result.getErrcode());
} }
} }

View File

@ -1,5 +1,6 @@
package com.foxinmy.weixin4j.test; package com.foxinmy.weixin4j.test.msg;
import org.dom4j.DocumentException;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -18,7 +19,7 @@ import com.foxinmy.weixin4j.msg.out.VoiceMessage;
* @date 2014年3月24日 * @date 2014年3月24日
* @since JDK 1.7 * @since JDK 1.7
*/ */
public class MessageOutTest { public class OutMsgTest {
private BaseMessage inMessage; private BaseMessage inMessage;
@Before @Before
@ -29,7 +30,7 @@ public class MessageOutTest {
} }
@Test @Test
public void text() { public void text() throws DocumentException {
TextMessage message = new TextMessage("text", inMessage); TextMessage message = new TextMessage("text", inMessage);
System.out.println(message.toXml()); System.out.println(message.toXml());
} }

View File

@ -0,0 +1,29 @@
package com.foxinmy.weixin4j.test.msg;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.foxinmy.weixin4j.api.TmplApi;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.msg.out.TemplateMessage;
import com.foxinmy.weixin4j.test.TokenTest;
public class TemplateMsgTest extends TokenTest {
private TmplApi tmplApi;
@Before
public void init() {
this.tmplApi = new TmplApi(tokenApi);
}
@Test
public void test() throws WeixinException {
TemplateMessage tplMessage = new TemplateMessage("touser",
"template_id", "title", "url");
tplMessage.pushData("name", "val");
BaseResult result = tmplApi.sendTmplMessage(tplMessage);
Assert.assertEquals(0, result.getErrcode());
}
}