官网接口地址:https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Creating_Custom-Defined_Menu.html
//创建一个微信菜单实体类
WeixinMenu.java
1package com.weixin.menu; 2 3import java.io.Serializable; 4import java.util.Set; 5 6 7public abstract class WeixinMenu implements Serializable { 8 9 10 // primary key 11 private Integer id; 12 13 // fields 14 private String name; 15 private String type; 16 private String url; 17 private String key; 18 19 // many to one 20 private WeixinMenu parent; 21 22 // collections 23 private java.util.Set<WeixinMenu> child; 24 25 26 public Integer getId() { 27 return id; 28 } 29 30 public void setId(Integer id) { 31 this.id = id; 32 } 33 34 public String getName() { 35 return name; 36 } 37 38 public void setName(String name) { 39 this.name = name; 40 } 41 42 public String getType() { 43 return type; 44 } 45 46 public void setType(String type) { 47 this.type = type; 48 } 49 50 public String getUrl() { 51 return url; 52 } 53 54 public void setUrl(String url) { 55 this.url = url; 56 } 57 58 public String getKey() { 59 return key; 60 } 61 62 public void setKey(String key) { 63 this.key = key; 64 } 65 66 public WeixinMenu getParent() { 67 return parent; 68 } 69 70 public void setParent(WeixinMenu parent) { 71 this.parent = parent; 72 } 73 74 public Set<WeixinMenu> getChild() { 75 return child; 76 } 77 78 public void setChild(Set<WeixinMenu> child) { 79 this.child = child; 80 } 81 82 public String toString() { 83 return super.toString(); 84 } 85 86 87}
//控制器方法
WeixinMenuAct.java
1package com.weixin.menu; 2 3import org.apache.commons.lang.StringUtils; 4import org.apache.http.HttpEntity; 5import org.apache.http.HttpResponse; 6import org.apache.http.StatusLine; 7import org.apache.http.client.ClientProtocolException; 8import org.apache.http.client.HttpClient; 9import org.apache.http.client.HttpResponseException; 10import org.apache.http.client.ResponseHandler; 11import org.apache.http.client.methods.HttpGet; 12import org.apache.http.client.methods.HttpPost; 13import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 14import org.apache.http.entity.StringEntity; 15import org.apache.http.impl.client.CloseableHttpClient; 16import org.apache.http.impl.client.HttpClientBuilder; 17import org.apache.http.impl.client.HttpClients; 18import org.apache.http.util.EntityUtils; 19import org.json.JSONException; 20import org.json.JSONObject; 21import org.springframework.ui.ModelMap; 22import org.springframework.web.bind.annotation.RequestMapping; 23 24import javax.net.ssl.SSLContext; 25import javax.net.ssl.TrustManager; 26import javax.net.ssl.X509TrustManager; 27import java.io.IOException; 28import java.net.URI; 29import java.security.cert.CertificateException; 30import java.security.cert.X509Certificate; 31import java.util.Iterator; 32import java.util.List; 33import java.util.Set; 34 35public class Menu { 36 37 38 /** 39 * 生成微信菜单请求方法 40 * @param request 41 * @param model 42 * @return 43 */ 44 @RequestMapping("/weixinMenu/o_menu.do") 45 public String menu(HttpServletRequest request, ModelMap model) { 46 List<WeixinMenu> menus =null; //获取菜单集合 47 String msg =createMenu(getMenuJsonString(menus)); 48 try { 49 JSONObject object = new JSONObject(msg); 50 if (!object.get("errcode").equals("0")){ 51 model.addAttribute("msg",msg); 52 //操作失败处理代码 53 } 54 } catch (JSONException e) { 55 e.printStackTrace(); 56 } 57 return null; 58 } 59 60 61 /** 62 * 创建自定义菜单 63 */ 64 public String createMenu(String menus){ 65 String token=getToken();//获取access_token 66 String createMenuUrl="https://api.weixin.qq.com/cgi-bin/menu/create"; //微信提供的菜单接口地址 67 String url = createMenuUrl+"?access_token=" + token; 68 String msg = post(url, menus,"application/json"); 69 return msg; 70 } 71 72 /** 73 * 获取access_token 74 * @return 75 */ 76 public String getToken() { 77 String tokenGetUrl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";//微信提供获取access_token接口地址 78 String appid=""; 79 String secret=""; 80 81 System.out.println("~~~~~appid:"+appid); 82 System.out.println("~~~~~secret:"+secret); 83 JSONObject tokenJson=new JSONObject(); 84 if(StringUtils.isNotBlank(appid)&&StringUtils.isNotBlank(secret)){ 85 tokenGetUrl+="&appid="+appid+"&secret="+secret; 86 tokenJson=getUrlResponse(tokenGetUrl); 87 System.out.println("~~~~~tokenJson:"+tokenJson.toString()); 88 try { 89 return (String) tokenJson.get("access_token"); 90 } catch (JSONException e) { 91 System.out.println("报错了"); 92 return null; 93 } 94 }else{ 95 System.out.println("appid和secret为空"); 96 return null; 97 } 98 } 99 100 private JSONObject getUrlResponse(String url){ 101 CharsetHandler handler = new CharsetHandler("UTF-8"); 102 try { 103 HttpGet httpget = new HttpGet(new URI(url)); 104 HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); 105 //HttpClient 106 CloseableHttpClient client = httpClientBuilder.build(); 107 client = (CloseableHttpClient) wrapClient(client); 108 return new JSONObject(client.execute(httpget, handler)); 109 } catch (Exception e) { 110 e.printStackTrace(); 111 return null; 112 } 113 } 114 115 116 /** 117 * 将菜单集合转换为json数据 118 * @param menus 119 * @return 120 */ 121 public String getMenuJsonString(List<WeixinMenu> menus) { 122 123 String strJson = "{" + 124 "\"button\":["; 125 126 for (int i = 0; i < menus.size(); i++) { 127 strJson = strJson + "{ "; 128 WeixinMenu menu = menus.get(i); 129 if(menu.getChild().size()>0){ 130 strJson = strJson + 131 "\"name\":\""+menu.getName()+"\","+ 132 "\"sub_button\":["; 133 Set<WeixinMenu> sets = menu.getChild(); 134 Iterator<WeixinMenu> iter = sets.iterator(); 135 int no = 1; 136 while(iter.hasNext()){ 137 if(no>5){ 138 break; 139 }else{ 140 if(no==1){ 141 strJson = strJson + "{"; 142 }else{ 143 strJson = strJson + ",{"; 144 } 145 WeixinMenu child = iter.next(); 146 if(child.getType().equals("click")){ 147 strJson = strJson + 148 "\"type\":\"click\","+ 149 "\"name\":\""+child.getName()+"\","+ 150 "\"key\":\""+child.getKey()+"\"}"; 151 }else{ 152 strJson = strJson + 153 "\"type\":\"view\","+ 154 "\"name\":\""+child.getName()+"\","+ 155 "\"url\":\""+child.getUrl()+"\"}"; 156 } 157 no++; 158 } 159 } 160 strJson = strJson+"]"; 161 }else if(menu.getType().equals("click")){ 162 strJson = strJson + 163 "\"type\":\"click\","+ 164 "\"name\":\""+menu.getName()+"\","+ 165 "\"key\":\""+menu.getKey()+"\""; 166 }else{ 167 strJson = strJson + 168 "\"type\":\"view\","+ 169 "\"name\":\""+menu.getName()+"\","+ 170 "\"url\":\""+menu.getUrl()+"\""; 171 } 172 if(i==menus.size()-1){ 173 strJson = strJson + "}"; 174 }else{ 175 strJson = strJson + "},"; 176 } 177 } 178 strJson = strJson + "]}"; 179 return strJson; 180 181 } 182 183 /** 184 * 发送请求 185 * @param url 请求地址 186 * @param json 数据 187 * @param contentType 编码 188 * @return 189 */ 190 private String post(String url, String json,String contentType) 191 { 192 HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); 193 //HttpClient 194 CloseableHttpClient client = httpClientBuilder.build(); 195 client = (CloseableHttpClient) wrapClient(client); 196 HttpPost post = new HttpPost(url); 197 try 198 { 199 StringEntity s = new StringEntity(json,"utf-8"); 200 if(StringUtils.isBlank(contentType)){ 201 s.setContentType("application/json"); 202 } 203 s.setContentType(contentType); 204 post.setEntity(s); 205 HttpResponse res = client.execute(post); 206 HttpEntity entity = res.getEntity(); 207 String str= EntityUtils.toString(entity, "utf-8"); 208 return str; 209 } 210 catch (Exception e) 211 { 212 e.printStackTrace(); 213 } 214 return null; 215 } 216 217 218 private static HttpClient wrapClient(HttpClient base) { 219 try { 220 SSLContext ctx = SSLContext.getInstance("TLSv1"); 221 X509TrustManager tm = new X509TrustManager() { 222 public void checkClientTrusted(X509Certificate[] xcs, 223 String string) throws CertificateException { 224 } 225 226 public void checkServerTrusted(X509Certificate[] xcs, 227 String string) throws CertificateException { 228 } 229 230 public X509Certificate[] getAcceptedIssuers() { 231 return null; 232 } 233 }; 234 ctx.init(null, new TrustManager[] { tm }, null); 235 SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(ctx, new String[] { "TLSv1" }, null, 236 SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); 237 CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); 238 return httpclient; 239 240 } catch (Exception ex) { 241 return null; 242 } 243 } 244 245 246 private class CharsetHandler implements ResponseHandler<String> { 247 private String charset; 248 249 public CharsetHandler(String charset) { 250 this.charset = charset; 251 } 252 253 public String handleResponse(HttpResponse response) 254 throws ClientProtocolException, IOException { 255 StatusLine statusLine = response.getStatusLine(); 256 if (statusLine.getStatusCode() >= 300) { 257 throw new HttpResponseException(statusLine.getStatusCode(), 258 statusLine.getReasonPhrase()); 259 } 260 HttpEntity entity = response.getEntity(); 261 if (entity != null) { 262 if (!StringUtils.isBlank(charset)) { 263 return EntityUtils.toString(entity, charset); 264 } else { 265 return EntityUtils.toString(entity); 266 } 267 } else { 268 return null; 269 } 270 } 271 } 272 273}