Просмотр исходного кода

将模板消息相关接口代码移到单独的service,并作相应重构调整,增加单元测试 for issue #63

master
Binary Wang 8 лет назад
Родитель
Сommit
77db3c2dae
9 измененных файлов: 273 добавлений и 164 удалений
  1. +9
    -44
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
  2. +49
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpTemplateMsgService.java
  3. +7
    -29
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java
  4. +58
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImpl.java
  5. +0
    -38
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/Industry.java
  6. +83
    -15
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpIndustry.java
  7. +5
    -13
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpIndustryGsonAdapter.java
  8. +3
    -25
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImplTest.java
  9. +59
    -0
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpTemplateMsgServiceImplTest.java

+ 9
- 44
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;

/**
* <pre>
* 发送模板消息
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=模板消息接口
* </pre>
*
* @return msgid
*/
String templateSend(WxMpTemplateMessage templateMessage) throws WxErrorException;

/**
* <pre>
* 语义查询接口
@@ -266,27 +245,6 @@ public interface WxMpService {
*/
WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws Exception;

/**
* <pre>
* 设置所属行业
* 官方文档中暂未告知响应内容
* 详情请见: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
* </pre>
*
* @return JsonObject
*/
String setIndustry(WxMpIndustry wxMpIndustry) throws WxErrorException;

/***
* <pre>
* 获取设置的行业信息
* 详情请见: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
* </pre>
*
* @return wxMpIndustry
*/
WxMpIndustry getIndustry() throws WxErrorException;

/**
* 获取WxMpConfigStorage 对象
*
@@ -370,4 +328,11 @@ public interface WxMpService {
* @return WxMpStoreService
*/
WxMpStoreService getStoreService();

/**
* 返回模板消息相关接口方法的实现类对象,以方便调用其各种接口
*
* @return WxMpTemplateMsgService
*/
WxMpTemplateMsgService getTemplateMsgService();
}

+ 49
- 0
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;

/**
* <pre>
* 模板消息接口
* 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 <a href="https://github.com/binarywang">binarywang(Binary Wang)</a>
* </pre>
*/
public interface WxMpTemplateMsgService {

/**
* <pre>
* 设置所属行业
* 官方文档中暂未告知响应内容
* 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN
* </pre>
*
* @return 是否成功
*/
boolean setIndustry(WxMpIndustry wxMpIndustry) throws WxErrorException;

/***
* <pre>
* 获取设置的行业信息
* 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN
* </pre>
*
* @return wxMpIndustry
*/
WxMpIndustry getIndustry() throws WxErrorException;

/**
* <pre>
* 发送模板消息
* 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN
* </pre>
*
* @return 消息Id
*/
String sendTemplateMsg(WxMpTemplateMessage templateMessage) throws WxErrorException;

}

+ 7
- 29
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;
}

}

+ 58
- 0
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;

/**
* <pre>
* Created by Binary Wang on 2016-10-14.
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a>
* </pre>
*/
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);
}

}

+ 0
- 38
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/Industry.java Просмотреть файл

@@ -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;
}
}

+ 83
- 15
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;
}
}

+ 5
- 13
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;


+ 3
- 25
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");


+ 59
- 0
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;

/**
* <pre>
* Created by Binary Wang on 2016-10-14.
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a>
* </pre>
*/
@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);
}

}

Загрузка…
Отмена
Сохранить