@@ -0,0 +1,62 @@ | |||
package me.chanjar.weixin.mp.api; | |||
import me.chanjar.weixin.common.bean.WxMenu; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest; | |||
import me.chanjar.weixin.mp.bean.kefu.result.*; | |||
import java.io.File; | |||
import java.util.Date; | |||
/** | |||
* 菜单相关操作接口 | |||
* @author Binary Wang | |||
* | |||
*/ | |||
public interface WxMpMenuService { | |||
/** | |||
* <pre> | |||
* 自定义菜单创建接口 | |||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=自定义菜单创建接口 | |||
* 如果要创建个性化菜单,请设置matchrule属性 | |||
* 详情请见:http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html | |||
* </pre> | |||
*/ | |||
public void menuCreate(WxMenu menu) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 自定义菜单删除接口 | |||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=自定义菜单删除接口 | |||
* </pre> | |||
*/ | |||
public void menuDelete() throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 删除个性化菜单接口 | |||
* 详情请见: http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html | |||
* </pre> | |||
* @param menuid | |||
*/ | |||
public void menuDelete(String menuid) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 自定义菜单查询接口 | |||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=自定义菜单查询接口 | |||
* </pre> | |||
*/ | |||
public WxMenu menuGet() throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 测试个性化菜单匹配结果 | |||
* 详情请见: http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html | |||
* </pre> | |||
* @param userid 可以是粉丝的OpenID,也可以是粉丝的微信号。 | |||
*/ | |||
public WxMenu menuTryMatch(String userid) throws WxErrorException; | |||
} |
@@ -1,8 +1,6 @@ | |||
package me.chanjar.weixin.mp.api; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
import java.util.List; | |||
@@ -10,8 +8,6 @@ import java.util.Map; | |||
import me.chanjar.weixin.common.bean.WxCardApiSignature; | |||
import me.chanjar.weixin.common.bean.WxJsapiSignature; | |||
import me.chanjar.weixin.common.bean.WxMenu; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||
@@ -22,20 +18,11 @@ 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.WxMpMaterial; | |||
import me.chanjar.weixin.mp.bean.WxMpMaterialArticleUpdate; | |||
import me.chanjar.weixin.mp.bean.WxMpMaterialNews; | |||
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; | |||
import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; | |||
import me.chanjar.weixin.mp.bean.result.WxMediaImgUploadResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpCardResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialCountResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialFileBatchGetResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialNewsBatchGetResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialUploadResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialVideoInfoResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | |||
import me.chanjar.weixin.mp.bean.result.WxMpPayCallback; | |||
import me.chanjar.weixin.mp.bean.result.WxMpPayRefundResult; | |||
@@ -161,50 +148,6 @@ public interface WxMpService { | |||
*/ | |||
public WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 自定义菜单创建接口 | |||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=自定义菜单创建接口 | |||
* 如果要创建个性化菜单,请设置matchrule属性 | |||
* 详情请见:http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html | |||
* </pre> | |||
*/ | |||
public void menuCreate(WxMenu menu) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 自定义菜单删除接口 | |||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=自定义菜单删除接口 | |||
* </pre> | |||
*/ | |||
public void menuDelete() throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 删除个性化菜单接口 | |||
* 详情请见: http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html | |||
* </pre> | |||
* @param menuid | |||
*/ | |||
public void menuDelete(String menuid) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 自定义菜单查询接口 | |||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=自定义菜单查询接口 | |||
* </pre> | |||
*/ | |||
public WxMenu menuGet() throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 测试个性化菜单匹配结果 | |||
* 详情请见: http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html | |||
* </pre> | |||
* @param userid 可以是粉丝的OpenID,也可以是粉丝的微信号。 | |||
*/ | |||
public WxMenu menuTryMatch(String userid) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 分组管理接口 - 创建分组 | |||
@@ -760,11 +703,17 @@ public interface WxMpService { | |||
WxMpKefuService getKefuService(); | |||
/** | |||
* 返回客服接口方法实现类,以方便调用个其各种接口 | |||
* 返回素材相关接口的方法实现类,以方便调用个其各种接口 | |||
* @return WxMpMaterialService | |||
*/ | |||
WxMpMaterialService getMaterialService(); | |||
/** | |||
* 返回素材相关接口的方法实现类,以方便调用个其各种接口 | |||
* @return WxMpMenuService | |||
*/ | |||
WxMpMenuService getMenuService(); | |||
/** | |||
* 获取WxMpConfigStorage 对象 | |||
* @return WxMpConfigStorage | |||
@@ -2,7 +2,6 @@ package me.chanjar.weixin.mp.api; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.StringReader; | |||
import java.io.UnsupportedEncodingException; | |||
import java.net.URLEncoder; | |||
@@ -16,9 +15,7 @@ import java.util.Map; | |||
import java.util.Map.Entry; | |||
import java.util.SortedMap; | |||
import java.util.TreeMap; | |||
import java.util.UUID; | |||
import me.chanjar.weixin.mp.api.impl.WxMpMaterialServiceImpl; | |||
import org.apache.http.Consts; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.client.ClientProtocolException; | |||
@@ -44,33 +41,28 @@ import com.google.gson.reflect.TypeToken; | |||
import com.google.gson.stream.JsonReader; | |||
import com.thoughtworks.xstream.XStream; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.bean.WxCardApiSignature; | |||
import me.chanjar.weixin.common.bean.WxJsapiSignature; | |||
import me.chanjar.weixin.common.bean.WxMenu; | |||
import me.chanjar.weixin.common.bean.result.WxError; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.session.StandardSessionManager; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.common.util.RandomUtils; | |||
import me.chanjar.weixin.common.util.crypto.SHA1; | |||
import me.chanjar.weixin.common.util.crypto.WxCryptUtil; | |||
import me.chanjar.weixin.common.util.fs.FileUtils; | |||
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; | |||
import me.chanjar.weixin.common.util.http.DefaultApacheHttpHttpClientBuilder; | |||
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.URIUtil; | |||
import me.chanjar.weixin.common.util.http.Utf8ResponseHandler; | |||
import me.chanjar.weixin.common.util.json.GsonHelper; | |||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||
import me.chanjar.weixin.common.util.xml.XStreamInitializer; | |||
import me.chanjar.weixin.mp.api.impl.WxMpKefuServiceImpl; | |||
import me.chanjar.weixin.mp.api.impl.WxMpMaterialServiceImpl; | |||
import me.chanjar.weixin.mp.api.impl.WxMpMenuServiceImpl; | |||
import me.chanjar.weixin.mp.bean.WxMpCustomMessage; | |||
import me.chanjar.weixin.mp.bean.WxMpGroup; | |||
import me.chanjar.weixin.mp.bean.WxMpIndustry; | |||
@@ -79,20 +71,11 @@ 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.WxMpMaterial; | |||
import me.chanjar.weixin.mp.bean.WxMpMaterialArticleUpdate; | |||
import me.chanjar.weixin.mp.bean.WxMpMaterialNews; | |||
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; | |||
import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; | |||
import me.chanjar.weixin.mp.bean.result.WxMediaImgUploadResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpCardResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialCountResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialFileBatchGetResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialNewsBatchGetResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialUploadResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpMaterialVideoInfoResult; | |||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; | |||
import me.chanjar.weixin.mp.bean.result.WxMpPayCallback; | |||
import me.chanjar.weixin.mp.bean.result.WxMpPayRefundResult; | |||
@@ -105,12 +88,6 @@ import me.chanjar.weixin.mp.bean.result.WxMpUserCumulate; | |||
import me.chanjar.weixin.mp.bean.result.WxMpUserList; | |||
import me.chanjar.weixin.mp.bean.result.WxMpUserSummary; | |||
import me.chanjar.weixin.mp.bean.result.WxRedpackResult; | |||
import me.chanjar.weixin.mp.util.http.MaterialDeleteRequestExecutor; | |||
import me.chanjar.weixin.mp.util.http.MaterialNewsInfoRequestExecutor; | |||
import me.chanjar.weixin.mp.util.http.MaterialUploadRequestExecutor; | |||
import me.chanjar.weixin.mp.util.http.MaterialVideoInfoRequestExecutor; | |||
import me.chanjar.weixin.mp.util.http.MaterialVoiceAndImageDownloadRequestExecutor; | |||
import me.chanjar.weixin.mp.util.http.MediaImgUploadRequestExecutor; | |||
import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; | |||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||
@@ -139,6 +116,8 @@ public class WxMpServiceImpl implements WxMpService { | |||
protected WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this); | |||
protected WxMpMenuService menuService = new WxMpMenuServiceImpl(this); | |||
protected CloseableHttpClient httpClient; | |||
protected HttpHost httpProxy; | |||
@@ -259,59 +238,6 @@ public class WxMpServiceImpl implements WxMpService { | |||
execute(new SimplePostRequestExecutor(), url, message.toJson()); | |||
} | |||
@Override | |||
public void menuCreate(WxMenu menu) throws WxErrorException { | |||
if (menu.getMatchRule() != null) { | |||
String url = "https://api.weixin.qq.com/cgi-bin/menu/addconditional"; | |||
execute(new SimplePostRequestExecutor(), url, menu.toJson()); | |||
} else { | |||
String url = "https://api.weixin.qq.com/cgi-bin/menu/create"; | |||
execute(new SimplePostRequestExecutor(), url, menu.toJson()); | |||
} | |||
} | |||
@Override | |||
public void menuDelete() throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/menu/delete"; | |||
execute(new SimpleGetRequestExecutor(), url, null); | |||
} | |||
@Override | |||
public void menuDelete(String menuid) throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/menu/delconditional"; | |||
execute(new SimpleGetRequestExecutor(), url, "menuid=" + menuid); | |||
} | |||
@Override | |||
public WxMenu menuGet() throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/menu/get"; | |||
try { | |||
String resultContent = execute(new SimpleGetRequestExecutor(), url, null); | |||
return WxMenu.fromJson(resultContent); | |||
} catch (WxErrorException e) { | |||
// 46003 不存在的菜单数据 | |||
if (e.getError().getErrorCode() == 46003) { | |||
return null; | |||
} | |||
throw e; | |||
} | |||
} | |||
@Override | |||
public WxMenu menuTryMatch(String userid) throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/menu/trymatch"; | |||
try { | |||
String resultContent = execute(new SimpleGetRequestExecutor(), url, "user_id=" + userid); | |||
return WxMenu.fromJson(resultContent); | |||
} catch (WxErrorException e) { | |||
// 46003 不存在的菜单数据 46002 不存在的菜单版本 | |||
if (e.getError().getErrorCode() == 46003 || e.getError().getErrorCode() == 46002) { | |||
return null; | |||
} | |||
throw e; | |||
} | |||
} | |||
@Override | |||
public WxMpMassUploadResult massNewsUpload(WxMpMassNews news) throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/media/uploadnews"; | |||
@@ -1323,5 +1249,10 @@ public class WxMpServiceImpl implements WxMpService { | |||
public WxMpMaterialService getMaterialService() { | |||
return this.materialService; | |||
} | |||
@Override | |||
public WxMpMenuService getMenuService() { | |||
return this.menuService; | |||
} | |||
} |
@@ -0,0 +1,73 @@ | |||
package me.chanjar.weixin.mp.api.impl; | |||
import me.chanjar.weixin.common.bean.WxMenu; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
import me.chanjar.weixin.mp.api.WxMpMenuService; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
/** | |||
* Created by Binary Wang on 2016/7/21. | |||
*/ | |||
public class WxMpMenuServiceImpl implements WxMpMenuService { | |||
private WxMpService wxMpService; | |||
public WxMpMenuServiceImpl(WxMpService wxMpService) { | |||
this.wxMpService = wxMpService; | |||
} | |||
@Override | |||
public void menuCreate(WxMenu menu) throws WxErrorException { | |||
if (menu.getMatchRule() != null) { | |||
String url = "https://api.weixin.qq.com/cgi-bin/menu/addconditional"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, menu.toJson()); | |||
} else { | |||
String url = "https://api.weixin.qq.com/cgi-bin/menu/create"; | |||
this.wxMpService.execute(new SimplePostRequestExecutor(), url, menu.toJson()); | |||
} | |||
} | |||
@Override | |||
public void menuDelete() throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/menu/delete"; | |||
this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null); | |||
} | |||
@Override | |||
public void menuDelete(String menuid) throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/menu/delconditional"; | |||
this.wxMpService.execute(new SimpleGetRequestExecutor(), url, "menuid=" + menuid); | |||
} | |||
@Override | |||
public WxMenu menuGet() throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/menu/get"; | |||
try { | |||
String resultContent = this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null); | |||
return WxMenu.fromJson(resultContent); | |||
} catch (WxErrorException e) { | |||
// 46003 不存在的菜单数据 | |||
if (e.getError().getErrorCode() == 46003) { | |||
return null; | |||
} | |||
throw e; | |||
} | |||
} | |||
@Override | |||
public WxMenu menuTryMatch(String userid) throws WxErrorException { | |||
String url = "https://api.weixin.qq.com/cgi-bin/menu/trymatch"; | |||
try { | |||
String resultContent = this.wxMpService.execute(new SimpleGetRequestExecutor(), url, "user_id=" + userid); | |||
return WxMenu.fromJson(resultContent); | |||
} catch (WxErrorException e) { | |||
// 46003 不存在的菜单数据 46002 不存在的菜单版本 | |||
if (e.getError().getErrorCode() == 46003 || e.getError().getErrorCode() == 46002) { | |||
return null; | |||
} | |||
throw e; | |||
} | |||
} | |||
} |
@@ -1,10 +1,12 @@ | |||
package me.chanjar.weixin.mp.api; | |||
package me.chanjar.weixin.mp.api.impl; | |||
import com.google.inject.Inject; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.common.bean.WxMenu; | |||
import me.chanjar.weixin.common.bean.WxMenu.WxMenuButton; | |||
import me.chanjar.weixin.common.exception.WxErrorException; | |||
import me.chanjar.weixin.mp.api.ApiTestModule; | |||
import me.chanjar.weixin.mp.api.WxMpServiceImpl; | |||
import org.testng.Assert; | |||
import org.testng.annotations.DataProvider; | |||
import org.testng.annotations.Guice; | |||
@@ -13,11 +15,12 @@ import org.testng.annotations.Test; | |||
/** | |||
* 测试菜单 | |||
* @author chanjarster | |||
* @author Binary Wang | |||
* | |||
*/ | |||
@Test(groups="menuAPI", dependsOnGroups="baseAPI") | |||
@Test(groups="menuAPI") | |||
@Guice(modules = ApiTestModule.class) | |||
public class WxMpMenuAPITest { | |||
public class WxMpMenuServiceImplTest { | |||
@Inject | |||
protected WxMpServiceImpl wxService; | |||
@@ -25,7 +28,7 @@ public class WxMpMenuAPITest { | |||
@Test(dataProvider = "menu") | |||
public void testCreateMenu(WxMenu wxMenu) throws WxErrorException { | |||
System.out.println(wxMenu.toJson()); | |||
wxService.menuCreate(wxMenu); | |||
this.wxService.getMenuService().menuCreate(wxMenu); | |||
} | |||
@Test | |||
@@ -69,17 +72,19 @@ public class WxMpMenuAPITest { | |||
WxMenu menu = WxMenu.fromJson(a); | |||
System.out.println(menu.toJson()); | |||
wxService.menuCreate(menu); | |||
this.wxService.getMenuService().menuCreate(menu); | |||
} | |||
@Test(dependsOnMethods = { "testCreateMenu"}) | |||
public void testGetMenu() throws WxErrorException { | |||
Assert.assertNotNull(wxService.menuGet()); | |||
WxMenu wxMenu = this.wxService.getMenuService().menuGet(); | |||
Assert.assertNotNull(wxMenu); | |||
System.out.println(wxMenu.toJson()); | |||
} | |||
@Test(dependsOnMethods = { "testGetMenu"}) | |||
public void testDeleteMenu() throws WxErrorException { | |||
wxService.menuDelete(); | |||
this.wxService.getMenuService().menuDelete(); | |||
} | |||
@DataProvider(name="menu") |
@@ -6,7 +6,7 @@ | |||
<class name="me.chanjar.weixin.mp.api.WxMpBusyRetryTest" /> | |||
<class name="me.chanjar.weixin.mp.api.WxMpBaseAPITest" /> | |||
<class name="me.chanjar.weixin.mp.api.WxMpCustomMessageAPITest" /> | |||
<class name="me.chanjar.weixin.mp.api.WxMpMenuAPITest" /> | |||
<class name="me.chanjar.weixin.mp.api.impl.WxMpMenuAPITest" /> | |||
<class name="me.chanjar.weixin.mp.api.WxMpGroupAPITest" /> | |||
<class name="me.chanjar.weixin.mp.api.WxMpMassMessageAPITest" /> | |||
<class name="me.chanjar.weixin.mp.api.WxMpUserAPITest" /> | |||