diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index 292c5645..e77b60d9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -3,19 +3,8 @@ package me.chanjar.weixin.mp.api; import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.util.http.RequestExecutor; -import me.chanjar.weixin.mp.bean.WxMpIndustry; -import me.chanjar.weixin.mp.bean.WxMpMassTagMessage; -import me.chanjar.weixin.mp.bean.WxMpMassNews; -import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage; -import me.chanjar.weixin.mp.bean.WxMpMassPreviewMessage; -import me.chanjar.weixin.mp.bean.WxMpMassVideo; -import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; -import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; -import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; -import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; -import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; -import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; -import me.chanjar.weixin.mp.bean.result.WxMpUser; +import me.chanjar.weixin.mp.bean.*; +import me.chanjar.weixin.mp.bean.result.*; /** * 微信API的Service @@ -133,16 +122,6 @@ public interface WxMpService { */ String shortUrl(String long_url) throws WxErrorException; - /** - *
- * 发送模板消息 - * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=模板消息接口 - *- * - * @return msgid - */ - String templateSend(WxMpTemplateMessage templateMessage) throws WxErrorException; - /** *
* 语义查询接口 @@ -266,27 +245,6 @@ public interface WxMpService { */ WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws Exception; - /** - *- * 设置所属行业 - * 官方文档中暂未告知响应内容 - * 详情请见:http://mp.weixin.qq.com/wiki/5/6dde9eaa909f83354e0094dc3ad99e05.html#.E8.AE.BE.E7.BD.AE.E6.89.80.E5.B1.9E.E8.A1.8C.E4.B8.9A - *- * - * @return JsonObject - */ - String setIndustry(WxMpIndustry wxMpIndustry) throws WxErrorException; - - /*** - *- * 获取设置的行业信息 - * 详情请见:http://mp.weixin.qq.com/wiki/5/6dde9eaa909f83354e0094dc3ad99e05.html#.E8.AE.BE.E7.BD.AE.E6.89.80.E5.B1.9E.E8.A1.8C.E4.B8.9A - *- * - * @return wxMpIndustry - */ - WxMpIndustry getIndustry() throws WxErrorException; - /** * 获取WxMpConfigStorage 对象 * @@ -370,4 +328,11 @@ public interface WxMpService { * @return WxMpStoreService */ WxMpStoreService getStoreService(); + + /** + * 返回模板消息相关接口方法的实现类对象,以方便调用其各种接口 + * + * @return WxMpTemplateMsgService + */ + WxMpTemplateMsgService getTemplateMsgService(); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpTemplateMsgService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpTemplateMsgService.java new file mode 100644 index 00000000..d468a89e --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpTemplateMsgService.java @@ -0,0 +1,49 @@ +package me.chanjar.weixin.mp.api; + +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.bean.WxMpIndustry; +import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; + +/** + *+ * 模板消息接口 + * http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN + * Created by Binary Wang on 2016-10-14. + * @author miller.lin + * @author binarywang(Binary Wang) + *+ */ +public interface WxMpTemplateMsgService { + + /** + *+ * 设置所属行业 + * 官方文档中暂未告知响应内容 + * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN + *+ * + * @return 是否成功 + */ + boolean setIndustry(WxMpIndustry wxMpIndustry) throws WxErrorException; + + /*** + *+ * 获取设置的行业信息 + * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN + *+ * + * @return wxMpIndustry + */ + WxMpIndustry getIndustry() throws WxErrorException; + + /** + *+ * 发送模板消息 + * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN + *+ * + * @return 消息Id + */ + String sendTemplateMsg(WxMpTemplateMessage templateMessage) throws WxErrorException; + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java index db8cfffa..7b5171f5 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java @@ -69,6 +69,8 @@ public class WxMpServiceImpl implements WxMpService { private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this); + private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this); + private CloseableHttpClient httpClient; private HttpHost httpProxy; @@ -221,35 +223,6 @@ public class WxMpServiceImpl implements WxMpService { return tmpJsonElement.getAsJsonObject().get("short_url").getAsString(); } - @Override - public String templateSend(WxMpTemplateMessage templateMessage) throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/message/template/send"; - String responseContent = this.post(url, templateMessage.toJson()); - final JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); - if (jsonObject.get("errcode").getAsInt() == 0){ - return jsonObject.get("msgid").getAsString(); - } - - throw new WxErrorException(WxError.fromJson(responseContent)); - } - - @Override - public String setIndustry(WxMpIndustry wxMpIndustry) throws WxErrorException { - if (null == wxMpIndustry.getPrimaryIndustry() || null == wxMpIndustry.getPrimaryIndustry().getId() - || null == wxMpIndustry.getSecondIndustry() || null == wxMpIndustry.getSecondIndustry().getId()) { - throw new IllegalArgumentException("industry id is empty"); - } - String url = "https://api.weixin.qq.com/cgi-bin/template/api_set_industry"; - return this.post(url, wxMpIndustry.toJson()); - } - - @Override - public WxMpIndustry getIndustry() throws WxErrorException { - String url = "https://api.weixin.qq.com/cgi-bin/template/get_industry"; - String responseContent = this.get(url, null); - return WxMpIndustry.fromJson(responseContent); - } - @Override public WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException { String url = "https://api.weixin.qq.com/semantic/semproxy/search"; @@ -562,4 +535,9 @@ public class WxMpServiceImpl implements WxMpService { return this.storeService; } + @Override + public WxMpTemplateMsgService getTemplateMsgService() { + return this.templateMsgService; + } + } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImpl.java new file mode 100644 index 00000000..d4f03ec9 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImpl.java @@ -0,0 +1,58 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import me.chanjar.weixin.common.bean.result.WxError; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.WxMpTemplateMsgService; +import me.chanjar.weixin.mp.bean.WxMpIndustry; +import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; + +/** + *+ * Created by Binary Wang on 2016-10-14. + * @author binarywang(Binary Wang) + *+ */ +public class WxMpTemplateMsgServiceImpl implements WxMpTemplateMsgService { + public static final String API_URL_PREFIX = "https://api.weixin.qq.com/cgi-bin/template"; + private static final JsonParser JSON_PARSER = new JsonParser(); + + private WxMpService wxMpService; + + public WxMpTemplateMsgServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public String sendTemplateMsg(WxMpTemplateMessage templateMessage) throws WxErrorException { + String url = "https://api.weixin.qq.com/cgi-bin/message/template/send"; + String responseContent = this.wxMpService.post(url, templateMessage.toJson()); + final JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); + if (jsonObject.get("errcode").getAsInt() == 0) { + return jsonObject.get("msgid").getAsString(); + } + throw new WxErrorException(WxError.fromJson(responseContent)); + } + + @Override + public boolean setIndustry(WxMpIndustry wxMpIndustry) throws WxErrorException { + if (null == wxMpIndustry.getPrimaryIndustry() || null == wxMpIndustry.getPrimaryIndustry().getId() + || null == wxMpIndustry.getSecondIndustry() || null == wxMpIndustry.getSecondIndustry().getId()) { + throw new IllegalArgumentException("行业Id不能为空,请核实"); + } + + String url = API_URL_PREFIX + "/api_set_industry"; + this.wxMpService.post(url, wxMpIndustry.toJson()); + return true; + } + + @Override + public WxMpIndustry getIndustry() throws WxErrorException { + String url = API_URL_PREFIX + "/get_industry"; + String responseContent = this.wxMpService.get(url, null); + return WxMpIndustry.fromJson(responseContent); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/Industry.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/Industry.java deleted file mode 100644 index da5b5134..00000000 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/Industry.java +++ /dev/null @@ -1,38 +0,0 @@ -package me.chanjar.weixin.mp.bean; - -import java.io.Serializable; - -/** - * @author miller - * 官方文档中,创建和获取的数据结构不一样。所以采用冗余字段的方式,实现相应的接口 - */ -public class Industry implements Serializable { - private static final long serialVersionUID = -1707184885588012142L; - private String id; - private String firstClass; - private String secondClass; - - public String getId() { - return this.id; - } - - public void setId(String id) { - this.id = id; - } - - public String getFirstClass() { - return this.firstClass; - } - - public void setFirstClass(String firstClass) { - this.firstClass = firstClass; - } - - public String getSecondClass() { - return this.secondClass; - } - - public void setSecondClass(String secondClass) { - this.secondClass = secondClass; - } -} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpIndustry.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpIndustry.java index 281b9315..b94fe10b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpIndustry.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpIndustry.java @@ -2,6 +2,8 @@ package me.chanjar.weixin.mp.bean; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; import java.io.Serializable; @@ -9,31 +11,97 @@ import java.io.Serializable; * @author miller */ public class WxMpIndustry implements Serializable { - private static final long serialVersionUID = -7700398224795914722L; - private Industry primaryIndustry; - private Industry secondIndustry; + private static final long serialVersionUID = -7700398224795914722L; + private Industry primaryIndustry; + private Industry secondIndustry; - public static WxMpIndustry fromJson(String json) { - return WxMpGsonBuilder.create().fromJson(json, WxMpIndustry.class); + public WxMpIndustry() { + } + + public WxMpIndustry(Industry primaryIndustry, Industry secondIndustry) { + this.primaryIndustry = primaryIndustry; + this.secondIndustry = secondIndustry; + } + + /** + * @author miller + * 官方文档中,创建和获取的数据结构不一样。所以采用冗余字段的方式,实现相应的接口 + */ + public static class Industry implements Serializable { + private static final long serialVersionUID = -1707184885588012142L; + private String id; + private String firstClass; + private String secondClass; + + public Industry() { + } + + public Industry(String id) { + this.id = id; + } + + public Industry(String id, String firstClass, String secondClass) { + this.id = id; + this.firstClass = firstClass; + this.secondClass = secondClass; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); } - public String toJson() { - return WxMpGsonBuilder.create().toJson(this); + public String getId() { + return this.id; } - public Industry getPrimaryIndustry() { - return this.primaryIndustry; + public void setId(String id) { + this.id = id; } - public void setPrimaryIndustry(Industry primaryIndustry) { - this.primaryIndustry = primaryIndustry; + public String getFirstClass() { + return this.firstClass; } - public Industry getSecondIndustry() { - return this.secondIndustry; + public void setFirstClass(String firstClass) { + this.firstClass = firstClass; } - public void setSecondIndustry(Industry secondIndustry) { - this.secondIndustry = secondIndustry; + public String getSecondClass() { + return this.secondClass; } + + public void setSecondClass(String secondClass) { + this.secondClass = secondClass; + } + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); + } + + public static WxMpIndustry fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxMpIndustry.class); + } + + public String toJson() { + return WxMpGsonBuilder.create().toJson(this); + } + + public Industry getPrimaryIndustry() { + return this.primaryIndustry; + } + + public void setPrimaryIndustry(Industry primaryIndustry) { + this.primaryIndustry = primaryIndustry; + } + + public Industry getSecondIndustry() { + return this.secondIndustry; + } + + public void setSecondIndustry(Industry secondIndustry) { + this.secondIndustry = secondIndustry; + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpIndustryGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpIndustryGsonAdapter.java index 60361249..ea715a70 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpIndustryGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpIndustryGsonAdapter.java @@ -1,19 +1,11 @@ package me.chanjar.weixin.mp.util.json; -import java.lang.reflect.Type; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; - +import com.google.gson.*; import me.chanjar.weixin.common.util.json.GsonHelper; -import me.chanjar.weixin.mp.bean.Industry; import me.chanjar.weixin.mp.bean.WxMpIndustry; +import java.lang.reflect.Type; + /** * @author miller */ @@ -42,8 +34,8 @@ public class WxMpIndustryGsonAdapter return wxMpIndustry; } - private static Industry convertFromJson(JsonObject json) { - Industry industry = new Industry(); + private static WxMpIndustry.Industry convertFromJson(JsonObject json) { + WxMpIndustry.Industry industry = new WxMpIndustry.Industry(); industry.setFirstClass(GsonHelper.getString(json, "first_class")); industry.setSecondClass(GsonHelper.getString(json, "second_class")); return industry; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImplTest.java index c108d575..49316948 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImplTest.java @@ -1,20 +1,12 @@ package me.chanjar.weixin.mp.api.impl; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.testng.Assert; -import org.testng.annotations.Guice; -import org.testng.annotations.Test; - import com.google.inject.Inject; - import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.mp.api.ApiTestModule; import me.chanjar.weixin.mp.api.WxXmlMpInMemoryConfigStorage; -import me.chanjar.weixin.mp.bean.WxMpTemplateData; -import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; +import org.testng.Assert; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; @Test @Guice(modules = ApiTestModule.class) @@ -88,20 +80,6 @@ public class WxMpServiceImplTest { Assert.fail("Not yet implemented"); } - @Test(invocationCount = 100, threadPoolSize = 30) - public void testTemplateSend() throws WxErrorException { - SimpleDateFormat dateFormat = new SimpleDateFormat( - "yyyy-MM-dd HH:mm:ss.SSS"); - WxXmlMpInMemoryConfigStorage configStorage = (WxXmlMpInMemoryConfigStorage) this.wxService - .getWxMpConfigStorage(); - WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder() - .toUser(configStorage.getOpenid()) - .templateId(configStorage.getTemplateId()).build(); - templateMessage.addWxMpTemplateData( - new WxMpTemplateData("first", dateFormat.format(new Date()))); - this.wxService.templateSend(templateMessage); - } - @Test public void testSetIndustry() { Assert.fail("Not yet implemented"); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImplTest.java new file mode 100644 index 00000000..5fb8061e --- /dev/null +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImplTest.java @@ -0,0 +1,59 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.inject.Inject; +import me.chanjar.weixin.common.exception.WxErrorException; +import me.chanjar.weixin.mp.api.ApiTestModule; +import me.chanjar.weixin.mp.api.WxXmlMpInMemoryConfigStorage; +import me.chanjar.weixin.mp.bean.WxMpIndustry; +import me.chanjar.weixin.mp.bean.WxMpTemplateData; +import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; +import org.testng.Assert; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + *+ * Created by Binary Wang on 2016-10-14. + * @author binarywang(Binary Wang) + *+ */ +@Guice(modules = ApiTestModule.class) +public class WxMpTemplateMsgServiceImplTest { + @Inject + protected WxMpServiceImpl wxService; + + @Test(invocationCount = 10, threadPoolSize = 10) + public void testSendTemplateMsg() throws WxErrorException { + SimpleDateFormat dateFormat = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss.SSS"); + WxXmlMpInMemoryConfigStorage configStorage = (WxXmlMpInMemoryConfigStorage) this.wxService + .getWxMpConfigStorage(); + WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder() + .toUser(configStorage.getOpenid()) + .templateId(configStorage.getTemplateId()).build(); + templateMessage.addWxMpTemplateData( + new WxMpTemplateData("first", dateFormat.format(new Date()))); + String msgId = this.wxService.getTemplateMsgService().sendTemplateMsg(templateMessage); + Assert.assertNotNull(msgId); + System.out.println(msgId); + } + + @Test + public void testGetIndustry() throws Exception { + final WxMpIndustry industry = this.wxService.getTemplateMsgService().getIndustry(); + Assert.assertNotNull(industry); + System.out.println(industry); + } + + @Test + public void testSetIndustry() throws Exception { + WxMpIndustry industry = new WxMpIndustry(new WxMpIndustry.Industry("1"), + new WxMpIndustry.Industry("04")); + boolean result = this.wxService.getTemplateMsgService().setIndustry(industry); + Assert.assertTrue(result); + } + +}