微信开发 (一) 消息回复
来源:互联网 发布:典韦 程咬金 知乎 编辑:程序博客网 时间:2024/05/16 08:31
如果微信服务号或者订阅号一旦接入了开发者模式,微信的后台自动回复后台的配置就会消失,菜单配置也会消失,这时候就需要开发人员写代码来维护!
第一步:填写服务器配置
1.可以参照微信官方文档点击打开链接 基本上不会错唯一注意的是url 一定要是外网的地址而且端口是80或者443
第二步:验证消息的确来自微信服务器
@RequestMapping(value="/service",method={RequestMethod.GET})@ResponseBodypublic void index(HttpServletRequest request,HttpServletResponse response) throws Exception{request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); String signature = request.getParameter("signature"); String timestamp = request.getParameter("timestamp"); String nonce = request.getParameter("nonce"); String echostr = request.getParameter("echostr"); String result = ""; if(StringUtil.isNotEmpty(echostr)){ String[] arr = new String[] {TOKEN, timestamp, nonce}; StringBuilder content = new StringBuilder(); for (int i = 0; i < arr.length; i++) { content.append(arr[i]); } Arrays.sort(arr); Boolean checkFlag = content ==null ? false : signature.equals(EncryptUtils.SHA1(content.toString())); result = echostr; }else{ Map<String,String> map = WeixinFormatXmlProcess.parseXml(request); String content = map.get("Content"); String ToUserName = map.get("ToUserName"); String FromUserName = map.get("FromUserName"); String replayMessage = WeixinFormatXmlProcess.formatXmlAnswer(ToUserName, FromUserName,content); result = replayMessage; } PrintWriter pw = response.getWriter(); response.setContentType("text/plain"); pw.write(result); pw.flush(); pw.close(); }
第三步:依据接口文档实现业务逻辑
/** * * @Title: index1 * @Description: * @param @param request * @param @param response * @param @throws Exception * @return void */@RequestMapping(value="/service",method={RequestMethod.POST})@ResponseBodypublic void index1(HttpServletRequest request,HttpServletResponse response) throws Exception{ logger.debug(" request service wx qq ... "); WxMessage modelInfo = new WxMessage(); modelInfo.setWx_service_type("2"); String replayMessage = wxMessageService.getWeiXinReplayMessage(request, modelInfo); logger.debug(" replayMessage is ... {}",replayMessage);if(StringUtil.isNotEmpty(replayMessage)){wirteRespose(response, replayMessage);}}@Overridepublic String getWeiXinReplayMessage(HttpServletRequest request,WxMessage modelInfo) throws Exception{String replayMessage ="";Map<String,String> map = WeixinFormatXmlProcess.parseXml(request);String eventType = map.get("Event"); String toUserName = map.get("ToUserName");String fromUserName = map.get("FromUserName");String content = map.get("Content");//关注事件if ("subscribe".equals(eventType)) {modelInfo.setWx_reply_type("1");replayMessage = getWeiXinReplayMessage(fromUserName,toUserName,getWxMessageByModel(modelInfo));}else {List<WxMessage> listWxMessage = getListWxMessageByModel(modelInfo);if (null!=listWxMessage && listWxMessage.size()>0) {for(WxMessage model: listWxMessage){if(content.trim().equals(model.getWx_key_words())){replayMessage = getWeiXinReplayMessage(fromUserName,toUserName,model);}}}}return replayMessage ;} /** * 封装文字类的返回消息 * @param to * @param from * @param content * @return */ public static String formatXmlAnswer(String to, String from, String content) { StringBuffer sb = new StringBuffer(); Date date = new Date(); sb.append("<xml><ToUserName><![CDATA["); sb.append(to); sb.append("]]></ToUserName><FromUserName><![CDATA["); sb.append(from); sb.append("]]></FromUserName><CreateTime>"); sb.append(date.getTime()); sb.append("</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA["); sb.append(content); sb.append("]]></Content>"); /*sb.append("<MsgId>"); sb.append(msgid); sb.append("</MsgId>");*/ sb.append("</xml>"); return sb.toString(); } /** * * @Title: formatXmlImage * @Description: 回复图片消息 * @param @param to * @param @param from * @param @param content * @param @param media_id * @param @return * @return String */ public static String formatXmlImage(String to, String from, String content,Object media_id) { StringBuffer sb = new StringBuffer(); Date date = new Date(); sb.append("<xml><ToUserName><![CDATA["); sb.append(to); sb.append("]]></ToUserName><FromUserName><![CDATA["); sb.append(from); sb.append("]]></FromUserName><CreateTime>"); sb.append(date.getTime()); sb.append("</CreateTime>"); sb.append("<MsgType><![CDATA[image]]></MsgType>"); sb.append("<Image><MediaId><![CDATA["); sb.append(media_id); sb.append("]]></MediaId></Image>"); sb.append("</xml>"); return sb.toString(); } /** * * @Title: formatXmlImageAndText * @Description: 回复图文消息 * @param @param to * @param @param from * @param @param model * @param @return * @return String */ public static String formatXmlImageAndText(String to, String from,WxMessage model) { StringBuffer sb = new StringBuffer();int wxArticleCount = model.getWx_article_count();String wxArticleTitle = model.getWx_article_title();String [] wxArticleTitleArray =new String[wxArticleCount]; if(StringUtil.isNotEmpty(wxArticleTitle)){for(int i=0;i<wxArticleTitle.split(WEIXIN_SPLIT).length;i++){wxArticleTitleArray[i] = wxArticleTitle.split(WEIXIN_SPLIT)[i];}}String wxPicUrl= model.getWx_pic_url();String [] wxPicUrlArray = new String[wxArticleCount];if(StringUtil.isNotEmpty(wxPicUrl)){for(int i=0;i<wxPicUrl.split(WEIXIN_SPLIT).length;i++){wxPicUrlArray[i] = wxPicUrl.split(WEIXIN_SPLIT)[i];}}String wxArticleUrl= model.getWx_article_url();String [] wxArticleUrlArray = new String[wxArticleCount];if(StringUtil.isNotEmpty(wxArticleUrl)){for(int i=0;i<wxArticleUrl.split(WEIXIN_SPLIT).length;i++){wxArticleUrlArray[i] = wxArticleUrl.split(WEIXIN_SPLIT)[i];}}String wxMessageDesc= model.getWx_message_desc();String [] wxMessageDescArray = new String[wxArticleCount];if(StringUtil.isNotEmpty(wxMessageDesc)){for(int i=0;i<wxMessageDesc.split(WEIXIN_SPLIT).length;i++){wxMessageDescArray[i] = wxMessageDesc.split(WEIXIN_SPLIT)[i];}}Date date = new Date(); sb.append("<xml><ToUserName><![CDATA["); sb.append(to); sb.append("]]></ToUserName><FromUserName><![CDATA["); sb.append(from); sb.append("]]></FromUserName><CreateTime>"); sb.append(date.getTime()); sb.append("</CreateTime>"); sb.append("<MsgType><![CDATA[news]]></MsgType>");sb.append("<ArticleCount>"+wxArticleCount+"</ArticleCount>");sb.append("<Articles>");for(int i=0;i<wxArticleCount;i++){sb.append("<item>");if(StringUtil.isNotEmpty(wxArticleTitleArray[i])){sb.append("<Title><![CDATA["+wxArticleTitleArray[i]+"]]></Title>");}if(StringUtil.isNotEmpty(wxMessageDescArray[i])){sb.append("<Description><![CDATA["+wxMessageDescArray[i]+"]]></Description>");}if(StringUtil.isNotEmpty(wxPicUrlArray[i])){sb.append("<PicUrl><![CDATA["+(String)SysConfigInit.sysConfig.get(GlobalConstant.IMGPATH_URL_DOMAIN)+wxPicUrlArray[i]+"]]></PicUrl>");}if(StringUtil.isNotEmpty(wxArticleUrlArray[i])){sb.append("<Url><![CDATA["+wxArticleUrlArray[i]+"]]></Url>");}sb.append("</item>");}sb.append("<Articles>"); sb.append("</xml>"); return sb.toString(); } /** * * @Title: parseXml1 * @Description: 获取微信端传过来的参数 * @param @param str * @param @return * @param @throws Exception * @return Map<String,Object> */ public static Map<String,String> parseXml(HttpServletRequest request) throws Exception { // 将解析结果存储在HashMap中 Map<String,String> map = new HashMap<String,String>(); // 从request中取得输入流 InputStream inputStream = request.getInputStream(); // 读取输入流 SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); // 得到xml根元素 Element root = document.getRootElement(); // 得到根元素的所有子节点 List<Element> elementList = root.elements(); // 遍历所有子节点 for (Element e : elementList) map.put(e.getName(), e.getText()); // 释放资源 inputStream.close(); inputStream = null; return map; } /** * * @Title: parseXml1 * @Description: 获取微信端传过来的参数 * @param @param str * @param @return * @param @throws Exception * @return Map<String,Object> */ public static Map<String,Object> parseXml1(String str) throws Exception { // 将解析结果存储在HashMap中 Map<String,Object> map = new HashMap<String,Object>(); // 从request中取得输入流 InputStream inputStream =new ByteArrayInputStream(str.getBytes()); //request.getInputStream(); // 读取输入流 SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); // 得到xml根元素 Element root = document.getRootElement(); // 得到根元素的所有子节点 List<Element> elementList = root.elements(); // 遍历所有子节点 for (Element e : elementList) map.put(e.getName(), e.getText()); // 释放资源 inputStream.close(); inputStream = null; return map; }/*** * @param type 类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb)* @param filename 文件名字* @param mediaFileUrl 文件路劲*/public static String uploadPermanentMedia(String type, String filename, String mediaFileUrl,String accessToken) {String medeId="";BufferedReader reader = null;OutputStream out = null;DataInputStream in = null;try {// 拼装请求地址String uploadMediaUrl = "http://api.weixin.qq.com/cgi-bin/material/add_material?access_token=##ACCESS_TOKEN##&type=##type##";uploadMediaUrl = uploadMediaUrl.replace("##ACCESS_TOKEN##", accessToken).replace("##type##", type);URL url = new URL(uploadMediaUrl);String result = null;File file = new File(mediaFileUrl);if (!file.exists() || !file.isFile()) {System.out.println("上传的文件不存在");}HttpURLConnection con = (HttpURLConnection) url.openConnection();con.setRequestMethod("POST"); // 以Post方式提交表单,默认get方式con.setDoInput(true);con.setDoOutput(true);con.setUseCaches(false); // post方式不能使用缓存// 设置请求头信息con.setRequestProperty("Connection", "Keep-Alive");con.setRequestProperty("Charset", "UTF-8");// 设置边界String BOUNDARY = "----------" + System.currentTimeMillis();con.setRequestProperty("Content-Type", "multipart/form-data; boundary="+ BOUNDARY);// 请求正文信息// 第一部分:StringBuilder sb = new StringBuilder();sb.append("--"); // 必须多两道线sb.append(BOUNDARY);sb.append("\r\n");sb.append("Content-Disposition: form-data;name=\"media\";filename=\""+ filename + "\" \r\n");sb.append("Content-Type:application/octet-stream\r\n\r\n");byte[] head = sb.toString().getBytes("utf-8");// 获得输出流out = new DataOutputStream(con.getOutputStream());// 输出表头out.write(head);// 文件正文部分// 把文件已流文件的方式 推入到url中in = new DataInputStream(new FileInputStream(file));int bytes = 0;byte[] bufferOut = new byte[1024];while ((bytes = in.read(bufferOut)) != -1) {out.write(bufferOut, 0, bytes);}in.close();// 结尾部分byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线out.write(foot);out.flush();out.close();StringBuffer buffer = new StringBuffer();// 定义BufferedReader输入流来读取URL的响应reader = new BufferedReader(new InputStreamReader(con.getInputStream()));String line = null;while ((line = reader.readLine()) != null) {buffer.append(line);}if (result == null) {result = buffer.toString();}// 使用JSON-lib解析返回结果JSONObject jsonObject = JSONObject.fromObject(result);if (jsonObject.has("media_id")) {medeId =jsonObject.getString("media_id");logger.info("media_id:" + jsonObject.getString("media_id"));} else {logger.error(jsonObject.toString());}} catch (IOException e) {logger.error("发送POST请求出现异常!" + e);e.printStackTrace();} finally {try {if (reader != null) {reader.close();}if (out != null) { out.close(); } if (in != null) { in.close(); }} catch (IOException e) {// TODO Auto-generated catch blocklogger.error("关闭异常");e.printStackTrace();}}return medeId;}/*** * @Title: deleteMedid* @Description: 删除永久素材* @param @param medid* @param @return* @param @throws Exception * @return boolean*/public static boolean deleteMedid(String medid,String access_token){String medeid = "{\"media_id\":\""+medid+"\"}";String url ="https://api.weixin.qq.com/cgi-bin/material/del_material?access_token="+access_token;String result =SmsClientAccessTool.getInstance().doAccessHTTPPost(url, medeid,null);JSONObject jsonObject = JSONObject.fromObject(result);if(jsonObject!=null){if(0==jsonObject.getInt("errcode")){logger.info("删除成功medid"+medid);return true;}else{logger.info("删除失败medid"+medid);return false;}}else{return false;}}
这个方法是第一步里面配置的url 这时候只要用户和公众号交互就会进入这个方法这时候用户就可以在这个方法里面写用户关注、关键字回复的消息。这个方法也可以拿到用户的openid 拿到用户open_id特别需要注意这是微信的服务端的方法。所以拿到open_id不能存在session里面需要存到数据库里面。获取open_id 有两种方式第一种是在这个方法里面,第二种是通过网页授权获取后面会讲到。怎么通过网页授权拿到open_id。这里基本上可以回复图文消息、文字消息、图片消息。
文字消息
图片消息(图片消息需要上传素材)
图文消息(这里需要注意最多只能八条图文一次性)
至此基本上完成了微信的消息服务。基本上这些回复做成后台可配置的附上一些后台的截图
1 0
- 微信开发 (一) 消息回复
- PHP微信开发---模板消息回复
- [微信开发五]--图文消息回复
- 微信消息自动回复开发
- 微信开发之消息回复
- 微信开发基本消息回复
- php 微信开发回复消息
- 微信消息回复
- 微信公众平台开发【发送消息】被动回复消息
- 微信开发_接收消息,回复消息(3)
- 微信开发中的消息验证与消息回复
- 微信公众号开发(一、接收用户消息自动回复)
- 微信开发中signature的验证,文本消息回复,单图文消息回复,多图文消息回复
- 微信图文消息回复
- 微信关注回复消息
- 微信公众平台开发(十) 消息回复总结
- 微信公众平台开发(十) 消息回复总结
- 【php】微信公众帐号开发接口--消息回复
- angular 倒序绑定数据
- springWeb返回Json数据的处理
- 编译警告:ISO C90 forbids mixed declarations and code
- mysql 中二进制日志
- ZXing生成和读取条形码二维码(C#)
- 微信开发 (一) 消息回复
- 一次启动tomcat失败的案例
- node-oracledb 安装
- 开发移动应用程序的三种选择:原生、HTML5或混合
- 底部导航栏的几种实现方式
- 百度地图canvas自定义轨迹
- linux系统中device tree的SPI描述
- ECharts简介
- 换了阿里云的maven源之后,整个世界都美好了
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
揭阳车牌
揭阳论坛网
揭阳是哪里
揭阳招工网
揭阳培训班
揭阳学院
揭阳八景
揭阳城隍庙
厦门到揭阳
揭阳古墓
长沙 揭阳
广东 揭阳
成都至揭阳
揭阳榕城区
南昌揭阳
揭阳医院
揭阳南昌
揭阳武汉
上海至揭阳
揭阳移动卡
重庆至揭阳
南宁揭阳
揭阳怎么样
南宁 揭阳
揭阳丰胸
上海揭阳
郑州至揭阳
福州 揭阳
沈阳 揭阳
西安揭阳
揭阳联通
揭阳二日游
揭阳花店
揭阳到厦门
揭阳割包皮
合肥 揭阳
郑州 揭阳
四川揭阳
汕头揭阳
揭阳靓号
揭阳印花厂