转载自:http://blog.csdn.net/wangqianjiao/article/details/8469780
微信公众平台现在推出自动回复消息接口,但是由于是接口内容用的是PHP语言写的,很多地方操作起来让本人这个对java比较熟悉的小伙很别扭,所以仿照PHP的接口代码做了一套jsp语言编写的接口。
首先先把整个接口代码贴出来做下比较,然后我们再分析代码:
PHP代码:
<?php /** * wechat php test */ //define your token define("TOKEN", "weixin"); $wechatObj = new wechatCallbackapiTest(); $wechatObj->valid(); class wechatCallbackapiTest { public function valid() { $echoStr = $_GET["echostr"]; //valid signature , option if($this->checkSignature()){ echo $echoStr; exit; } } public function responseMsg() { //get post data, May be due to the different environments $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //extract post data if (!empty($postStr)){ $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $keyword = trim($postObj->Content); $time = time(); $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> <FuncFlag>0</FuncFlag> </xml>"; if(!empty( $keyword )) { $msgType = "text"; $contentStr = "Welcome to wechat world!"; $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); echo $resultStr; }else{ echo "Input something..."; } }else { echo ""; exit; } } private function checkSignature() { $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr); $tmpStr = implode( $tmpArr ); $tmpStr = sha1( $tmpStr ); if( $tmpStr == $signature ){ return true; }else{ return false; } } } ?>
JAVA代码:
<%@page import="java.util.Date"%> <%@page import="org.dom4j.Element"%> <%@page import="org.dom4j.DocumentHelper"%> <%@page import="org.dom4j.Document"%> <%@page import="java.io.IOException"%> <%@page import="java.io.InputStreamReader"%> <%@page import="java.io.BufferedReader"%> <%@page import="java.io.Reader"%> <%@page import="java.security.MessageDigest"%> <%@page import="java.util.Arrays"%> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <% //WeiXinHandler为内部类不能使用非final类型的对象 final String TOKEN="weixin"; final HttpServletRequest final_request=request; final HttpServletResponse final_response=response; %> <% class WeiXinHandler{ public void valid(){ String echostr=final_request.getParameter("echostr"); if(null==echostr||echostr.isEmpty()){ responseMsg(); }else{ if(this.checkSignature()){ this.print(echostr); }else{ this.print("error"); } } } //自动回复内容 public void responseMsg(){ String postStr=null; try{ postStr=this.readStreamParameter(final_request.getInputStream()); }catch(Exception e){ e.printStackTrace(); } //System.out.println(postStr); if (null!=postStr&&!postStr.isEmpty()){ Document document=null; try{ document = DocumentHelper.parseText(postStr); }catch(Exception e){ e.printStackTrace(); } if(null==document){ this.print(""); return; } Element root=document.getRootElement(); String fromUsername = root.elementText("FromUserName"); String toUsername = root.elementText("ToUserName"); String keyword = root.elementTextTrim("Content"); String time = new Date().getTime()+""; String textTpl = "<xml>"+ "<ToUserName><![CDATA[%1$s]]></ToUserName>"+ "<FromUserName><![CDATA[%2$s]]></FromUserName>"+ "<CreateTime>%3$s</CreateTime>"+ "<MsgType><![CDATA[%4$s]]></MsgType>"+ "<Content><![CDATA[%5$s]]></Content>"+ "<FuncFlag>0</FuncFlag>"+ "</xml>"; if(null!=keyword&&!keyword.equals("")) { String msgType = "text"; String contentStr = "Welcome to wechat world!"; String resultStr = textTpl.format(textTpl, fromUsername, toUsername, time, msgType, contentStr); this.print(resultStr); }else{ this.print("Input something..."); } }else { this.print(""); } } //微信接口验证 public boolean checkSignature(){ String signature = final_request.getParameter("signature"); String timestamp = final_request.getParameter("timestamp"); String nonce = final_request.getParameter("nonce"); String token=TOKEN; String[] tmpArr={token,timestamp,nonce}; Arrays.sort(tmpArr); String tmpStr=this.ArrayToString(tmpArr); tmpStr=this.SHA1Encode(tmpStr); if(tmpStr.equalsIgnoreCase(signature)){ return true; }else{ return false; } } //向请求端发送返回数据 public void print(String content){ try{ final_response.getWriter().print(content); final_response.getWriter().flush(); final_response.getWriter().close(); }catch(Exception e){ } } //数组转字符串 public String ArrayToString(String [] arr){ StringBuffer bf = new StringBuffer(); for(int i = 0; i < arr.length; i++){ bf.append(arr[i]); } return bf.toString(); } //sha1加密 public String SHA1Encode(String sourceString) { String resultString = null; try { resultString = new String(sourceString); MessageDigest md = MessageDigest.getInstance("SHA-1"); resultString = byte2hexString(md.digest(resultString.getBytes())); } catch (Exception ex) { } return resultString; } public final String byte2hexString(byte[] bytes) { StringBuffer buf = new StringBuffer(bytes.length * 2); for (int i = 0; i < bytes.length; i++) { if (((int) bytes[i] & 0xff) < 0x10) { buf.append("0"); } buf.append(Long.toString((int) bytes[i] & 0xff, 16)); } return buf.toString().toUpperCase(); } //从输入流读取post参数 public String readStreamParameter(ServletInputStream in){ StringBuilder buffer = new StringBuilder(); BufferedReader reader=null; try{ reader = new BufferedReader(new InputStreamReader(in)); String line=null; while((line = reader.readLine())!=null){ buffer.append(line); } }catch(Exception e){ e.printStackTrace(); }finally{ if(null!=reader){ try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return buffer.toString(); } } %> <% WeiXinHandler handler=new WeiXinHandler(); handler.valid(); %>
以上就是PHP接口和JSP接口的所有代码,现在我们来对一些需要注意的地方做下分析:
首先的从总体看的话,jsp要比PHP繁琐一些,因为很多函数需要自己写,像sha1加密,解析xml字符串等都需要自己找第三方的库。
第一点,我们要获取微信公众平台给jsp发送的post或get参数,正常情况下都是用request.getParameter就可以获取到,但是在写的过程中发现PHP是这样获取
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
这时通过查询一些资料知道这样获取的是无法通过$_GET或$_POST函数得到的”未识别 MIME 类型的数据“,原始的 POST 数据
(参考:http://blog.csdn.net/china_skag/article/details/7284227)
所以这里使用获取原始数据流的方式来解析post的xml数据
String postStr=null; try{ postStr=this.readStreamParameter(final_request.getInputStream()); }catch(Exception e){ e.printStackTrace(); }
//从输入流读取post参数 public String readStreamParameter(ServletInputStream in){ StringBuilder buffer = new StringBuilder(); BufferedReader reader=null; try{ reader = new BufferedReader(new InputStreamReader(in)); String line=null; while((line = reader.readLine())!=null){ buffer.append(line); } }catch(Exception e){ e.printStackTrace(); }finally{ if(null!=reader){ try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return buffer.toString(); }
第二个,是response消息返回给微信平台,我尝试的用最一般的out.print去做,但是发现没反应,观察PHP的代码写法
echo ""; exit;
猜想可能需要有个刷新的操作才能把消息response回去,于是找了下response内的一些函数做出以下尝试
//向请求端发送返回数据 public void print(String content){ try{ final_response.getWriter().print(content); final_response.getWriter().flush(); final_response.getWriter().close(); }catch(Exception e){ } }
发现以上做法是可以在微信发送端得到消息的;
第三个,接口描述上说目前只支持80端口的服务端地址,所以我这里的做法是用apache服务器路由到tomcat的jsp上
关于微信公众平台的消息接口的详细介绍,可以参看微信公众平台的官方文档,里面介绍了消息的xml的格式和消息的发送方式等。
相关推荐
微信公众平台技术文档:客服消息 一、接口说明 当用户和公众号产生特定动作的交互时(具体动作列表请见下方说明),微信将会把消息数据推送给开发者,开发者可以在一段时间内(目前修改为48小时)调用客服接口,通过...
他还是一位资深的Java软件开发工程师和Android/iOS移动应用开发工程师,活跃于CocoaChina、开源中国、CSDN等社区,CSDN博客专家,在CSDN博客撰写了系列微信公众平台二次开发的教程,深受欢迎并被广泛传播,也因此...
微信提供了公众平台支付API,开发者可以调用这些接口来实现支付功能。在Java中,我们需要使用微信官方提供的SDK,如`wxpay-sdk-java`,来与微信服务器进行交互。 2. **生成二维码** - **QRCodeEncoder**: 生成...
### 使用Delphi Xe8 开发微信功能 -- (一)微信支付商户平台之对账单下载 #### 背景介绍 随着移动互联网的发展,微信作为国内最受欢迎的社交软件之一,其提供的各种服务功能也在逐渐扩展。对于企业来说,利用微信...
开放平台(网页应用,移动应用,公众号第三方平台开发) 商户平台(支付) 服务商平台(代支付) 专家 < groupId>com.github.liyiorg</ groupId> < artifactId>weixin-popular < version>2.8.30 </ dependenc
微信提供了公众平台接口,企业微信接口,以及微信小程序接口等,开发者可以通过这些接口发送和接收消息,实现与用户交互。 2. **消息类型与处理**:微信机器人需要识别并处理各种消息类型,包括文本、图片、语音、...
微信支付是中国最流行的移动支付方式之一,其退款功能对于商家来说非常重要,因为它允许在商品或服务出现问题时,为客户提供退款服务。在这个过程中,开发者需要利用微信支付提供的API接口来实现退款申请。以下是对...
4.微信小程序开发框架:微信小程序开发框架是微信平台提供的一种开发框架,用于开发微信小程序的前端和后端。 5.医院挂号系统:医院挂号系统是一种医疗信息系统,用于管理医院的挂号信息和医生信息。 6.患者预约挂号...
通过本课程的学习,学员能够入门微信公众平台开发,能够胜任企业级的订阅号、服务号、企业号的应用开发工作。通过本课程的学习,学员能够对微信公众平台有一个清晰的、系统性的认识。例如,公众号是什么,它有什么...
内容概要:本文结合移动应用开发技术、手机地图服务和HTML前端开发技术,构建了基于 微信公众平台的汽车4S店的智能管理系统,该系统包含微信客户端和后台管理端两个 部分。本文首先釆用Java语言和SpringBoot框架技术...
doGet返回exhostr,给微信平台。 这里我只写第二种方式的请求(这里的请求是以get方式请求),代码如下: import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import ...
包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。 包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python...
本文实例讲述了微信公众平台开发获取用户Openid及个人信息。分享给大家供大家参考,具体如下: 前言: 初次尝试微信公众号的开发,对于学习方法的探索都是来源于网上的博客、问答,对于参差不齐的信息,自己也是有...
现在所有的web端网页商城常用的支付方式之一。web网站开发课程,web网站要实现支付的话,必须学习微信扫码支付。内容逻辑清晰,包你一会就会
本项目是一个基于Java SSM(Spring、SpringMVC、MyBatis)开发框架构建的“最多跑一次”警民政务系统,旨在优化公众与政府服务的交互体验,提高政务服务效率,减少市民办事过程中的繁琐流程。同时,系统还集成了微信...
- 通过开发一款基于微信小程序的消防知识学习平台,可以利用用户的碎片化时间进行学习,增强公众的消防安全意识。 - 提高个人在面对突发事件时的自救互救能力,减少灾害带来的损失。 - 推动消防安全知识普及,构建...
标题中的“基于微信小程序的走失人员报备平台”是一个智能解决方案,利用微信小程序的便捷性和普及性,为公众提供一个快速、有效地报备走失人员的渠道。这个平台可能结合了现代信息技术,如大数据、云计算和人工智能...
本文主要探讨的是基于微信小程序的牙齿健康科普平台的设计与实现,该平台旨在通过微信小程序这一便捷的移动应用,为用户提供牙齿保健知识、疾病预防及治疗建议等服务。平台的开发结合了Java语言、微信小程序技术和...
本项目旨在开发一个基于微信小程序的精准扶贫数据收集平台,利用移动互联网的优势,实现对贫困地区的精准帮扶,助力贫困人口快速脱贫。 #### 二、技术栈概述 - **微信小程序**:作为前端展示平台,负责用户交互...