添加群发支持

This commit is contained in:
Daniel Qian 2014-08-25 11:01:09 +08:00
parent 71215bbe79
commit f326d7e72e
20 changed files with 682 additions and 60 deletions

View File

@ -1,17 +1,78 @@
package chanjarster.weixin.api; package chanjarster.weixin.api;
import java.util.HashMap;
import java.util.Map;
public class WxConsts { public class WxConsts {
public static final String MSG_TEXT = "text"; ///////////////////////
public static final String MSG_IMAGE = "image"; // 微信推送过来的消息的类型和发送给微信xml格式消息的消息类型
public static final String MSG_VOICE = "voice"; ///////////////////////
public static final String MSG_MUSIC = "music"; public static final String XML_MSG_TEXT = "text";
public static final String MSG_VIDEO = "video"; public static final String XML_MSG_IMAGE = "image";
public static final String MSG_NEWS = "news"; public static final String XML_MSG_VOICE = "voice";
public static final String MSG_LOCATION = "location"; public static final String XML_MSG_VIDEO = "video";
public static final String MSG_LINK = "link"; public static final String XML_MSG_NEWS = "news";
public static final String MSG_EVENT = "event"; public static final String XML_MSG_MUSIC = "news";
public static final String XML_MSG_LOCATION = "location";
public static final String XML_MSG_LINK = "link";
public static final String XML_MSG_EVENT = "event";
///////////////////////
// 客服消息的消息类型
///////////////////////
public static final String CUSTOM_MSG_TEXT = "text";
public static final String CUSTOM_MSG_IMAGE = "image";
public static final String CUSTOM_MSG_VOICE = "voice";
public static final String CUSTOM_MSG_VIDEO = "video";
public static final String CUSTOM_MSG_MUSIC = "music";
public static final String CUSTOM_MSG_NEWS = "news";
///////////////////////
// 群发消息的消息类型
///////////////////////
public static final String MASS_MSG_NEWS = "mpnews";
public static final String MASS_MSG_TEXT = "text";
public static final String MASS_MSG_VOICE = "voice";
public static final String MASS_MSG_IMAGE = "image";
public static final String MASS_MSG_VIDEO = "mpvideo";
///////////////////////
// 群发消息后微信端推送给服务器的反馈消息
///////////////////////
public static final String MASS_ST_SUCCESS = "send success";
public static final String MASS_ST_FAIL = "send fail";
public static final String MASS_ST_涉嫌广告 = "err(10001)";
public static final String MASS_ST_涉嫌政治 = "err(20001)";
public static final String MASS_ST_涉嫌社会 = "err(20004)";
public static final String MASS_ST_涉嫌色情 = "err(20002)";
public static final String MASS_ST_涉嫌违法犯罪 = "err(20006)";
public static final String MASS_ST_涉嫌欺诈 = "err(20008)";
public static final String MASS_ST_涉嫌版权 = "err(20013)";
public static final String MASS_ST_涉嫌互推_互相宣传 = "err(22000)";
public static final String MASS_ST_涉嫌其他 = "err(21000)";
/**
* 群发反馈消息代码所对应的文字描述
*/
public static final Map<String, String> MASS_ST_2_DESC = new HashMap<String, String>();
static {
MASS_ST_2_DESC.put(MASS_ST_SUCCESS, "发送成功");
MASS_ST_2_DESC.put(MASS_ST_FAIL, "发送失败");
MASS_ST_2_DESC.put(MASS_ST_涉嫌广告, "涉嫌广告");
MASS_ST_2_DESC.put(MASS_ST_涉嫌政治, "涉嫌政治");
MASS_ST_2_DESC.put(MASS_ST_涉嫌社会, "涉嫌社会");
MASS_ST_2_DESC.put(MASS_ST_涉嫌色情, "涉嫌色情");
MASS_ST_2_DESC.put(MASS_ST_涉嫌违法犯罪, "涉嫌违法犯罪");
MASS_ST_2_DESC.put(MASS_ST_涉嫌欺诈, "涉嫌欺诈");
MASS_ST_2_DESC.put(MASS_ST_涉嫌版权, "涉嫌版权");
MASS_ST_2_DESC.put(MASS_ST_涉嫌互推_互相宣传, "涉嫌互推_互相宣传");
MASS_ST_2_DESC.put(MASS_ST_涉嫌其他, "涉嫌其他");
}
///////////////////////
// 微信端推送过来的事件类型
///////////////////////
public static final String EVT_SUBSCRIBE = "subscribe"; public static final String EVT_SUBSCRIBE = "subscribe";
public static final String EVT_UNSUBSCRIBE = "unsubscribe"; public static final String EVT_UNSUBSCRIBE = "unsubscribe";
public static final String EVT_SCAN = "SCAN"; public static final String EVT_SCAN = "SCAN";
@ -20,25 +81,20 @@ public class WxConsts {
public static final String EVT_VIEW = "VIEW"; public static final String EVT_VIEW = "VIEW";
public static final String EVT_MASS_SEND_JOB_FINISH = "MASSSENDJOBFINISH"; public static final String EVT_MASS_SEND_JOB_FINISH = "MASSSENDJOBFINISH";
///////////////////////
// 上传多媒体文件的类型
///////////////////////
public static final String MEDIA_IMAGE = "image"; public static final String MEDIA_IMAGE = "image";
public static final String MEDIA_VOICE = "voice"; public static final String MEDIA_VOICE = "voice";
public static final String MEDIA_VIDEO = "video"; public static final String MEDIA_VIDEO = "video";
public static final String MEDIA_THUMB = "thumb"; public static final String MEDIA_THUMB = "thumb";
///////////////////////
// 文件类型
///////////////////////
public static final String FILE_JPG = "jpeg"; public static final String FILE_JPG = "jpeg";
public static final String FILE_MP3 = "mp3"; public static final String FILE_MP3 = "mp3";
public static final String FILE_ARM = "arm"; public static final String FILE_ARM = "arm";
public static final String FILE_MP4 = "mp4"; public static final String FILE_MP4 = "mp4";
public static final String ST_SEND_SUCCESS = "send success";
public static final String ST_SEND_FAIL = "send fail";
public static final String ST_涉嫌广告 = "err(10001)";
public static final String ST_涉嫌政治 = "err(20001)";
public static final String ST_涉嫌社会 = "err(20004)";
public static final String ST_涉嫌色情 = "err(20002)";
public static final String ST_涉嫌违法犯罪 = "err(20006)";
public static final String ST_涉嫌欺诈 = "err(20008)";
public static final String ST_涉嫌版权 = "err(20013)";
public static final String ST_涉嫌互推_互相宣传 = "err(22000)";
public static final String ST_涉嫌其他 = "err(21000)";
} }

View File

@ -5,8 +5,13 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import chanjarster.weixin.bean.WxCustomMessage; import chanjarster.weixin.bean.WxCustomMessage;
import chanjarster.weixin.bean.WxMassMessage;
import chanjarster.weixin.bean.WxMassNews;
import chanjarster.weixin.bean.WxMassVideo;
import chanjarster.weixin.bean.WxMenu; import chanjarster.weixin.bean.WxMenu;
import chanjarster.weixin.bean.result.WxUploadResult; import chanjarster.weixin.bean.result.WxMassMaterialUploadResult;
import chanjarster.weixin.bean.result.WxMassSendResult;
import chanjarster.weixin.bean.result.WxMediaUploadResult;
import chanjarster.weixin.exception.WxErrorException; import chanjarster.weixin.exception.WxErrorException;
/** /**
@ -58,7 +63,7 @@ public interface WxService {
* @param inputStream 输入流 * @param inputStream 输入流
* @throws WxErrorException * @throws WxErrorException
*/ */
public WxUploadResult uploadMedia(String mediaType, String fileType, InputStream inputStream) throws WxErrorException, IOException; public WxMediaUploadResult uploadMedia(String mediaType, String fileType, InputStream inputStream) throws WxErrorException, IOException;
/** /**
* @see #uploadMedia(String, String, InputStream) * @see #uploadMedia(String, String, InputStream)
@ -66,7 +71,7 @@ public interface WxService {
* @param file * @param file
* @throws WxErrorException * @throws WxErrorException
*/ */
public WxUploadResult uploadMedia(String mediaType, File file) throws WxErrorException; public WxMediaUploadResult uploadMedia(String mediaType, File file) throws WxErrorException;
/** /**
* <pre> * <pre>
@ -90,6 +95,40 @@ public interface WxService {
*/ */
public void sendCustomMessage(WxCustomMessage message) throws WxErrorException; public void sendCustomMessage(WxCustomMessage message) throws WxErrorException;
/**
* <pre>
* 上传群发用的图文消息上传后才能群发图文消息 {@link #sendMassMessage(WxMassMessage)}
*
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口
* </pre>
* @param news
* @throws WxErrorException
*/
public WxMassMaterialUploadResult uploadMassNews(WxMassNews news) throws WxErrorException;
/**
* <pre>
* 上传群发用的视频上传后才能群发视频消息 {@link #sendMassMessage(WxMassMessage)}
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口
* </pre>
* @return
* @throws WxErrorException
*/
public WxMassMaterialUploadResult uploadMassVideo(WxMassVideo video) throws WxErrorException;
/**
* <pre>
* 群发消息
* 如果发送图文消息必须先使用 {@link #uploadMassNews(WxMassNews)} 获得media_id然后再发送
* 如果发送视频消息必须先使用 {@link #uploadMassVideo(WxMassVideo)} 获得media_id然后再发送
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口
* </pre>
* @param message
* @throws WxErrorException
* @return
*/
public WxMassSendResult sendMassMessage(WxMassMessage message) throws WxErrorException;
/** /**
* <pre> * <pre>
* 自定义菜单创建接口 * 自定义菜单创建接口

View File

@ -18,9 +18,14 @@ import org.apache.http.impl.client.HttpClients;
import chanjarster.weixin.bean.WxAccessToken; import chanjarster.weixin.bean.WxAccessToken;
import chanjarster.weixin.bean.WxCustomMessage; import chanjarster.weixin.bean.WxCustomMessage;
import chanjarster.weixin.bean.WxMassMessage;
import chanjarster.weixin.bean.WxMassNews;
import chanjarster.weixin.bean.WxMassVideo;
import chanjarster.weixin.bean.WxMenu; import chanjarster.weixin.bean.WxMenu;
import chanjarster.weixin.bean.result.WxError; import chanjarster.weixin.bean.result.WxError;
import chanjarster.weixin.bean.result.WxUploadResult; import chanjarster.weixin.bean.result.WxMassMaterialUploadResult;
import chanjarster.weixin.bean.result.WxMassSendResult;
import chanjarster.weixin.bean.result.WxMediaUploadResult;
import chanjarster.weixin.exception.WxErrorException; import chanjarster.weixin.exception.WxErrorException;
import chanjarster.weixin.util.fs.FileUtil; import chanjarster.weixin.util.fs.FileUtil;
import chanjarster.weixin.util.http.MediaDownloadRequestExecutor; import chanjarster.weixin.util.http.MediaDownloadRequestExecutor;
@ -137,11 +142,11 @@ public class WxServiceImpl implements WxService {
} }
} }
public WxUploadResult uploadMedia(String mediaType, String fileType, InputStream inputStream) throws WxErrorException, IOException { public WxMediaUploadResult uploadMedia(String mediaType, String fileType, InputStream inputStream) throws WxErrorException, IOException {
return uploadMedia(mediaType,FileUtil.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); return uploadMedia(mediaType,FileUtil.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType));
} }
public WxUploadResult uploadMedia(String mediaType, File file) throws WxErrorException { public WxMediaUploadResult uploadMedia(String mediaType, File file) throws WxErrorException {
String url = "http://file.api.weixin.qq.com/cgi-bin/media/upload?type=" + mediaType; String url = "http://file.api.weixin.qq.com/cgi-bin/media/upload?type=" + mediaType;
return execute(new MediaUploadRequestExecutor(), url, file); return execute(new MediaUploadRequestExecutor(), url, file);
} }
@ -151,6 +156,24 @@ public class WxServiceImpl implements WxService {
return execute(new MediaDownloadRequestExecutor(), url, "media_id=" + media_id); return execute(new MediaDownloadRequestExecutor(), url, "media_id=" + media_id);
} }
public WxMassMaterialUploadResult uploadMassNews(WxMassNews news) throws WxErrorException {
String url = "https://api.weixin.qq.com/cgi-bin/media/uploadnews";
String responseContent = execute(new SimplePostRequestExecutor(), url, news.toJson());
return WxMassMaterialUploadResult.fromJson(responseContent);
}
public WxMassMaterialUploadResult uploadMassVideo(WxMassVideo video) throws WxErrorException {
String url = " https://file.api.weixin.qq.com/cgi-bin/media/uploadvideo";
String responseContent = execute(new SimplePostRequestExecutor(), url, video.toJson());
return WxMassMaterialUploadResult.fromJson(responseContent);
}
public WxMassSendResult sendMassMessage(WxMassMessage message) throws WxErrorException {
String url = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall";
String responseContent = execute(new SimplePostRequestExecutor(), url, message.toJson());
return WxMassSendResult.fromJson(responseContent);
}
/** /**
* 向微信端发送请求在这里执行的策略是当发生access_token过期时才去刷新然后重新执行请求而不是全局定时请求 * 向微信端发送请求在这里执行的策略是当发生access_token过期时才去刷新然后重新执行请求而不是全局定时请求
* @param executor * @param executor

View File

@ -3,6 +3,7 @@ package chanjarster.weixin.bean;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import chanjarster.weixin.api.WxConsts;
import chanjarster.weixin.util.json.WxGsonBuilder; import chanjarster.weixin.util.json.WxGsonBuilder;
/** /**
@ -32,6 +33,19 @@ public class WxCustomMessage {
public String getMsgtype() { public String getMsgtype() {
return msgtype; return msgtype;
} }
/**
* <pre>
* 请使用
* {@link WxConsts#CUSTOM_MSG_TEXT}
* {@link WxConsts#CUSTOM_MSG_IMAGE}
* {@link WxConsts#CUSTOM_MSG_VOICE}
* {@link WxConsts#CUSTOM_MSG_MUSIC}
* {@link WxConsts#CUSTOM_MSG_VIDEO}
* {@link WxConsts#CUSTOM_MSG_NEWS}
* </pre>
* @param msgtype
*/
public void setMsgtype(String msgtype) { public void setMsgtype(String msgtype) {
this.msgtype = msgtype; this.msgtype = msgtype;
} }

View File

@ -0,0 +1,96 @@
package chanjarster.weixin.bean;
import java.util.ArrayList;
import java.util.List;
import chanjarster.weixin.api.WxConsts;
import chanjarster.weixin.bean.result.WxMassMaterialUploadResult;
import chanjarster.weixin.util.json.WxGsonBuilder;
/**
* 群发消息
*
* @author chanjarster
*/
public class WxMassMessage {
protected List<String> touser = new ArrayList<String>();
protected String group_id;
protected String msgtype;
protected String content;
protected String media_id;
public WxMassMessage() {
super();
}
/**
* 利用上传群发所用的素材的结果构造群发消息
* @param r
* @return
*/
public WxMassMessage(WxMassMaterialUploadResult r) {
setMedia_id(r.getMedia_id());
if("video".equals(r.getType())) {
setMsgtype(WxConsts.MASS_MSG_VIDEO);
} else {
setMsgtype(r.getType());
}
}
public String getMsgtype() {
return msgtype;
}
/**
* <pre>
* 请使用
* {@link WxConsts#MASS_MSG_IMAGE}
* {@link WxConsts#MASS_MSG_NEWS}
* {@link WxConsts#MASS_MSG_TEXT}
* {@link WxConsts#MASS_MSG_VIDEO}
* {@link WxConsts#MASS_MSG_VOICE}
* </pre>
* @param msgtype
*/
public void setMsgtype(String msgtype) {
this.msgtype = msgtype;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getMedia_id() {
return media_id;
}
public void setMedia_id(String media_id) {
this.media_id = media_id;
}
public String toJson() {
return WxGsonBuilder.INSTANCE.create().toJson(this);
}
public List<String> getTouser() {
return touser;
}
public void setTouser(List<String> touser) {
this.touser = touser;
}
public String getGroup_id() {
return group_id;
}
public void setGroup_id(String group_id) {
this.group_id = group_id;
}
}

View File

@ -0,0 +1,102 @@
package chanjarster.weixin.bean;
import java.util.ArrayList;
import java.util.List;
import chanjarster.weixin.util.json.WxGsonBuilder;
/**
* 群发时用到的图文消息素材
* @author chanjarster
*
*/
public class WxMassNews {
protected List<WxMassNewsArticle> articles = new ArrayList<WxMassNewsArticle>();
public List<WxMassNewsArticle> getArticles() {
return articles;
}
public void setArticles(List<WxMassNewsArticle> articles) {
this.articles = articles;
}
public String toJson() {
return WxGsonBuilder.INSTANCE.create().toJson(this);
}
public static class WxMassNewsArticle {
/**
* (必填) 图文消息缩略图的media_id可以在基础支持-上传多媒体文件接口中获得
*/
protected String thumb_media_id;
/**
* 图文消息的作者
*/
protected String author;
/**
* (必填) 图文消息的标题
*/
protected String title;
/**
* 在图文消息页面点击阅读原文后的页面
*/
protected String content_source_url;
/**
* (必填) 图文消息页面的内容支持HTML标签
*/
protected String content;
/**
* 图文消息的描述
*/
protected String digest;
/**
* 是否显示封面1为显示0为不显示
*/
protected boolean show_cover_pic;
public String getThumb_media_id() {
return thumb_media_id;
}
public void setThumb_media_id(String thumb_media_id) {
this.thumb_media_id = thumb_media_id;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent_source_url() {
return content_source_url;
}
public void setContent_source_url(String content_source_url) {
this.content_source_url = content_source_url;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getDigest() {
return digest;
}
public void setDigest(String digest) {
this.digest = digest;
}
public boolean isShow_cover_pic() {
return show_cover_pic;
}
public void setShow_cover_pic(boolean show_cover_pic) {
this.show_cover_pic = show_cover_pic;
}
}
}

View File

@ -0,0 +1,33 @@
package chanjarster.weixin.bean;
import chanjarster.weixin.util.json.WxGsonBuilder;
/**
* 群发时用到的视频素材
* @author chanjarster
*
*/
public class WxMassVideo {
protected String media_id;
protected String title;
protected String description;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String toJson() {
return WxGsonBuilder.INSTANCE.create().toJson(this);
}
}

View File

@ -9,6 +9,7 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import chanjarster.weixin.api.WxConsts;
import chanjarster.weixin.util.xml.AdapterCDATA; import chanjarster.weixin.util.xml.AdapterCDATA;
import chanjarster.weixin.util.xml.XmlTransformer; import chanjarster.weixin.util.xml.XmlTransformer;
@ -159,9 +160,35 @@ public class WxXmlMessage {
CreateTime = createTime; CreateTime = createTime;
} }
/**
* <pre>
* 当接受用户消息时可能会获得以下值
* {@link WxConsts#XML_MSG_TEXT}
* {@link WxConsts#XML_MSG_IMAGE}
* {@link WxConsts#XML_MSG_VOICE}
* {@link WxConsts#XML_MSG_VIDEO}
* {@link WxConsts#XML_MSG_LOCATION}
* {@link WxConsts#XML_MSG_LINK}
* {@link WxConsts#XML_MSG_EVENT}
* </pre>
* @return
*/
public String getMsgType() { public String getMsgType() {
return MsgType; return MsgType;
} }
/**
* <pre>
* 当发送消息的时候使用
* {@link WxConsts#XML_MSG_TEXT}
* {@link WxConsts#XML_MSG_IMAGE}
* {@link WxConsts#XML_MSG_VOICE}
* {@link WxConsts#XML_MSG_VIDEO}
* {@link WxConsts#XML_MSG_NEWS}
* {@link WxConsts#XML_MSG_MUSIC}
* </pre>
* @param msgType
*/
public void setMsgType(String msgType) { public void setMsgType(String msgType) {
MsgType = msgType; MsgType = msgType;
} }

View File

@ -0,0 +1,49 @@
package chanjarster.weixin.bean.result;
import chanjarster.weixin.util.json.WxGsonBuilder;
/**
* 上传群发所用的素材的结果
* @author chanjarster
*
*/
public class WxMassMaterialUploadResult {
protected String type;
protected String media_id;
protected long created_at;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMedia_id() {
return media_id;
}
public void setMedia_id(String media_id) {
this.media_id = media_id;
}
public long getCreated_at() {
return created_at;
}
public void setCreated_at(long created_at) {
this.created_at = created_at;
}
public static WxMassMaterialUploadResult fromJson(String json) {
return WxGsonBuilder.create().fromJson(json, WxMassMaterialUploadResult.class);
}
@Override
public String toString() {
return "WxUploadResult [type=" + type + ", media_id=" + media_id + ", created_at=" + created_at + "]";
}
}

View File

@ -0,0 +1,49 @@
package chanjarster.weixin.bean.result;
import chanjarster.weixin.util.json.WxGsonBuilder;
/**
* <pre>
* 群发消息一发送就返回的结果
*
* 真正的群发消息是否发送成功要看
* http://mp.weixin.qq.com/wiki/index.php?title=高级群发接口#.E4.BA.8B.E4.BB.B6.E6.8E.A8.E9.80.81.E7.BE.A4.E5.8F.91.E7.BB.93.E6.9E.9C
*
* </pre>
* @author chanjarster
*
*/
public class WxMassSendResult {
protected String errcode;
protected String errmsg;
protected String msg_id;
public String getErrcode() {
return errcode;
}
public void setErrcode(String errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
public String getMsg_id() {
return msg_id;
}
public void setMsg_id(String msg_id) {
this.msg_id = msg_id;
}
public static WxMassSendResult fromJson(String json) {
return WxGsonBuilder.create().fromJson(json, WxMassSendResult.class);
}
}

View File

@ -2,7 +2,7 @@ package chanjarster.weixin.bean.result;
import chanjarster.weixin.util.json.WxGsonBuilder; import chanjarster.weixin.util.json.WxGsonBuilder;
public class WxUploadResult { public class WxMediaUploadResult {
protected String type; protected String type;
protected String media_id; protected String media_id;
@ -33,8 +33,8 @@ public class WxUploadResult {
this.created_at = created_at; this.created_at = created_at;
} }
public static WxUploadResult fromJson(String json) { public static WxMediaUploadResult fromJson(String json) {
return WxGsonBuilder.create().fromJson(json, WxUploadResult.class); return WxGsonBuilder.create().fromJson(json, WxMediaUploadResult.class);
} }
public String getThumb_media_id() { public String getThumb_media_id() {

View File

@ -11,7 +11,7 @@ import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.MultipartEntityBuilder;
import chanjarster.weixin.bean.result.WxError; import chanjarster.weixin.bean.result.WxError;
import chanjarster.weixin.bean.result.WxUploadResult; import chanjarster.weixin.bean.result.WxMediaUploadResult;
import chanjarster.weixin.exception.WxErrorException; import chanjarster.weixin.exception.WxErrorException;
/** /**
@ -19,10 +19,10 @@ import chanjarster.weixin.exception.WxErrorException;
* @author chanjarster * @author chanjarster
* *
*/ */
public class MediaUploadRequestExecutor implements RequestExecutor<WxUploadResult, File> { public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUploadResult, File> {
@Override @Override
public WxUploadResult execute(String uri, File file) throws WxErrorException, ClientProtocolException, IOException { public WxMediaUploadResult execute(String uri, File file) throws WxErrorException, ClientProtocolException, IOException {
HttpPost httpPost = new HttpPost(uri); HttpPost httpPost = new HttpPost(uri);
if (file != null) { if (file != null) {
HttpEntity entity = MultipartEntityBuilder HttpEntity entity = MultipartEntityBuilder
@ -38,7 +38,7 @@ public class MediaUploadRequestExecutor implements RequestExecutor<WxUploadResul
if (error.getErrcode() != 0) { if (error.getErrcode() != 0) {
throw new WxErrorException(error); throw new WxErrorException(error);
} }
return WxUploadResult.fromJson(responseContent); return WxMediaUploadResult.fromJson(responseContent);
} }
} }

View File

@ -32,25 +32,25 @@ public class WxCustomMessageGsonAdapter implements JsonSerializer<WxCustomMessag
messageJson.addProperty("touser", message.getTouser()); messageJson.addProperty("touser", message.getTouser());
messageJson.addProperty("msgtype", message.getMsgtype()); messageJson.addProperty("msgtype", message.getMsgtype());
if (WxConsts.MSG_TEXT.equals(message.getMsgtype())) { if (WxConsts.CUSTOM_MSG_TEXT.equals(message.getMsgtype())) {
JsonObject text = new JsonObject(); JsonObject text = new JsonObject();
text.addProperty("content", message.getContent()); text.addProperty("content", message.getContent());
messageJson.add("text", text); messageJson.add("text", text);
} }
if (WxConsts.MSG_IMAGE.equals(message.getMsgtype())) { if (WxConsts.CUSTOM_MSG_IMAGE.equals(message.getMsgtype())) {
JsonObject image = new JsonObject(); JsonObject image = new JsonObject();
image.addProperty("media_id", message.getMedia_id()); image.addProperty("media_id", message.getMedia_id());
messageJson.add("image", image); messageJson.add("image", image);
} }
if (WxConsts.MSG_VOICE.equals(message.getMsgtype())) { if (WxConsts.CUSTOM_MSG_VOICE.equals(message.getMsgtype())) {
JsonObject voice = new JsonObject(); JsonObject voice = new JsonObject();
voice.addProperty("media_id", message.getMedia_id()); voice.addProperty("media_id", message.getMedia_id());
messageJson.add("voice", voice); messageJson.add("voice", voice);
} }
if (WxConsts.MSG_VIDEO.equals(message.getMsgtype())) { if (WxConsts.CUSTOM_MSG_VIDEO.equals(message.getMsgtype())) {
JsonObject video = new JsonObject(); JsonObject video = new JsonObject();
video.addProperty("media_id", message.getMedia_id()); video.addProperty("media_id", message.getMedia_id());
video.addProperty("thumb_media_id", message.getThumb_media_id()); video.addProperty("thumb_media_id", message.getThumb_media_id());
@ -59,7 +59,7 @@ public class WxCustomMessageGsonAdapter implements JsonSerializer<WxCustomMessag
messageJson.add("video", video); messageJson.add("video", video);
} }
if (WxConsts.MSG_MUSIC.equals(message.getMsgtype())) { if (WxConsts.CUSTOM_MSG_MUSIC.equals(message.getMsgtype())) {
JsonObject music = new JsonObject(); JsonObject music = new JsonObject();
music.addProperty("title", message.getTitle()); music.addProperty("title", message.getTitle());
music.addProperty("description", message.getDescription()); music.addProperty("description", message.getDescription());
@ -69,7 +69,7 @@ public class WxCustomMessageGsonAdapter implements JsonSerializer<WxCustomMessag
messageJson.add("music", music); messageJson.add("music", music);
} }
if (WxConsts.MSG_NEWS.equals(message.getMsgtype())) { if (WxConsts.CUSTOM_MSG_NEWS.equals(message.getMsgtype())) {
JsonArray articleJsonArray = new JsonArray(); JsonArray articleJsonArray = new JsonArray();
for (WxArticle article : message.getArticles()) { for (WxArticle article : message.getArticles()) {
JsonObject articleJson = new JsonObject(); JsonObject articleJson = new JsonObject();

View File

@ -1,6 +1,8 @@
package chanjarster.weixin.util.json; package chanjarster.weixin.util.json;
import chanjarster.weixin.bean.WxCustomMessage; import chanjarster.weixin.bean.WxCustomMessage;
import chanjarster.weixin.bean.WxMassMessage;
import chanjarster.weixin.bean.WxMassNews;
import chanjarster.weixin.bean.WxMenu; import chanjarster.weixin.bean.WxMenu;
import com.google.gson.Gson; import com.google.gson.Gson;
@ -14,6 +16,8 @@ public class WxGsonBuilder {
INSTANCE.disableHtmlEscaping(); INSTANCE.disableHtmlEscaping();
INSTANCE.registerTypeAdapter(WxCustomMessage.class, new WxCustomMessageGsonAdapter()); INSTANCE.registerTypeAdapter(WxCustomMessage.class, new WxCustomMessageGsonAdapter());
INSTANCE.registerTypeAdapter(WxMenu.class, new WxMenuGsonAdapter()); INSTANCE.registerTypeAdapter(WxMenu.class, new WxMenuGsonAdapter());
INSTANCE.registerTypeAdapter(WxMassNews.class, new WxMassNewsGsonAdapter());
INSTANCE.registerTypeAdapter(WxMassMessage.class, new WxMassMessageGsonAdapter());
} }
public static Gson create() { public static Gson create() {

View File

@ -0,0 +1,74 @@
/*
* KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved.
*
* This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended
* only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction
* arose from modification of the original source, or other redistribution of this source
* is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD.
*/
package chanjarster.weixin.util.json;
import java.lang.reflect.Type;
import chanjarster.weixin.api.WxConsts;
import chanjarster.weixin.bean.WxMassMessage;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
/**
*
* @author qianjia
*
*/
public class WxMassMessageGsonAdapter implements JsonSerializer<WxMassMessage> {
public JsonElement serialize(WxMassMessage message, Type typeOfSrc, JsonSerializationContext context) {
JsonObject messageJson = new JsonObject();
if (message.getTouser().size() > 0) {
JsonArray sub = new JsonArray();
for(String openId : message.getTouser()) {
sub.add(new JsonPrimitive(openId));
}
messageJson.add("touser", sub);
} else {
JsonObject sub = new JsonObject();
sub.addProperty("group_id", message.getGroup_id());
messageJson.add("filter", sub);
}
if (WxConsts.MASS_MSG_NEWS.equals(message.getMsgtype())) {
JsonObject sub = new JsonObject();
sub.addProperty("media_id", message.getMedia_id());
messageJson.add("mpnews", sub);
}
if (WxConsts.MASS_MSG_TEXT.equals(message.getMsgtype())) {
JsonObject sub = new JsonObject();
sub.addProperty("content", message.getContent());
messageJson.add("text", sub);
}
if (WxConsts.MASS_MSG_VOICE.equals(message.getMsgtype())) {
JsonObject sub = new JsonObject();
sub.addProperty("media_id", message.getMedia_id());
messageJson.add("voice", sub);
}
if (WxConsts.MASS_MSG_IMAGE.equals(message.getMsgtype())) {
JsonObject sub = new JsonObject();
sub.addProperty("media_id", message.getMedia_id());
messageJson.add("image", sub);
}
if (WxConsts.MASS_MSG_VIDEO.equals(message.getMsgtype())) {
JsonObject sub = new JsonObject();
sub.addProperty("media_id", message.getMedia_id());
messageJson.add("mpvideo", sub);
}
messageJson.addProperty("msgtype", message.getMsgtype());
return messageJson;
}
}

View File

@ -0,0 +1,56 @@
/*
* KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved.
*
* This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended
* only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction
* arose from modification of the original source, or other redistribution of this source
* is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD.
*/
package chanjarster.weixin.util.json;
import java.lang.reflect.Type;
import chanjarster.weixin.bean.WxMassNews;
import chanjarster.weixin.bean.WxMassNews.WxMassNewsArticle;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
/**
*
* @author qianjia
*
*/
public class WxMassNewsGsonAdapter implements JsonSerializer<WxMassNews> {
public JsonElement serialize(WxMassNews message, Type typeOfSrc, JsonSerializationContext context) {
JsonObject newsJson = new JsonObject();
JsonArray articleJsonArray = new JsonArray();
for (WxMassNewsArticle article : message.getArticles()) {
JsonObject articleJson = new JsonObject();
articleJson.addProperty("thumb_media_id", article.getThumb_media_id());
articleJson.addProperty("title", article.getTitle());
articleJson.addProperty("content", article.getContent());
if (null != article.getAuthor()) {
articleJson.addProperty("author", article.getAuthor());
}
if (null != article.getContent_source_url()) {
articleJson.addProperty("content_source_url", article.getContent_source_url());
}
if (null != article.getDigest()) {
articleJson.addProperty("digest", article.getDigest());
}
articleJson.addProperty("show_cover_pic", article.isShow_cover_pic() ? "1" : "0");
articleJsonArray.add(articleJson);
}
newsJson.add("articles", articleJsonArray);
return newsJson;
}
}

View File

@ -21,18 +21,18 @@ public class WxMessageRouterTest {
this.router = new WxMessageRouter(); this.router = new WxMessageRouter();
router router
.rule() .rule()
.msgType(WxConsts.MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1").content("CONTENT_1") .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1").content("CONTENT_1")
.handler(new WxEchoMessageHandler(sb, "COMBINE_4")) .handler(new WxEchoMessageHandler(sb, "COMBINE_4"))
.end() .end()
.rule() .rule()
.msgType(WxConsts.MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1") .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1")
.handler(new WxEchoMessageHandler(sb, "COMBINE_3")) .handler(new WxEchoMessageHandler(sb, "COMBINE_3"))
.end() .end()
.rule() .rule()
.msgType(WxConsts.MSG_TEXT).event(WxConsts.EVT_CLICK) .msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK)
.handler(new WxEchoMessageHandler(sb, "COMBINE_2")) .handler(new WxEchoMessageHandler(sb, "COMBINE_2"))
.end() .end()
.rule().msgType(WxConsts.MSG_TEXT).handler(new WxEchoMessageHandler(sb, WxConsts.MSG_TEXT)).end() .rule().msgType(WxConsts.XML_MSG_TEXT).handler(new WxEchoMessageHandler(sb, WxConsts.XML_MSG_TEXT)).end()
.rule().event(WxConsts.EVT_CLICK).handler(new WxEchoMessageHandler(sb, WxConsts.EVT_CLICK)).end() .rule().event(WxConsts.EVT_CLICK).handler(new WxEchoMessageHandler(sb, WxConsts.EVT_CLICK)).end()
.rule().eventKey("KEY_1").handler(new WxEchoMessageHandler(sb, "KEY_1")).end() .rule().eventKey("KEY_1").handler(new WxEchoMessageHandler(sb, "KEY_1")).end()
.rule().content("CONTENT_1").handler(new WxEchoMessageHandler(sb, "CONTENT_1")).end() .rule().content("CONTENT_1").handler(new WxEchoMessageHandler(sb, "CONTENT_1")).end()
@ -54,7 +54,7 @@ public class WxMessageRouterTest {
@DataProvider(name="messages-1") @DataProvider(name="messages-1")
public Object[][] messages2() { public Object[][] messages2() {
WxXmlMessage message1 = new WxXmlMessage(); WxXmlMessage message1 = new WxXmlMessage();
message1.setMsgType(WxConsts.MSG_TEXT); message1.setMsgType(WxConsts.XML_MSG_TEXT);
WxXmlMessage message2 = new WxXmlMessage(); WxXmlMessage message2 = new WxXmlMessage();
message2.setEvent(WxConsts.EVT_CLICK); message2.setEvent(WxConsts.EVT_CLICK);
@ -69,22 +69,22 @@ public class WxMessageRouterTest {
message5.setContent("BLA"); message5.setContent("BLA");
WxXmlMessage c2 = new WxXmlMessage(); WxXmlMessage c2 = new WxXmlMessage();
c2.setMsgType(WxConsts.MSG_TEXT); c2.setMsgType(WxConsts.XML_MSG_TEXT);
c2.setEvent(WxConsts.EVT_CLICK); c2.setEvent(WxConsts.EVT_CLICK);
WxXmlMessage c3 = new WxXmlMessage(); WxXmlMessage c3 = new WxXmlMessage();
c3.setMsgType(WxConsts.MSG_TEXT); c3.setMsgType(WxConsts.XML_MSG_TEXT);
c3.setEvent(WxConsts.EVT_CLICK); c3.setEvent(WxConsts.EVT_CLICK);
c3.setEventKey("KEY_1"); c3.setEventKey("KEY_1");
WxXmlMessage c4 = new WxXmlMessage(); WxXmlMessage c4 = new WxXmlMessage();
c4.setMsgType(WxConsts.MSG_TEXT); c4.setMsgType(WxConsts.XML_MSG_TEXT);
c4.setEvent(WxConsts.EVT_CLICK); c4.setEvent(WxConsts.EVT_CLICK);
c4.setEventKey("KEY_1"); c4.setEventKey("KEY_1");
c4.setContent("CONTENT_1"); c4.setContent("CONTENT_1");
return new Object[][] { return new Object[][] {
new Object[] { message1, WxConsts.MSG_TEXT + "," }, new Object[] { message1, WxConsts.XML_MSG_TEXT + "," },
new Object[] { message2, WxConsts.EVT_CLICK + "," }, new Object[] { message2, WxConsts.EVT_CLICK + "," },
new Object[] { message3, "KEY_1," }, new Object[] { message3, "KEY_1," },
new Object[] { message4, "CONTENT_1," }, new Object[] { message4, "CONTENT_1," },

View File

@ -19,7 +19,7 @@ import org.testng.annotations.Test;
import chanjarster.weixin.bean.WxCustomMessage; import chanjarster.weixin.bean.WxCustomMessage;
import chanjarster.weixin.bean.WxMenu; import chanjarster.weixin.bean.WxMenu;
import chanjarster.weixin.bean.WxMenu.WxMenuButton; import chanjarster.weixin.bean.WxMenu.WxMenuButton;
import chanjarster.weixin.bean.result.WxUploadResult; import chanjarster.weixin.bean.result.WxMediaUploadResult;
import chanjarster.weixin.exception.WxErrorException; import chanjarster.weixin.exception.WxErrorException;
import chanjarster.weixin.util.xml.XmlTransformer; import chanjarster.weixin.util.xml.XmlTransformer;
@ -54,7 +54,7 @@ public class WxServiceTest {
public void sendCustomMessage() throws WxErrorException { public void sendCustomMessage() throws WxErrorException {
WxXmlConfigStorage configProvider = (WxXmlConfigStorage) wxService.wxConfigStorage; WxXmlConfigStorage configProvider = (WxXmlConfigStorage) wxService.wxConfigStorage;
WxCustomMessage message = new WxCustomMessage(); WxCustomMessage message = new WxCustomMessage();
message.setMsgtype(WxConsts.MSG_TEXT); message.setMsgtype(WxConsts.CUSTOM_MSG_TEXT);
message.setTouser(configProvider.getOpenId()); message.setTouser(configProvider.getOpenId());
message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>");
@ -79,7 +79,7 @@ public class WxServiceTest {
@Test(dependsOnMethods = { "testRefreshAccessToken" }, dataProvider="uploadMedia", enabled = true) @Test(dependsOnMethods = { "testRefreshAccessToken" }, dataProvider="uploadMedia", enabled = true)
public void testUploadMedia1(String mediaType, String fileType, String fileName) throws WxErrorException, IOException { public void testUploadMedia1(String mediaType, String fileType, String fileName) throws WxErrorException, IOException {
InputStream inputStream = ClassLoader.getSystemResourceAsStream(fileName); InputStream inputStream = ClassLoader.getSystemResourceAsStream(fileName);
WxUploadResult res = wxService.uploadMedia(mediaType, fileType, inputStream); WxMediaUploadResult res = wxService.uploadMedia(mediaType, fileType, inputStream);
Assert.assertNotNull(res.getType()); Assert.assertNotNull(res.getType());
Assert.assertNotNull(res.getCreated_at()); Assert.assertNotNull(res.getCreated_at());
Assert.assertTrue(res.getMedia_id() != null || res.getThumb_media_id() != null); Assert.assertTrue(res.getMedia_id() != null || res.getThumb_media_id() != null);

View File

@ -12,7 +12,7 @@ public class WxCustomMessageTest {
public void testTextReply() { public void testTextReply() {
WxCustomMessage reply = new WxCustomMessage(); WxCustomMessage reply = new WxCustomMessage();
reply.setTouser("OPENID"); reply.setTouser("OPENID");
reply.setMsgtype(WxConsts.MSG_TEXT); reply.setMsgtype(WxConsts.CUSTOM_MSG_TEXT);
reply.setContent("sfsfdsdf"); reply.setContent("sfsfdsdf");
Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}"); Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"text\",\"text\":{\"content\":\"sfsfdsdf\"}}");
} }
@ -20,7 +20,7 @@ public class WxCustomMessageTest {
public void testImageReply() { public void testImageReply() {
WxCustomMessage reply = new WxCustomMessage(); WxCustomMessage reply = new WxCustomMessage();
reply.setTouser("OPENID"); reply.setTouser("OPENID");
reply.setMsgtype(WxConsts.MSG_IMAGE); reply.setMsgtype(WxConsts.CUSTOM_MSG_IMAGE);
reply.setMedia_id("MEDIA_ID"); reply.setMedia_id("MEDIA_ID");
Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}"); Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"image\",\"image\":{\"media_id\":\"MEDIA_ID\"}}");
} }
@ -28,7 +28,7 @@ public class WxCustomMessageTest {
public void testVoiceReply() { public void testVoiceReply() {
WxCustomMessage reply = new WxCustomMessage(); WxCustomMessage reply = new WxCustomMessage();
reply.setTouser("OPENID"); reply.setTouser("OPENID");
reply.setMsgtype(WxConsts.MSG_VOICE); reply.setMsgtype(WxConsts.CUSTOM_MSG_VOICE);
reply.setMedia_id("MEDIA_ID"); reply.setMedia_id("MEDIA_ID");
Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"}}"); Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"voice\",\"voice\":{\"media_id\":\"MEDIA_ID\"}}");
} }
@ -36,7 +36,7 @@ public class WxCustomMessageTest {
public void testVideoReply() { public void testVideoReply() {
WxCustomMessage reply = new WxCustomMessage(); WxCustomMessage reply = new WxCustomMessage();
reply.setTouser("OPENID"); reply.setTouser("OPENID");
reply.setMsgtype(WxConsts.MSG_VIDEO); reply.setMsgtype(WxConsts.CUSTOM_MSG_VIDEO);
reply.setMedia_id("MEDIA_ID"); reply.setMedia_id("MEDIA_ID");
reply.setThumb_media_id("MEDIA_ID"); reply.setThumb_media_id("MEDIA_ID");
reply.setTitle("TITLE"); reply.setTitle("TITLE");
@ -47,7 +47,7 @@ public class WxCustomMessageTest {
public void testMusicReply() { public void testMusicReply() {
WxCustomMessage reply = new WxCustomMessage(); WxCustomMessage reply = new WxCustomMessage();
reply.setTouser("OPENID"); reply.setTouser("OPENID");
reply.setMsgtype(WxConsts.MSG_MUSIC); reply.setMsgtype(WxConsts.CUSTOM_MSG_MUSIC);
reply.setThumb_media_id("MEDIA_ID"); reply.setThumb_media_id("MEDIA_ID");
reply.setDescription("DESCRIPTION"); reply.setDescription("DESCRIPTION");
reply.setTitle("TITLE"); reply.setTitle("TITLE");
@ -59,7 +59,7 @@ public class WxCustomMessageTest {
public void testNewsReply() { public void testNewsReply() {
WxCustomMessage reply = new WxCustomMessage(); WxCustomMessage reply = new WxCustomMessage();
reply.setTouser("OPENID"); reply.setTouser("OPENID");
reply.setMsgtype(WxConsts.MSG_NEWS); reply.setMsgtype(WxConsts.CUSTOM_MSG_NEWS);
WxArticle article1 = new WxArticle(); WxArticle article1 = new WxArticle();
article1.setUrl("URL"); article1.setUrl("URL");

View File

@ -39,7 +39,7 @@ public class WxXmlMessageTest {
Assert.assertEquals(wxMessage.getToUserName(), "toUser"); Assert.assertEquals(wxMessage.getToUserName(), "toUser");
Assert.assertEquals(wxMessage.getFromUserName(), "fromUser"); Assert.assertEquals(wxMessage.getFromUserName(), "fromUser");
Assert.assertEquals(wxMessage.getCreateTime(), new Long(1348831860l)); Assert.assertEquals(wxMessage.getCreateTime(), new Long(1348831860l));
Assert.assertEquals(wxMessage.getMsgType(), WxConsts.MSG_TEXT); Assert.assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_TEXT);
Assert.assertEquals(wxMessage.getContent(), "this is a test"); Assert.assertEquals(wxMessage.getContent(), "this is a test");
Assert.assertEquals(wxMessage.getMsgId(), new Long(1234567890123456l)); Assert.assertEquals(wxMessage.getMsgId(), new Long(1234567890123456l));
Assert.assertEquals(wxMessage.getPicUrl(), "this is a url"); Assert.assertEquals(wxMessage.getPicUrl(), "this is a url");
@ -66,7 +66,7 @@ public class WxXmlMessageTest {
wxMessage.setToUserName("toUser"); wxMessage.setToUserName("toUser");
wxMessage.setFromUserName("fromUser"); wxMessage.setFromUserName("fromUser");
wxMessage.setCreateTime(new Long(1348831860l)); wxMessage.setCreateTime(new Long(1348831860l));
wxMessage.setMsgType(WxConsts.MSG_TEXT); wxMessage.setMsgType(WxConsts.XML_MSG_TEXT);
wxMessage.setContent("this is a test"); wxMessage.setContent("this is a test");
wxMessage.setMsgId(new Long(1234567890123456l)); wxMessage.setMsgId(new Long(1234567890123456l));
wxMessage.setPicUrl("this is a url"); wxMessage.setPicUrl("this is a url");