| @@ -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; | 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.bean.messagebuilder.*; | ||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
| @@ -28,7 +30,16 @@ public class WxCpMessage implements Serializable { | |||||
| private String musicUrl; | private String musicUrl; | ||||
| private String hqMusicUrl; | private String hqMusicUrl; | ||||
| private String safe; | 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 | * 获得文本消息builder | ||||
| @@ -65,6 +76,13 @@ public class WxCpMessage implements Serializable { | |||||
| return new NewsBuilder(); | return new NewsBuilder(); | ||||
| } | } | ||||
| /** | |||||
| * 获得mpnews图文消息builder | |||||
| */ | |||||
| public static MpnewsBuilder MPNEWS() { | |||||
| return new MpnewsBuilder(); | |||||
| } | |||||
| /** | /** | ||||
| * 获得文件消息builder | * 获得文件消息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_MUSIC} | ||||
| * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_VIDEO} | * {@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_NEWS} | ||||
| * {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_MPNEWS} | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @param msgType | |||||
| * @param msgType 消息类型 | |||||
| */ | */ | ||||
| public void setMsgType(String msgType) { | public void setMsgType(String msgType) { | ||||
| this.msgType = msgType; | this.msgType = msgType; | ||||
| @@ -189,11 +208,11 @@ public class WxCpMessage implements Serializable { | |||||
| this.hqMusicUrl = hqMusicUrl; | this.hqMusicUrl = hqMusicUrl; | ||||
| } | } | ||||
| public List<WxArticle> getArticles() { | |||||
| public List<NewArticle> getArticles() { | |||||
| return this.articles; | return this.articles; | ||||
| } | } | ||||
| public void setArticles(List<WxArticle> articles) { | |||||
| public void setArticles(List<NewArticle> articles) { | |||||
| this.articles = articles; | this.articles = articles; | ||||
| } | } | ||||
| @@ -201,45 +220,4 @@ public class WxCpMessage implements Serializable { | |||||
| return WxCpGsonBuilder.INSTANCE.create().toJson(this); | 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.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | import me.chanjar.weixin.cp.bean.WxCpMessage; | ||||
| import me.chanjar.weixin.cp.bean.article.NewArticle; | |||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| import java.util.List; | import java.util.List; | ||||
| @@ -17,13 +18,13 @@ import java.util.List; | |||||
| */ | */ | ||||
| public final class NewsBuilder extends BaseBuilder<NewsBuilder> { | public final class NewsBuilder extends BaseBuilder<NewsBuilder> { | ||||
| private List<WxCpMessage.WxArticle> articles = new ArrayList<>(); | |||||
| private List<NewArticle> articles = new ArrayList<>(); | |||||
| public NewsBuilder() { | public NewsBuilder() { | ||||
| this.msgType = WxConsts.CUSTOM_MSG_NEWS; | this.msgType = WxConsts.CUSTOM_MSG_NEWS; | ||||
| } | } | ||||
| public NewsBuilder addArticle(WxCpMessage.WxArticle article) { | |||||
| public NewsBuilder addArticle(NewArticle article) { | |||||
| this.articles.add(article); | this.articles.add(article); | ||||
| return this; | return this; | ||||
| } | } | ||||
| @@ -11,6 +11,8 @@ package me.chanjar.weixin.cp.util.json; | |||||
| import com.google.gson.*; | import com.google.gson.*; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | import me.chanjar.weixin.common.api.WxConsts; | ||||
| import me.chanjar.weixin.cp.bean.WxCpMessage; | 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 org.apache.commons.lang3.StringUtils; | ||||
| import java.lang.reflect.Type; | import java.lang.reflect.Type; | ||||
| @@ -71,7 +73,7 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { | |||||
| if (WxConsts.CUSTOM_MSG_NEWS.equals(message.getMsgType())) { | if (WxConsts.CUSTOM_MSG_NEWS.equals(message.getMsgType())) { | ||||
| JsonObject newsJsonObject = new JsonObject(); | JsonObject newsJsonObject = new JsonObject(); | ||||
| JsonArray articleJsonArray = new JsonArray(); | JsonArray articleJsonArray = new JsonArray(); | ||||
| for (WxCpMessage.WxArticle article : message.getArticles()) { | |||||
| for (NewArticle article : message.getArticles()) { | |||||
| JsonObject articleJson = new JsonObject(); | JsonObject articleJson = new JsonObject(); | ||||
| articleJson.addProperty("title", article.getTitle()); | articleJson.addProperty("title", article.getTitle()); | ||||
| articleJson.addProperty("description", article.getDescription()); | articleJson.addProperty("description", article.getDescription()); | ||||
| @@ -83,6 +85,29 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { | |||||
| messageJson.add("news", newsJsonObject); | 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; | return messageJson; | ||||
| } | } | ||||
| @@ -1,7 +1,8 @@ | |||||
| package me.chanjar.weixin.cp.bean; | package me.chanjar.weixin.cp.bean; | ||||
| import me.chanjar.weixin.common.api.WxConsts; | 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.Assert; | ||||
| import org.testng.annotations.Test; | import org.testng.annotations.Test; | ||||
| @@ -68,14 +69,14 @@ public class WxCpMessageTest { | |||||
| reply.setToUser("OPENID"); | reply.setToUser("OPENID"); | ||||
| reply.setMsgType(WxConsts.CUSTOM_MSG_NEWS); | reply.setMsgType(WxConsts.CUSTOM_MSG_NEWS); | ||||
| WxArticle article1 = new WxArticle(); | |||||
| NewArticle article1 = new NewArticle(); | |||||
| article1.setUrl("URL"); | article1.setUrl("URL"); | ||||
| article1.setPicUrl("PIC_URL"); | article1.setPicUrl("PIC_URL"); | ||||
| article1.setDescription("Is Really A Happy Day"); | article1.setDescription("Is Really A Happy Day"); | ||||
| article1.setTitle("Happy Day"); | article1.setTitle("Happy Day"); | ||||
| reply.getArticles().add(article1); | reply.getArticles().add(article1); | ||||
| WxArticle article2 = new WxArticle(); | |||||
| NewArticle article2 = new NewArticle(); | |||||
| article2.setUrl("URL"); | article2.setUrl("URL"); | ||||
| article2.setPicUrl("PIC_URL"); | article2.setPicUrl("PIC_URL"); | ||||
| article2.setDescription("Is Really A Happy Day"); | article2.setDescription("Is Really A Happy Day"); | ||||
| @@ -87,13 +88,13 @@ public class WxCpMessageTest { | |||||
| } | } | ||||
| public void testNewsBuild() { | public void testNewsBuild() { | ||||
| WxArticle article1 = new WxArticle(); | |||||
| NewArticle article1 = new NewArticle(); | |||||
| article1.setUrl("URL"); | article1.setUrl("URL"); | ||||
| article1.setPicUrl("PIC_URL"); | article1.setPicUrl("PIC_URL"); | ||||
| article1.setDescription("Is Really A Happy Day"); | article1.setDescription("Is Really A Happy Day"); | ||||
| article1.setTitle("Happy Day"); | article1.setTitle("Happy Day"); | ||||
| WxArticle article2 = new WxArticle(); | |||||
| NewArticle article2 = new NewArticle(); | |||||
| article2.setUrl("URL"); | article2.setUrl("URL"); | ||||
| article2.setPicUrl("PIC_URL"); | article2.setPicUrl("PIC_URL"); | ||||
| article2.setDescription("Is Really A Happy Day"); | 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\"}]}}"); | 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\"}}"); | |||||
| } | |||||
| } | } | ||||