| @@ -0,0 +1,139 @@ | |||
| package me.chanjar.weixin.cp.bean.article; | |||
| /** | |||
| * <pre> | |||
| * Created by BinaryWang on 2017/3/27. | |||
| * </pre> | |||
| * @author Binary Wang | |||
| */ | |||
| public class MpnewsArticle { | |||
| private String title; | |||
| private String thumbMediaId; | |||
| private String author; | |||
| private String contentSourceUrl; | |||
| private String content; | |||
| private String digest; | |||
| private String showCoverPic; | |||
| private MpnewsArticle(Builder builder) { | |||
| setTitle(builder.title); | |||
| setThumbMediaId(builder.thumbMediaId); | |||
| setAuthor(builder.author); | |||
| setContentSourceUrl(builder.contentSourceUrl); | |||
| setContent(builder.content); | |||
| setDigest(builder.digest); | |||
| setShowCoverPic(builder.showCoverPic); | |||
| } | |||
| public static Builder newBuilder() { | |||
| return new Builder(); | |||
| } | |||
| public String getTitle() { | |||
| return title; | |||
| } | |||
| public void setTitle(String title) { | |||
| this.title = title; | |||
| } | |||
| public String getThumbMediaId() { | |||
| return thumbMediaId; | |||
| } | |||
| public void setThumbMediaId(String thumbMediaId) { | |||
| this.thumbMediaId = thumbMediaId; | |||
| } | |||
| public String getAuthor() { | |||
| return author; | |||
| } | |||
| public void setAuthor(String author) { | |||
| this.author = author; | |||
| } | |||
| public String getContentSourceUrl() { | |||
| return contentSourceUrl; | |||
| } | |||
| public void setContentSourceUrl(String contentSourceUrl) { | |||
| this.contentSourceUrl = contentSourceUrl; | |||
| } | |||
| 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 String getShowCoverPic() { | |||
| return showCoverPic; | |||
| } | |||
| public void setShowCoverPic(String showCoverPic) { | |||
| this.showCoverPic = showCoverPic; | |||
| } | |||
| public static final class Builder { | |||
| private String title; | |||
| private String thumbMediaId; | |||
| private String author; | |||
| private String contentSourceUrl; | |||
| private String content; | |||
| private String digest; | |||
| private String showCoverPic; | |||
| private Builder() { | |||
| } | |||
| public Builder title(String title) { | |||
| this.title = title; | |||
| return this; | |||
| } | |||
| public Builder thumbMediaId(String thumbMediaId) { | |||
| this.thumbMediaId = thumbMediaId; | |||
| return this; | |||
| } | |||
| public Builder author(String author) { | |||
| this.author = author; | |||
| return this; | |||
| } | |||
| public Builder contentSourceUrl(String contentSourceUrl) { | |||
| this.contentSourceUrl = contentSourceUrl; | |||
| return this; | |||
| } | |||
| public Builder content(String content) { | |||
| this.content = content; | |||
| return this; | |||
| } | |||
| public Builder digest(String digest) { | |||
| this.digest = digest; | |||
| return this; | |||
| } | |||
| public Builder showCoverPic(String showCoverPic) { | |||
| this.showCoverPic = showCoverPic; | |||
| return this; | |||
| } | |||
| public MpnewsArticle build() { | |||
| return new MpnewsArticle(this); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,49 @@ | |||
| package me.chanjar.weixin.cp.bean.article; | |||
| /** | |||
| * <pre> | |||
| * Created by BinaryWang on 2017/3/27. | |||
| * </pre> | |||
| * | |||
| * @author Binary Wang | |||
| */ | |||
| public class NewArticle { | |||
| private String title; | |||
| private String description; | |||
| private String url; | |||
| private String picUrl; | |||
| public String getTitle() { | |||
| return this.title; | |||
| } | |||
| public void setTitle(String title) { | |||
| this.title = title; | |||
| } | |||
| public String getDescription() { | |||
| return this.description; | |||
| } | |||
| public void setDescription(String description) { | |||
| this.description = description; | |||
| } | |||
| public String getUrl() { | |||
| return this.url; | |||
| } | |||
| public void setUrl(String url) { | |||
| this.url = url; | |||
| } | |||
| public String getPicUrl() { | |||
| return this.picUrl; | |||
| } | |||
| public void setPicUrl(String picUrl) { | |||
| this.picUrl = picUrl; | |||
| } | |||
| } | |||
| @@ -1,5 +1,7 @@ | |||
| package me.chanjar.weixin.cp.bean; | |||
| import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | |||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | |||
| import me.chanjar.weixin.cp.bean.messagebuilder.*; | |||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||
| @@ -28,7 +30,16 @@ public class WxCpMessage implements Serializable { | |||
| private String musicUrl; | |||
| private String hqMusicUrl; | |||
| private String safe; | |||
| private List<WxArticle> articles = new ArrayList<>(); | |||
| private List<NewArticle> articles = new ArrayList<>(); | |||
| private List<MpnewsArticle> mpnewsArticles = new ArrayList<>(); | |||
| public List<MpnewsArticle> getMpnewsArticles() { | |||
| return mpnewsArticles; | |||
| } | |||
| public void setMpnewsArticles(List<MpnewsArticle> mpnewsArticles) { | |||
| this.mpnewsArticles = mpnewsArticles; | |||
| } | |||
| /** | |||
| * 获得文本消息builder | |||
| @@ -65,6 +76,13 @@ public class WxCpMessage implements Serializable { | |||
| return new NewsBuilder(); | |||
| } | |||
| /** | |||
| * 获得mpnews图文消息builder | |||
| */ | |||
| public static MpnewsBuilder MPNEWS() { | |||
| return new MpnewsBuilder(); | |||
| } | |||
| /** | |||
| * 获得文件消息builder | |||
| */ | |||
| @@ -117,9 +135,10 @@ public class WxCpMessage implements Serializable { | |||
| * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_MUSIC} | |||
| * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_VIDEO} | |||
| * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_NEWS} | |||
| * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_MPNEWS} | |||
| * </pre> | |||
| * | |||
| * @param msgType | |||
| * @param msgType 消息类型 | |||
| */ | |||
| public void setMsgType(String msgType) { | |||
| this.msgType = msgType; | |||
| @@ -189,11 +208,11 @@ public class WxCpMessage implements Serializable { | |||
| this.hqMusicUrl = hqMusicUrl; | |||
| } | |||
| public List<WxArticle> getArticles() { | |||
| public List<NewArticle> getArticles() { | |||
| return this.articles; | |||
| } | |||
| public void setArticles(List<WxArticle> articles) { | |||
| public void setArticles(List<NewArticle> articles) { | |||
| this.articles = articles; | |||
| } | |||
| @@ -201,45 +220,4 @@ public class WxCpMessage implements Serializable { | |||
| return WxCpGsonBuilder.INSTANCE.create().toJson(this); | |||
| } | |||
| public static class WxArticle { | |||
| private String title; | |||
| private String description; | |||
| private String url; | |||
| private String picUrl; | |||
| public String getTitle() { | |||
| return this.title; | |||
| } | |||
| public void setTitle(String title) { | |||
| this.title = title; | |||
| } | |||
| public String getDescription() { | |||
| return this.description; | |||
| } | |||
| public void setDescription(String description) { | |||
| this.description = description; | |||
| } | |||
| public String getUrl() { | |||
| return this.url; | |||
| } | |||
| public void setUrl(String url) { | |||
| this.url = url; | |||
| } | |||
| public String getPicUrl() { | |||
| return this.picUrl; | |||
| } | |||
| public void setPicUrl(String picUrl) { | |||
| this.picUrl = picUrl; | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,48 @@ | |||
| package me.chanjar.weixin.cp.bean.messagebuilder; | |||
| import me.chanjar.weixin.common.api.WxConsts; | |||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
| import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| /** | |||
| * mpnews类型的图文消息builder | |||
| * <pre> | |||
| * 用法: | |||
| * WxCustomMessage m = WxCustomMessage.MPNEWS().addArticle(article).toUser(...).build(); | |||
| * </pre> | |||
| * | |||
| * @author Binary Wang | |||
| */ | |||
| public final class MpnewsBuilder extends BaseBuilder<MpnewsBuilder> { | |||
| private List<MpnewsArticle> articles = new ArrayList<>(); | |||
| private String mediaId; | |||
| public MpnewsBuilder() { | |||
| this.msgType = WxConsts.CUSTOM_MSG_MPNEWS; | |||
| } | |||
| public MpnewsBuilder mediaId(String mediaId) { | |||
| this.mediaId = mediaId; | |||
| return this; | |||
| } | |||
| public MpnewsBuilder addArticle(MpnewsArticle article) { | |||
| this.articles.add(article); | |||
| return this; | |||
| } | |||
| @Override | |||
| public WxCpMessage build() { | |||
| WxCpMessage m = super.build(); | |||
| m.setMpnewsArticles(this.articles); | |||
| if (this.mediaId != null) { | |||
| m.setMediaId(this.mediaId); | |||
| } | |||
| return m; | |||
| } | |||
| } | |||
| @@ -2,6 +2,7 @@ package me.chanjar.weixin.cp.bean.messagebuilder; | |||
| import me.chanjar.weixin.common.api.WxConsts; | |||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | |||
| import java.util.ArrayList; | |||
| import java.util.List; | |||
| @@ -17,13 +18,13 @@ import java.util.List; | |||
| */ | |||
| public final class NewsBuilder extends BaseBuilder<NewsBuilder> { | |||
| private List<WxCpMessage.WxArticle> articles = new ArrayList<>(); | |||
| private List<NewArticle> articles = new ArrayList<>(); | |||
| public NewsBuilder() { | |||
| this.msgType = WxConsts.CUSTOM_MSG_NEWS; | |||
| } | |||
| public NewsBuilder addArticle(WxCpMessage.WxArticle article) { | |||
| public NewsBuilder addArticle(NewArticle article) { | |||
| this.articles.add(article); | |||
| return this; | |||
| } | |||
| @@ -11,6 +11,8 @@ package me.chanjar.weixin.cp.util.json; | |||
| import com.google.gson.*; | |||
| import me.chanjar.weixin.common.api.WxConsts; | |||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
| import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | |||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import java.lang.reflect.Type; | |||
| @@ -71,7 +73,7 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { | |||
| if (WxConsts.CUSTOM_MSG_NEWS.equals(message.getMsgType())) { | |||
| JsonObject newsJsonObject = new JsonObject(); | |||
| JsonArray articleJsonArray = new JsonArray(); | |||
| for (WxCpMessage.WxArticle article : message.getArticles()) { | |||
| for (NewArticle article : message.getArticles()) { | |||
| JsonObject articleJson = new JsonObject(); | |||
| articleJson.addProperty("title", article.getTitle()); | |||
| articleJson.addProperty("description", article.getDescription()); | |||
| @@ -83,6 +85,29 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { | |||
| messageJson.add("news", newsJsonObject); | |||
| } | |||
| if (WxConsts.CUSTOM_MSG_MPNEWS.equals(message.getMsgType())) { | |||
| JsonObject newsJsonObject = new JsonObject(); | |||
| if (message.getMediaId() != null) { | |||
| newsJsonObject.addProperty("media_id", message.getMediaId()); | |||
| }else { | |||
| JsonArray articleJsonArray = new JsonArray(); | |||
| for (MpnewsArticle article : message.getMpnewsArticles()) { | |||
| JsonObject articleJson = new JsonObject(); | |||
| articleJson.addProperty("title", article.getTitle()); | |||
| articleJson.addProperty("thumb_media_id", article.getThumbMediaId()); | |||
| articleJson.addProperty("author", article.getAuthor()); | |||
| articleJson.addProperty("content_source_url", article.getContentSourceUrl()); | |||
| articleJson.addProperty("content", article.getContent()); | |||
| articleJson.addProperty("digest", article.getDigest()); | |||
| articleJson.addProperty("show_cover_pic", article.getShowCoverPic()); | |||
| articleJsonArray.add(articleJson); | |||
| } | |||
| newsJsonObject.add("articles", articleJsonArray); | |||
| } | |||
| messageJson.add("mpnews", newsJsonObject); | |||
| } | |||
| return messageJson; | |||
| } | |||
| @@ -1,7 +1,8 @@ | |||
| package me.chanjar.weixin.cp.bean; | |||
| import me.chanjar.weixin.common.api.WxConsts; | |||
| import me.chanjar.weixin.cp.bean.WxCpMessage.WxArticle; | |||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | |||
| import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | |||
| import org.testng.Assert; | |||
| import org.testng.annotations.Test; | |||
| @@ -68,14 +69,14 @@ public class WxCpMessageTest { | |||
| reply.setToUser("OPENID"); | |||
| reply.setMsgType(WxConsts.CUSTOM_MSG_NEWS); | |||
| WxArticle article1 = new WxArticle(); | |||
| NewArticle article1 = new NewArticle(); | |||
| article1.setUrl("URL"); | |||
| article1.setPicUrl("PIC_URL"); | |||
| article1.setDescription("Is Really A Happy Day"); | |||
| article1.setTitle("Happy Day"); | |||
| reply.getArticles().add(article1); | |||
| WxArticle article2 = new WxArticle(); | |||
| NewArticle article2 = new NewArticle(); | |||
| article2.setUrl("URL"); | |||
| article2.setPicUrl("PIC_URL"); | |||
| article2.setDescription("Is Really A Happy Day"); | |||
| @@ -87,13 +88,13 @@ public class WxCpMessageTest { | |||
| } | |||
| public void testNewsBuild() { | |||
| WxArticle article1 = new WxArticle(); | |||
| NewArticle article1 = new NewArticle(); | |||
| article1.setUrl("URL"); | |||
| article1.setPicUrl("PIC_URL"); | |||
| article1.setDescription("Is Really A Happy Day"); | |||
| article1.setTitle("Happy Day"); | |||
| WxArticle article2 = new WxArticle(); | |||
| NewArticle article2 = new NewArticle(); | |||
| article2.setUrl("URL"); | |||
| article2.setPicUrl("PIC_URL"); | |||
| article2.setDescription("Is Really A Happy Day"); | |||
| @@ -104,4 +105,39 @@ public class WxCpMessageTest { | |||
| Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); | |||
| } | |||
| public void testMpnewsBuild_with_articles() { | |||
| MpnewsArticle article1 = MpnewsArticle.newBuilder() | |||
| .title("Happy Day") | |||
| .author("aaaaaa") | |||
| .content("hahaha") | |||
| .contentSourceUrl("nice url") | |||
| .digest("digest") | |||
| .showCoverPic("heihei") | |||
| .thumbMediaId("thumb") | |||
| .build(); | |||
| MpnewsArticle article2 = MpnewsArticle.newBuilder() | |||
| .title("Happy Day") | |||
| .author("aaaaaa") | |||
| .content("hahaha") | |||
| .contentSourceUrl("nice url") | |||
| .digest("digest") | |||
| .showCoverPic("heihei") | |||
| .thumbMediaId("thumb") | |||
| .build(); | |||
| WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build(); | |||
| Assert.assertEquals(reply.toJson(), "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\"," + | |||
| "\"mpnews\":{\"articles\":[{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}," + | |||
| "{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}]}}"); | |||
| } | |||
| public void testMpnewsBuild_with_media_id() { | |||
| WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").mediaId("mmm").build(); | |||
| Assert.assertEquals(reply.toJson(), | |||
| "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"mpnews\":{\"media_id\":\"mmm\"}}"); | |||
| } | |||
| } | |||