| @@ -8,21 +8,13 @@ | |||||
| */ | */ | ||||
| package me.chanjar.weixin.common.util.json; | package me.chanjar.weixin.common.util.json; | ||||
| import java.lang.reflect.Type; | |||||
| import com.google.gson.JsonArray; | |||||
| 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.bean.menu.WxMenu; | import me.chanjar.weixin.common.bean.menu.WxMenu; | ||||
| import me.chanjar.weixin.common.bean.menu.WxMenuButton; | import me.chanjar.weixin.common.bean.menu.WxMenuButton; | ||||
| import me.chanjar.weixin.common.bean.menu.WxMenuRule; | import me.chanjar.weixin.common.bean.menu.WxMenuRule; | ||||
| import java.lang.reflect.Type; | |||||
| /** | /** | ||||
| * @author Daniel Qian | * @author Daniel Qian | ||||
| @@ -76,6 +68,18 @@ public class WxMenuGsonAdapter implements JsonSerializer<WxMenu>, JsonDeserializ | |||||
| return matchRule; | return matchRule; | ||||
| } | } | ||||
| private WxMenuRule convertToRule(JsonObject json) { | |||||
| WxMenuRule menuRule = new WxMenuRule(); | |||||
| menuRule.setTagId(GsonHelper.getString(json,"tag_id")); | |||||
| menuRule.setSex(GsonHelper.getString(json,"sex")); | |||||
| menuRule.setCountry(GsonHelper.getString(json,"country")); | |||||
| menuRule.setProvince(GsonHelper.getString(json,"province")); | |||||
| menuRule.setCity(GsonHelper.getString(json,"city")); | |||||
| menuRule.setClientPlatformType(GsonHelper.getString(json,"client_platform_type")); | |||||
| menuRule.setLanguage(GsonHelper.getString(json,"language")); | |||||
| return menuRule; | |||||
| } | |||||
| @Override | @Override | ||||
| public WxMenu deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { | public WxMenu deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { | ||||
| /* | /* | ||||
| @@ -84,8 +88,7 @@ public class WxMenuGsonAdapter implements JsonSerializer<WxMenu>, JsonDeserializ | |||||
| * 查询菜单时是 { menu : { button : ... } } | * 查询菜单时是 { menu : { button : ... } } | ||||
| */ | */ | ||||
| WxMenu menu = new WxMenu(); | WxMenu menu = new WxMenu(); | ||||
| JsonObject menuJson = json.getAsJsonObject().get("menu").getAsJsonObject(); | |||||
| JsonArray buttonsJson = menuJson.get("button").getAsJsonArray(); | |||||
| JsonArray buttonsJson = json.getAsJsonObject().get("menu").getAsJsonObject().get("button").getAsJsonArray(); | |||||
| for (int i = 0; i < buttonsJson.size(); i++) { | for (int i = 0; i < buttonsJson.size(); i++) { | ||||
| JsonObject buttonJson = buttonsJson.get(i).getAsJsonObject(); | JsonObject buttonJson = buttonsJson.get(i).getAsJsonObject(); | ||||
| WxMenuButton button = convertFromJson(buttonJson); | WxMenuButton button = convertFromJson(buttonJson); | ||||
| @@ -14,12 +14,24 @@ public interface WxMpMenuService { | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 自定义菜单创建接口 | * 自定义菜单创建接口 | ||||
| * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=自定义菜单创建接口 | |||||
| * 详情请见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013&token=&lang=zh_CN | |||||
| * 如果要创建个性化菜单,请设置matchrule属性 | * 如果要创建个性化菜单,请设置matchrule属性 | ||||
| * 详情请见:http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html | |||||
| * 详情请见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN | |||||
| * </pre> | * </pre> | ||||
| * @return 如果是个性化菜单,则返回menuid,否则返回null | |||||
| */ | */ | ||||
| void menuCreate(WxMenu menu) throws WxErrorException; | |||||
| String menuCreate(WxMenu menu) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 自定义菜单创建接口 | |||||
| * 详情请见: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013&token=&lang=zh_CN | |||||
| * 如果要创建个性化菜单,请设置matchrule属性 | |||||
| * 详情请见:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455782296&token=&lang=zh_CN | |||||
| * </pre> | |||||
| * @return 如果是个性化菜单,则返回menuid,否则返回null | |||||
| */ | |||||
| String menuCreate(String json) throws WxErrorException; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| @@ -1,6 +1,7 @@ | |||||
| package me.chanjar.weixin.mp.api.impl; | package me.chanjar.weixin.mp.api.impl; | ||||
| import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||
| import com.google.gson.JsonParser; | |||||
| import me.chanjar.weixin.common.bean.menu.WxMenu; | import me.chanjar.weixin.common.bean.menu.WxMenu; | ||||
| import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| import me.chanjar.weixin.mp.api.WxMpMenuService; | import me.chanjar.weixin.mp.api.WxMpMenuService; | ||||
| @@ -24,7 +25,7 @@ public class WxMpMenuServiceImpl implements WxMpMenuService { | |||||
| } | } | ||||
| @Override | @Override | ||||
| public void menuCreate(WxMenu menu) throws WxErrorException { | |||||
| public String menuCreate(WxMenu menu) throws WxErrorException { | |||||
| String menuJson = menu.toJson(); | String menuJson = menu.toJson(); | ||||
| String url = API_URL_PREFIX + "/create"; | String url = API_URL_PREFIX + "/create"; | ||||
| if (menu.getMatchRule() != null) { | if (menu.getMatchRule() != null) { | ||||
| @@ -35,6 +36,29 @@ public class WxMpMenuServiceImpl implements WxMpMenuService { | |||||
| String result = this.wxMpService.post(url, menuJson); | String result = this.wxMpService.post(url, menuJson); | ||||
| log.debug("创建菜单:{},结果:{}", menuJson, result); | log.debug("创建菜单:{},结果:{}", menuJson, result); | ||||
| if (menu.getMatchRule() != null) { | |||||
| return new JsonParser().parse(result).getAsJsonObject().get("menuid").getAsString(); | |||||
| } | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| public String menuCreate(String json) throws WxErrorException { | |||||
| JsonParser jsonParser = new JsonParser(); | |||||
| JsonObject jsonObject = jsonParser.parse(json).getAsJsonObject(); | |||||
| String url = API_URL_PREFIX + "/create"; | |||||
| if (jsonObject.get("matchrule") != null) { | |||||
| url = API_URL_PREFIX + "/addconditional"; | |||||
| } | |||||
| String result = this.wxMpService.post(url, json); | |||||
| if (jsonObject.get("matchrule") != null) { | |||||
| return jsonParser.parse(result).getAsJsonObject().get("menuid").getAsString(); | |||||
| } | |||||
| return null; | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -50,7 +74,7 @@ public class WxMpMenuServiceImpl implements WxMpMenuService { | |||||
| JsonObject jsonObject = new JsonObject(); | JsonObject jsonObject = new JsonObject(); | ||||
| jsonObject.addProperty("menuid", menuId); | jsonObject.addProperty("menuid", menuId); | ||||
| String result = this.wxMpService.post(url, jsonObject.toString()); | String result = this.wxMpService.post(url, jsonObject.toString()); | ||||
| log.debug("根据MeunId({})删除菜单结果:{}", menuId, result); | |||||
| log.debug("根据MeunId({})删除个性化菜单结果:{}", menuId, result); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -77,7 +101,7 @@ public class WxMpMenuServiceImpl implements WxMpMenuService { | |||||
| String resultContent = this.wxMpService.post(url, jsonObject.toString()); | String resultContent = this.wxMpService.post(url, jsonObject.toString()); | ||||
| return WxMenu.fromJson(resultContent); | return WxMenu.fromJson(resultContent); | ||||
| } catch (WxErrorException e) { | } catch (WxErrorException e) { | ||||
| // 46003 不存在的菜单数据 46002 不存在的菜单版本 | |||||
| // 46003 不存在的菜单数据;46002 不存在的菜单版本 | |||||
| if (e.getError().getErrorCode() == 46003 | if (e.getError().getErrorCode() == 46003 | ||||
| || e.getError().getErrorCode() == 46002) { | || e.getError().getErrorCode() == 46002) { | ||||
| return null; | return null; | ||||
| @@ -8,23 +8,22 @@ import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.mp.api.ApiTestModule; | import me.chanjar.weixin.mp.api.ApiTestModule; | ||||
| import me.chanjar.weixin.mp.api.WxMpService; | import me.chanjar.weixin.mp.api.WxMpService; | ||||
| import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult; | import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult; | ||||
| import org.testng.Assert; | |||||
| import org.testng.annotations.DataProvider; | |||||
| import org.testng.annotations.Guice; | |||||
| import org.testng.annotations.Test; | |||||
| import org.testng.*; | |||||
| import org.testng.annotations.*; | |||||
| /** | /** | ||||
| * 测试菜单 | * 测试菜单 | ||||
| * | |||||
| * @author chanjarster | * @author chanjarster | ||||
| * @author Binary Wang | * @author Binary Wang | ||||
| * | |||||
| */ | */ | ||||
| @Test(groups="menuAPI") | |||||
| @Test(groups = "menuAPI") | |||||
| @Guice(modules = ApiTestModule.class) | @Guice(modules = ApiTestModule.class) | ||||
| public class WxMpMenuServiceImplTest { | public class WxMpMenuServiceImplTest { | ||||
| @Inject | @Inject | ||||
| protected WxMpService wxService; | protected WxMpService wxService; | ||||
| private String menuId = null; | |||||
| @Test(dataProvider = "menu") | @Test(dataProvider = "menu") | ||||
| public void testMenuCreate(WxMenu wxMenu) throws WxErrorException { | public void testMenuCreate(WxMenu wxMenu) throws WxErrorException { | ||||
| @@ -44,69 +43,111 @@ public class WxMpMenuServiceImplTest { | |||||
| System.out.println(selfMenuInfo); | System.out.println(selfMenuInfo); | ||||
| } | } | ||||
| @Test | |||||
| public void testCreateConditionalMenu() throws WxErrorException { | |||||
| String json = "{\n" + | |||||
| " \"button\":[\n" + | |||||
| " { \n" + | |||||
| " \"type\":\"click\",\n" + | |||||
| " \"name\":\"今日歌曲\",\n" + | |||||
| " \"key\":\"V1001_TODAY_MUSIC\" \n" + | |||||
| " },\n" + | |||||
| " { \n" + | |||||
| " \"name\":\"菜单\",\n" + | |||||
| " \"sub_button\":[\n" + | |||||
| " { \n" + | |||||
| " \"type\":\"view\",\n" + | |||||
| " \"name\":\"搜索\",\n" + | |||||
| " \"url\":\"http://www.soso.com/\"\n" + | |||||
| " },\n" + | |||||
| " {\n" + | |||||
| " \"type\":\"view\",\n" + | |||||
| " \"name\":\"视频\",\n" + | |||||
| " \"url\":\"http://v.qq.com/\"\n" + | |||||
| " },\n" + | |||||
| " {\n" + | |||||
| " \"type\":\"click\",\n" + | |||||
| " \"name\":\"赞一下我们\",\n" + | |||||
| " \"key\":\"V1001_GOOD\"\n" + | |||||
| " }]\n" + | |||||
| " }],\n" + | |||||
| "\"matchrule\":{\n" + | |||||
| " \"tag_id\":\"2\",\n" + | |||||
| " \"sex\":\"1\",\n" + | |||||
| " \"country\":\"中国\",\n" + | |||||
| " \"province\":\"广东\",\n" + | |||||
| " \"city\":\"广州\",\n" + | |||||
| " \"client_platform_type\":\"2\",\n" + | |||||
| " \"language\":\"zh_CN\"\n" + | |||||
| " }\n" + | |||||
| "}"; | |||||
| this.menuId = this.wxService.getMenuService().menuCreate(json); | |||||
| System.out.println(this.menuId); | |||||
| } | |||||
| @Test(dependsOnMethods = {"testCreateConditionalMenu"}) | |||||
| public void testDeleteConditionalMenu() throws WxErrorException { | |||||
| this.wxService.getMenuService().menuDelete(menuId); | |||||
| } | |||||
| @Test | @Test | ||||
| public void testCreateMenu2() throws WxErrorException { | public void testCreateMenu2() throws WxErrorException { | ||||
| String a = "{\n" | String a = "{\n" | ||||
| + " \"menu\": {\n" | |||||
| + " \"button\": [\n" | |||||
| + " {\n" | |||||
| + " \"type\": \"click\",\n" | |||||
| + " \"name\": \"今日歌曲\",\n" | |||||
| + " \"key\": \"V1001_TODAY_MUSIC\"\n" | |||||
| + " },\n" | |||||
| + " {\n" | |||||
| + " \"type\": \"click\",\n" | |||||
| + " \"name\": \"歌手简介\",\n" | |||||
| + " \"key\": \"V1001_TODAY_SINGER\"\n" | |||||
| + " },\n" | |||||
| + " {\n" | |||||
| + " \"name\": \"菜单\",\n" | |||||
| + " \"sub_button\": [\n" | |||||
| + " {\n" | |||||
| + " \"type\": \"view\",\n" | |||||
| + " \"name\": \"搜索\",\n" | |||||
| + " \"url\": \"http://www.soso.com/\"\n" | |||||
| + " },\n" | |||||
| + " {\n" | |||||
| + " \"type\": \"view\",\n" | |||||
| + " \"name\": \"视频\",\n" | |||||
| + " \"url\": \"http://v.qq.com/\"\n" | |||||
| + " },\n" | |||||
| + " {\n" | |||||
| + " \"type\": \"click\",\n" | |||||
| + " \"name\": \"赞一下我们\",\n" | |||||
| + " \"key\": \"V1001_GOOD\"\n" | |||||
| + " }\n" | |||||
| + " ]\n" | |||||
| + " }\n" | |||||
| + " ]\n" | |||||
| + " }\n" | |||||
| + "}"; | |||||
| + " \"menu\": {\n" | |||||
| + " \"button\": [\n" | |||||
| + " {\n" | |||||
| + " \"type\": \"click\",\n" | |||||
| + " \"name\": \"今日歌曲\",\n" | |||||
| + " \"key\": \"V1001_TODAY_MUSIC\"\n" | |||||
| + " },\n" | |||||
| + " {\n" | |||||
| + " \"type\": \"click\",\n" | |||||
| + " \"name\": \"歌手简介\",\n" | |||||
| + " \"key\": \"V1001_TODAY_SINGER\"\n" | |||||
| + " },\n" | |||||
| + " {\n" | |||||
| + " \"name\": \"菜单\",\n" | |||||
| + " \"sub_button\": [\n" | |||||
| + " {\n" | |||||
| + " \"type\": \"view\",\n" | |||||
| + " \"name\": \"搜索\",\n" | |||||
| + " \"url\": \"http://www.soso.com/\"\n" | |||||
| + " },\n" | |||||
| + " {\n" | |||||
| + " \"type\": \"view\",\n" | |||||
| + " \"name\": \"视频\",\n" | |||||
| + " \"url\": \"http://v.qq.com/\"\n" | |||||
| + " },\n" | |||||
| + " {\n" | |||||
| + " \"type\": \"click\",\n" | |||||
| + " \"name\": \"赞一下我们\",\n" | |||||
| + " \"key\": \"V1001_GOOD\"\n" | |||||
| + " }\n" | |||||
| + " ]\n" | |||||
| + " }\n" | |||||
| + " ]\n" | |||||
| + " }\n" | |||||
| + "}"; | |||||
| WxMenu menu = WxMenu.fromJson(a); | WxMenu menu = WxMenu.fromJson(a); | ||||
| System.out.println(menu.toJson()); | System.out.println(menu.toJson()); | ||||
| this.wxService.getMenuService().menuCreate(menu); | this.wxService.getMenuService().menuCreate(menu); | ||||
| } | } | ||||
| @Test(dependsOnMethods = { "testMenuCreate"}) | |||||
| @Test(dependsOnMethods = {"testMenuCreate"}) | |||||
| public void testMenuGet() throws WxErrorException { | public void testMenuGet() throws WxErrorException { | ||||
| WxMenu wxMenu = this.wxService.getMenuService().menuGet(); | WxMenu wxMenu = this.wxService.getMenuService().menuGet(); | ||||
| Assert.assertNotNull(wxMenu); | Assert.assertNotNull(wxMenu); | ||||
| System.out.println(wxMenu.toJson()); | System.out.println(wxMenu.toJson()); | ||||
| } | } | ||||
| @Test(dependsOnMethods = { "testMenuGet"}) | |||||
| @Test(dependsOnMethods = {"testMenuGet"}) | |||||
| public void testMenuDelete() throws WxErrorException { | public void testMenuDelete() throws WxErrorException { | ||||
| this.wxService.getMenuService().menuDelete(); | this.wxService.getMenuService().menuDelete(); | ||||
| } | } | ||||
| @Test | |||||
| public void testDeleteConditionalMenu() throws WxErrorException { | |||||
| String menuId = "123"; | |||||
| this.wxService.getMenuService().menuDelete(menuId); | |||||
| } | |||||
| @DataProvider(name="menu") | |||||
| @DataProvider(name = "menu") | |||||
| public Object[][] getMenu() { | public Object[][] getMenu() { | ||||
| WxMenu menu = new WxMenu(); | WxMenu menu = new WxMenu(); | ||||
| WxMenuButton button1 = new WxMenuButton(); | WxMenuButton button1 = new WxMenuButton(); | ||||
| @@ -145,10 +186,10 @@ public class WxMpMenuServiceImplTest { | |||||
| button3.getSubButtons().add(button32); | button3.getSubButtons().add(button32); | ||||
| button3.getSubButtons().add(button33); | button3.getSubButtons().add(button33); | ||||
| return new Object[][] { | |||||
| new Object[] { | |||||
| menu | |||||
| } | |||||
| return new Object[][]{ | |||||
| new Object[]{ | |||||
| menu | |||||
| } | |||||
| }; | }; | ||||
| } | } | ||||