小弟应运营要求要更改公众号菜单,本觉得是在公众号官网上进行配置便可,,谁知道 居然是开发者模式编辑的。无奈,从未接触过公众号开发的我。有开始啃开了微信开发的api,原来的作这个得小伙伴,跑路了。但没有交接。哎~~~html
废话很少说。开启流程。java
一、小弟这个仅仅是【订阅号】的开发。进入公众号后左边菜单找到web
这是该公众号开发时用到的关键参数列表,以下:spring
这里介绍下几个开发中用到的重要参数:数据库
一、开发者ID(AppId):就是开发人员在开发该订阅号 的帐号apache
二、开发者密码(AppSecret) : 就是开发人员在开发该订阅号 的密码json
三、IP白名单:该参数是微信服务器的一个ip白名单的验证,若是没有该白名单,微信服务器就不会认可你的地址是安全的。不能获取access_token参数api
四、服务器地址(URL):他是微信回调 你的服务器的地址。记住这个服务器地址是你的。不是微信的。并且这个地址有些硬性条件安全
(1)该url必须开通外网映射,无论你是在公司 仍是在家。这个地址必须外网可以访问到。服务器
(2)该url端口号必须是80,至于映射到本地应用端口是XXXX都无所谓。配置外网映射 我使用的是Sunny-Ngrok(https://www.ngrok.cc/)内网穿透服务,这个是一个网站提供,里面有免费的http外网映射。其余的映射服务均失败(多是本身太菜)。。格式,外网映射地址+应用验证接口
五、令牌(Token):验证使用的一个自定义字符串
六、消息加解密密钥:这个参数是发送/接收消时加密用的。但若是设置是明文方式,那么这个参数没用到。我就没用到
七、消息加密/解密方式:明文、兼容、安全
以上参数,构成了微信开发的基础参数。但想要真正开发,还有一些准备要作。
1、验证:
不能可直接在生产环境开发,大牛这么作的都不多。因此须要一个测试环境。那么就是开发者工具中的【公众号测试帐号】中,就能够建立,目前其余几项我就是看看没有仔细研究,后期补发。点击进入:
用手机微信直接受权登陆便可:
简单说明一下,测试帐号信息表中的内容是根据登陆的微信生成的。。我试了好几回都不会变。应该是帐号绑定的。注意,,这时测试帐号的帐号和密码,,前者的帐号 密码是生产环境。还有 这个登陆的微信必须是该公众号管理员受权绑定的微信帐号才行。
在公众号左侧菜单 人员设置中添加人员(建立者忽略),而后开发者工具中的Web开发者工具绑定一个开发者的微信号便可。
* 而后说说接口配置信息,第一次测试帐号配置是空的。url 也就是你的服务器地址,必须是80端口或443(也就是http和https默认端口)外网可以访问到的地址+你的验证应用接口地址 和第4 配置套路如出一辙好比 http://xxxx.cn/wx/yanzhengApi,验证的java demo为:
@ResponseBody @RequestMapping(value = "/WechatCallbackApi", method = RequestMethod.GET) public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 微信加密签名 String signature = request.getParameter("signature"); System.out.println("微信加密签名=====" + signature); // 随机字符串 String echostr = request.getParameter("echostr"); System.out.println("随机字符串=====" + echostr); // 时间戳 String timestamp = request.getParameter("timestamp"); System.out.println("时间戳=====" + echostr); // 随机数 String nonce = request.getParameter("nonce"); System.out.println("随机数=====" + echostr); String[] str = { TOKEN, timestamp, nonce }; Arrays.sort(str); // 字典序排序 String bigStr = str[0] + str[1] + str[2]; System.out.println("=====================" + bigStr); MessageDigestUtils digestutil = new MessageDigestUtils(); String sha1 = MessageDigestUtils.sha1(bigStr); // 确认请求来至微信 if (sha1.equals(signature)) { System.out.println("=====验证成功============"); response.getWriter().print(echostr); } }
这个demo 方法上面确定还有一个controller 的mapping,本身写吧。
* 下面的token 就是上述第5点的token
单机提交,若是没有问题,会提示配置成功(这里须要肯定你的借口在接收到请求后的响应时间,太长微信都不认, 多试几回就能够了),不然就是配置失败。失败的缘由,其实很简单。就是你的url配置的问题。通常token不会有问题。上述图片中是我配置好久才成功的截图。能够修改。提交验证是,会请求上述demo。大哥断点就知道怎么回事了。并且微信的api文档对这块说的仍是比较清楚的。就是没有明说url配置须要80或443 端口(PS:其实api文档也说明了。可是,是在另外一个页面说明的。。【开始开发】-【接入指南】最下方才说明,这里配置url啥都没说。)
完成以上工做久具有了 订阅号开发的最基本的配置。
* JS接口安全域名 我没有用到。这里不作介绍
使用你的登陆测试帐号的微信扫描一下 【测试号二维码】就会使当前微信关注这个订阅号了。点击关注。进入后,发现啥玩意都没有。咋办。新建菜单,这个自定义菜单可使用微信提供的web页面建立 也可使用java写,java 的demo以下
工具类:
package com.tiancaibao.service.weixin; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.log4j.Logger; import org.springframework.util.StringUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.tiancaibao.weixin.pojo.token.WeixinToken; /** * 获取微信access_token工具类 */ public class WeiXinAccessTokenUtil { private static final Logger DEBUG_LOGGER = Logger.getLogger(WeiXinAccessTokenUtil.class); /** * 从微信上 * 获取微信access_token * */ public static WeixinToken getWeiXinAccessToken(String appid,String secret) { if(StringUtils.isEmpty(appid)|| StringUtils.isEmpty(secret)) { DEBUG_LOGGER.error("appid or secret is null"); return null; } WeixinToken token = new WeixinToken(); try { String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret; HttpClient httpClient = new HttpClient(); GetMethod getMethod = new GetMethod(url); int execute = httpClient.executeMethod(getMethod); System.out.println("execute:"+execute); String getResponse = getMethod.getResponseBodyAsString(); System.out.println("========return的json========"+getResponse); JSONObject json = (JSONObject) JSON.parseObject(getResponse); token.setAccessToken(json.getString("access_token")); token.setExpiresIn(new Integer(json.getString("expires_in"))); Date createtime=new Date();; token.setCreatetime(createtime); } catch (IOException e) { DEBUG_LOGGER.error("getAccessToken failed,desc:::"+e); e.printStackTrace(); } return token; } }
access_token实体:
package com.tiancaibao.weixin.pojo.token; import java.io.Serializable; import java.util.Date; public class WeixinToken implements Serializable { private Integer id; private String accessToken; private Integer expiresIn; private Date createtime; protected String fields; private static final long serialVersionUID = 1L; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken == null ? null : accessToken.trim(); } public Integer getExpiresIn() { return expiresIn; } public void setExpiresIn(Integer expiresIn) { this.expiresIn = expiresIn; } public Date getCreatetime() { return createtime; } public void setCreatetime(Date createtime) { this.createtime = createtime; } public void setFields(String fields) { this.fields = fields; } public String getFields() { return fields; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(getClass().getSimpleName()); sb.append(" ["); sb.append("Hash = ").append(hashCode()); sb.append(", id=").append(id); sb.append(", accessToken=").append(accessToken); sb.append(", expiresIn=").append(expiresIn); sb.append(", createtime=").append(createtime); sb.append(", fields=").append(fields); sb.append(", serialVersionUID=").append(serialVersionUID); sb.append("]"); return sb.toString(); } }
请求建立工具:
package com.tiancaibao.weixin.menu; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ConnectException; import java.net.URL; import java.net.URLEncoder; import java.util.Date; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.tiancaibao.service.weixin.MyX509TrustManager; /** * * 开发人员: liming </br> */ public class WeixinUtil { private static Logger log = LoggerFactory.getLogger(WeixinUtil.class); // 菜单建立(POST) 限100(次/天) public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN"; /*** * 自定义菜单建立接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN 自定义菜单查询接口: http请求方式:GET https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN 自定义菜单删除接口: http请求方式:GET https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN * */ /** * 建立菜单 * * @param menu 菜单实例 * @param accessToken 有效的access_token * @return 0表示成功,其余值表示失败 */ public static int createMenu(Menu menu, String accessToken) { int result = 0; // 拼装建立菜单的url String url = menu_create_url.replace("ACCESS_TOKEN", accessToken); // 将菜单对象转换成json字符串 String jsonMenu = JSONObject.toJSONString(menu); // 调用接口建立菜单 JSONObject jsonObject = httpRequest(url, "POST", jsonMenu); if (null != jsonObject) { if (0 != jsonObject.getInteger("errcode")) { result = jsonObject.getInteger("errcode"); log.error("建立菜单失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg")); } } return result; } /** * 描述: 发起https请求并获取结果 * @param requestUrl 请求地址 * @param requestMethod 请求方式(GET、POST) * @param outputStr 提交的数据 * @return JSONObject(经过JSONObject.get(key)的方式获取json对象的属性值) */ public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) { JSONObject jsonObject = null; StringBuffer buffer = new StringBuffer(); try { // 建立SSLContext对象,并使用咱们指定的信任管理器初始化 TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); // 从上述SSLContext对象中获得SSLSocketFactory对象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); // 设置请求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod); if ("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect(); // 当有数据须要提交时 if (null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意编码格式,防止中文乱码 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 将返回的输入流转换成字符串 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); // 释放资源 inputStream.close(); inputStream = null; httpUrlConn.disconnect(); jsonObject = JSONObject.parseObject(buffer.toString()); } catch (ConnectException ce) { log.error("Weixin server connection timed out."); } catch (Exception e) { log.error("https request error:{}", e); } return jsonObject; } /** * 发送图片消息 * @param accesstoken * { "touser":"OPENID", "msgtype":"image", "image": { "media_id":"MEDIA_ID" } } * @param openid */ public static int SendCustomerMessage(String accesstoken ){ String url="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+accesstoken; ImageMsg image =new ImageMsg(); Image ima= new Image(); ima.setMedia_id("FsM7Uo7Nk1YDdSZr8zYu7p079vyXhsvdbW3ArYpwqcM"); image.setImage(ima); image.setTouser("ovlNE1A7Zlufu0wfMYiweE6igo-c"); image.setMsgtype("image");// 图片类型消息 String jsonMenu = JSONObject.toJSONString(image); System.out.println(jsonMenu); // 调用接口建立菜单 JSONObject jsonObject = httpRequest(url, "POST", jsonMenu); int result = 0; if (null != jsonObject) { if (0 != jsonObject.getInteger("errcode")) { result = jsonObject.getInteger("errcode"); log.error("建立菜单失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg")); } } return result; } public static void main(String[] args) { } }
自定义菜单建立main:
package com.tiancaibao.weixin.menu; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.tiancaibao.service.weixin.WeiXinAccessTokenUtil; import com.tiancaibao.weixin.pojo.token.WeixinToken; /** * 类名: MenuManager </br> * * 描述:菜单管理器类 </br> */ public class MenuManager { private static Logger log = LoggerFactory.getLogger(MenuManager.class); public static void main(String[] args) { // 第三方用户惟一凭证 测试 String appId = "wxxxxxxx"; // 第三方用户惟一凭证密钥 String appSecret = "xxxxxxxxxxxx"; WeixinToken weiXinAccessToken = WeiXinAccessTokenUtil.getWeiXinAccessToken(appId, appSecret); if (null != weiXinAccessToken) { String asstoken=weiXinAccessToken.getAccessToken(); // 调用接口建立菜单 int result = WeixinUtil.createMenu(getMenu(), asstoken); // 判断菜单建立结果 if (0 == result) log.info("菜单建立成功!"); else log.info("菜单建立失败,错误码:" + result); } } /** * 组装菜单数据 * * @return */ private static Menu getMenu() { //新菜单自定义 CommonButton mainBtn1New = new CommonButton(); mainBtn1New.setName("呀!活动"); mainBtn1New.setType("view"); mainBtn1New.setKey("http://weixin.xxxx"); CommonButton btn2_1 = new CommonButton(); btn2_1.setName("历史文章"); btn2_1.setType("view"); btn2_1.setUrl("xxxx"); CommonButton btn2_2 = new CommonButton(); btn2_2.setName("积分商城"); btn2_2.setType("view"); btn2_2.setUrl("http://xxxx"); CommonButton btn2_3 = new CommonButton(); btn2_3.setName("客服热线"); btn2_3.setType("click"); btn2_3.setKey("咱们的服务热线xx,工做时间 9:00-20:00,欢迎有问题拨打热线哦~"); CommonButton btn3_1 = new CommonButton(); btn3_1.setName("个人资产"); btn3_1.setType("view"); btn3_1.setKey("http://xxxx"); CommonButton btn3_2 = new CommonButton(); btn3_2.setName("登陆注册"); btn3_2.setType("view"); btn3_2.setKey("http://xxx"); CommonButton btn3_3 = new CommonButton(); btn3_3.setName("我要出借"); btn3_3.setType("view"); btn3_3.setKey("http://xxx"); CommonButton btn3_4 = new CommonButton(); btn3_4.setName("下载APP"); btn3_4.setType("view"); btn3_4.setKey("https://xxx"); /** * 微信: mainBtn1,mainBtn2,mainBtn3底部的三个一级菜单。 执行前观察appSecret参数是否须要重置。记得的话就不须要。。不急的。估计悬了。。要重置, * 但重置后会不会对全有的菜单有影响呢?~~ */ // ComplexButton mainBtn1 = new ComplexButton(); // mainBtn1.setName("呀!活动"); // //一级下有4个子菜单 // mainBtn1.setSub_button(new CommonButton[] {btn8,btn9}); ComplexButton mainBtn2 = new ComplexButton(); mainBtn2.setName("呀!姿式"); mainBtn2.setSub_button(new CommonButton[] { btn2_1,btn2_2, btn2_3 }); ComplexButton mainBtn3 = new ComplexButton(); mainBtn3.setName("呀!个人"); mainBtn3.setSub_button(new CommonButton[] { btn3_1,btn3_2,btn3_3, btn3_4 }); /** * 封装整个菜单 */ Menu menu = new Menu(); menu.setButton(new Button[] { mainBtn1New, mainBtn2, mainBtn3 }); return menu; } }
CommonButton:
package com.tiancaibao.weixin.menu; /** * 类名: CommonButton </br> * 包名: com.souvc.weixin.menu * 描述: 子菜单项 :没有子菜单的菜单项,有多是二级菜单项,也有多是不含二级菜单的一级菜单。 </br> */ public class CommonButton extends Button { private String type; private String key; private String url; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } }
complexButton:
package com.tiancaibao.weixin.menu; public class ComplexButton extends Button { private Button[] sub_button; public Button[] getSub_button() { return sub_button; } public void setSub_button(Button[] sub_button) { this.sub_button = sub_button; } }
Button:
package com.tiancaibao.weixin.menu; /** * 类名: Button </br> * 包名: com.souvc.weixin.menu * 描述: 菜单项的基类 </br> */ public class Button { private String name;//全部一级菜单、二级菜单都共有一个相同的属性,那就是name public String getName() { return name; } public void setName(String name) { this.name = name; } }
Menu:
package com.tiancaibao.weixin.menu; /** * 类名: Menu </br> * 包名: com.souvc.weixin.menu * 描述: 整个菜单对象的封装 </br> */ public class Menu { private Button[] button; public Button[] getButton() { return button; } public void setButton(Button[] button) { this.button = button; } }
以上就是 自定菜单的建立源码及过程。一级菜单和二级菜单的编辑 使用了java 的多态特性。api文档中也给出了具体的demo 能够参考。至于相关的事件和特性也请参看api文档,写的很详细了,不作赘述。
附加,接收微信回调处理方法:
/* * 特别注意,req.getInputStream()只能获取一次,而且只能读取一次。若是想要屡次读取,须要另外想办法。为了简单起见, */ @ResponseBody @RequestMapping(value = "/WechatCallbackApi", method = RequestMethod.POST) public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置编码 req.setCharacterEncoding("utf-8"); resp.setContentType("html/text;charset=utf-8"); resp.setCharacterEncoding("utf-8"); /* * 该部分咱们获取用户发送的信息,而且解析成<K,V>的形式进行显示 */ // 解析用户发送过来的信息 InputStream is = req.getInputStream();// 拿取请求流 // 将解析结果存储在HashMap中 Map<String, String> map = new HashMap<String, String>(); // 解析xml,将获取到的返回结果xml进行解析成咱们习惯的文字信息 SAXReader reader = new SAXReader();// Document document = null; try { document = reader.read(is);// 读取流中的内容 } catch (DocumentException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } // 获得xml根元素 Element root = document.getRootElement(); // 获得根元素的全部子节点 List<Element> elementList = root.elements(); // 遍历全部子节点,将全部的节点存放到map中,读取的时候方便 for (Element e : elementList) map.put(e.getName(), e.getText()); Set<String> keySet = map.keySet(); // 输出解析后用户发过来的信息 System.out.println("===解析用户发送过来的信息开始"); String FromUserName = "";// 用户的openid String event = "";// 事件类型 boolean ismessage = false; String messsgeContent = ""; String shopid = ""; String EventKey = ""; for (String key : keySet) { System.out.println(key + ":" + map.get(key)); if ("FromUserName".equals(key)) { FromUserName = map.get(key); } if ("Event".equals(key)) { event = map.get(key); } // 关键词报文开头 if ("MsgId".equals(key)) { ismessage = true; } if ("Content".equals(key)) { messsgeContent = map.get(key); } if ("EventKey".equals(key)) { EventKey = map.get(key); } } System.out.println("==========是否发送message==============" + ismessage); System.out.println(":解析用户发送过来的信息结束"); /* * 该部分咱们尝试按照文档的要求格式给用户回复文本信息、图文消息。重点:按照文档要求构造须要的参数。特别注意:参数区分大小写。 */ // 发送普通文本消息,请查看文档关于“回复文本消息”的xml格式 // 第一步:按照回复文本信息构造须要的参数 TextMsg textMsg = new TextMsg(); textMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”恰好相反 textMsg.setFromUserName(map.get("ToUserName")); textMsg.setCreateTime(new Date().getTime());// 消息建立时间 (整型) textMsg.setMsgType("text");// 文本类型消息 Date subscribedate = new Date(); // 自定义菜单为 CLICK,关注为subscribe if (event.equals("CLICK")) { textMsg.setContent("咱们的服务热线xxxx,工做时间 9:00-20:00,欢迎有问题拨打热线哦~\ue415"); } else if (event.equals("subscribe")) { // 查询是否有关注记录 Weixinshopsubscriberecord selectInfoByOpenId = wexinSubscibeservice.selectInfoByOpenId(FromUserName); System.out.println("=============查询是否有关注记录==========" + selectInfoByOpenId); if (EventKey != "" || EventKey != null || !"".equals(EventKey)) { System.out.println("===========================EventKey===============" + EventKey.toString()); String[] Str = EventKey.split("_"); // 此判断是为了防止二维码参数为空的状况 if (Str.length > 1) { shopid = Str[1]; } } // 未关注 if (selectInfoByOpenId == null) { // 初次关注 String FirstSubscribe = "终于等到你还好我没放弃,右下角快去开启你的财富之旅吧!" ; if(!"".equals(shopid)){ FirstSubscribe+=" 来源编号:"+ shopid; } textMsg.setContent(FirstSubscribe); Weixinshopsubscriberecord weixinshop = new Weixinshopsubscriberecord(); weixinshop.setOpenid(FromUserName); weixinshop.setShopid(shopid); weixinshop.setState("1"); weixinshop.setSubscribedate(subscribedate); weixinshop.setSubscribetime(subscribedate); // 保存openid wexinSubscibeservice.SubscribeSave(weixinshop); } else { // 取消后再次关注 selectInfoByOpenId.setState("2"); selectInfoByOpenId.setSubscribedate(subscribedate); selectInfoByOpenId.setSubscribetime(subscribedate); selectInfoByOpenId.setOpenid(FromUserName); selectInfoByOpenId.setShopid(shopid); wexinSubscibeservice.UpdateSubscribe(selectInfoByOpenId);// 更改记录 String SecondSubscribe = "欢迎回到财富之路,等你启程!" ; if(!"".equals(shopid)){ SecondSubscribe+=" 来源编号:"+ shopid; } textMsg.setContent(SecondSubscribe); } } else if (event.equals("unsubscribe")) { Weixinshopsubscriberecord weixinshop = new Weixinshopsubscriberecord(); weixinshop.setState("0");// 取消关注为0 weixinshop.setSubscribedate(subscribedate); weixinshop.setSubscribetime(subscribedate); weixinshop.setOpenid(FromUserName); weixinshop.setShopid(shopid); wexinSubscibeservice.UpdateSubscribe(weixinshop); } // 是否发送客服消息 Boolean issend = false; /** * 回复图片消息 */ ImageMsg imagemsg = new ImageMsg(); imagemsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”恰好相反 imagemsg.setFromUserName(map.get("ToUserName")); imagemsg.setCreateTime(new Date().getTime());// 消息建立时间 (整型) imagemsg.setMsgType("image");// 文本类型消息 Image Image = new Image(); // Image.setMediaId("FsM7Uo7Nk1YDdSZr8zYu7p079vyXhsvdbW3ArYpwqcM");//图片ID,不固定 Image.setMediaId("6GTGDx7tGKMgnHv2Qzd9-orxsSaNBr4TdLN_n2zdw14");// 图片ID,不固定 imagemsg.setImage(Image); // 消息内容 if (ismessage) { if (messsgeContent.indexOf("建军节快乐") != -1) { textMsg.setContent("活动已结束,欢迎下次来参加哦\ue409"); }else if(messsgeContent.indexOf("中秋") != -1){ textMsg.setContent("http://4xxx/index.jsp?aid=fe66eb90a5ea40e3a956ecaf2926f1c9&activityid=110312&wuid=457767&keyversion=0&isFromApiFilter=1"); }else if (messsgeContent.indexOf("客服 联系 电话") != -1) { textMsg.setContent("咱们的客服热线:xxx,快去拨打吧,美丽的客服妹子在等你~"); } else if (messsgeContent.indexOf("你好") != -1 || messsgeContent.indexOf("在么") != -1 || messsgeContent.indexOf("在") != -1 || messsgeContent.indexOf("在?") != -1 || messsgeContent.indexOf("你好?") != -1 || messsgeContent.indexOf("您好?") != -1 || messsgeContent.indexOf("你好?") != -1 || messsgeContent.indexOf("你好啊?") != -1 || messsgeContent.indexOf("hi") != -1 || messsgeContent.indexOf("hello") != -1) { textMsg.setContent("Hi~~~想我了吗?有任何问题,请电话骚扰咱们的客服哦,客服电话:xxx \ue032"); } else if (messsgeContent.indexOf("好买酒") != -1 || messsgeContent.indexOf("好卖酒") != -1 || messsgeContent.indexOf("酒") != -1) { // textMsg.setContent("呀呀,你是“好买酒”过来的吧?路途遥远,辛苦啦\ue056 // \n即日起,扫描上方二维码实名注册xxx,便可享受5000元体验金\ue106+80元现金红包\ue106+20%加息券\ue106“三重好礼”大礼包,机不可失,失再也不来,快去完成注册吧\ue056"); XStream xStream = new XStream(); xStream.alias("xml", imagemsg.getClass()); String imagemsgXml = xStream.toXML(imagemsg); System.out.println("回复图片的xml====" + imagemsgXml); PrintWriter printWriter = resp.getWriter(); printWriter.print(imagemsgXml); issend = true; } else { textMsg.setContent( "憋~着~急~哈~\ue415你的消息,小编我已收到,容我慢慢回复哈~\ue056有问题最好仍是找咱们的客服妹子哈,xxx,人家可比我这个成天只知道码字送积分的小编专业滴多哈~~~\ue409"); } } XStream xStream = new XStream(); xStream.alias("xml", textMsg.getClass()); String textMsg2Xml = xStream.toXML(textMsg); System.out.println("返回给微信服务器,让其发送用户消息的报文====" + textMsg2Xml); // 第三步,发送xml的格式信息给微信服务器,服务器转发给用户 // 除了这个,已关注再扫描的事件 if (!event.equals("SCAN")) { PrintWriter printWriter = resp.getWriter(); printWriter.print(textMsg2Xml); System.out.println("======文本发送了============"); } if (issend) { /** * 发送客服文本消息 */ // 第一步 获取accesstoken String accesstoken = ""; Date date1 = new Date(); Date date2 = new Date(); Weixincommoninfo selectaccesstoken = weixincommoInfoservice.selectInfo(); // 查看是否有accesstoken if (selectaccesstoken == null) { selectaccesstoken = new Weixincommoninfo(); WeixinToken weiXinAccessToken = WeiXinAccessTokenUtil.getWeiXinAccessToken(); accesstoken = weiXinAccessToken.getAccessToken(); selectaccesstoken.setSavefiled("accesstoken"); selectaccesstoken.setSaveinfo(accesstoken); selectaccesstoken.setExpiresIn(weiXinAccessToken.getExpiresIn()); selectaccesstoken.setCreatetime(date1); date2.setHours(date1.getHours() + 1);// 此处将accesstoken的有效期,设置为1小时 selectaccesstoken.setEffectivetime(date2); weixincommoInfoservice.Saveinfo(selectaccesstoken); } else { Date date = new Date(); // 判断当前时间是否在accesstoken 的有效期内, Date effectivetime = selectaccesstoken.getEffectivetime(); if (effectivetime.getTime() > date.getTime()) { accesstoken = selectaccesstoken.getSaveinfo(); System.out.println("数据库中的accesstoken能用"); } else { WeixinToken weiXinAccessToken = WeiXinAccessTokenUtil.getWeiXinAccessToken(); selectaccesstoken = new Weixincommoninfo(); accesstoken = weiXinAccessToken.getAccessToken(); selectaccesstoken.setSavefiled("accesstoken"); selectaccesstoken.setSaveinfo(accesstoken); selectaccesstoken.setExpiresIn(weiXinAccessToken.getExpiresIn()); selectaccesstoken.setCreatetime(date1); date2.setHours(date1.getHours() + 1); selectaccesstoken.setEffectivetime(date2); weixincommoInfoservice.upadateInfo(selectaccesstoken); System.out.println("数据库中的accesstoken不呢能用,从新获取更新"); } } // 第二步发送消息 System.out.println("发送客服消息======================="); String mescont = "呀呀,你是“好买酒”过来的吧?路途遥远,辛苦啦\ue056 \n即日起,扫描下方二维码实名注册xxx,便可享受5000元体验金\ue106+80元现金红包\ue106+20%加息券\ue106“三重好礼”大礼包,机不可失,失再也不来,快去完成注册吧\ue056"; WeixinUtil.SendCustomerTextMessage(accesstoken, FromUserName, mescont); } }