jsp 微信公众平台 token验证(php、jsp)(转载)
微信公众平台现在推出自动回复消息接口,但是由于是接口内容用的是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的格式和消息的发送方式等。
转载地址:http://blog.csdn.net/wangqianjiao/article/details/8469780/
jsp 微信公众平台 token验证(php、jsp)(转载)的更多相关文章
- 微信公众平台Token验证失败的解决办法
微信公众平台Token验证失败的解决办法 1.可查看url和token是否正确 2.查看服务器端口是否为80端口 3.你可以通过记录log日志来判断是否接受到微信提交过来的信息 1.$fp=fopen ...
- 微信公众平台——token验证php版
这几天开始接触微信公众号的开发,注册这些就不说了,我是先弄了个测试号用着.进入正题 所谓token验证,其实就是微信服务器向自己要用到的服务器url发送一段数据,其中有一个参数$_GET['echho ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(三):微信公众平台开发验证
要对接微信公众平台的"开发模式",即对接到自己的网站程序,必须在注册成功之后(见Senparc.Weixin.MP SDK 微信公众平台开发教程(一):微信公众平台注册),等待官方 ...
- 微信公众平台企业号验证接口、回调 PHP版
微信公众平台企业号验证接口.回调 PHP版,本人为了解决这个企业号的验证和发送消息的问题,整整研究了几天时间,由于微信企业号刚推出来,网上资料太少了!后来在一些朋友的帮助下和本人重复调试完好下,最终整 ...
- Thinkphp5 微信公众号token验证不成功的原因
最近要启动微信项目,上个月就开始了解微信的开发,这个月要启动项目,配置微信公众号信息一直失败.为此,我甚至手工写了微信提交过来的记录,如: ×tamp=1510210523& ...
- 服务器通过微信公众号Token验证测试的代码(Python版)
我在阿里云租了一个云服务器,然后想把这个作为我的微信公众号的后台,启用微信公众号开发者需要正确的响应微信服务器的Token验证,为此把这个验证的Python代码贴出来,只要在服务器上运行这段代码,注意 ...
- C#开发微信公众平台-就这么简单(转载)
写在前面 服务号和订阅号 URL配置 创建菜单 查询.删除菜单 接受消息 发送消息(图文.菜单事件响应) 示例Demo下载 后记 最近公司在做微信开发,其实就是接口开发,网上找了很多资料,当然园友也写 ...
- 分享:在微信公众平台做HTML5游戏经验谈(转载与http://software.intel.com/zh-cn/blogs/2013/04/03/html5)
分享:在微信公众平台做HTML5游戏经验谈 Dawei Cheng 程大伟... 于 星期三, 03/04/2013 - 03:19 提交 最近微信公众游戏平台讨论得如火如荼,大有HTML5游戏即将引 ...
- 微信公众号token验证失败的一些总结
这几天准备弄一个微信公众号,在进行服务器配置的时候出现总是出现token验证失败的报错. 实际上,这个问题很好解决.既然微信平台没有给我们很明确的报错提示,那么我们就可以通过跟踪获取到的请求参数进行分 ...
随机推荐
- java微信开发(wechat4j)——发送客服消息
微信支持主动发送客服消息.如果你要实现此功能,需要使用CustomerMsg类. 获得access_token access_token请求之后有一个过期时间,微信平台建议你使用一个中控服务器来定时刷 ...
- Telegram传奇:俄罗斯富豪、黑客高手、极权和阴谋…
说了很久要写Telegram的故事,一直拖延没有写.在我拖延的这段时间里面,Telegarm继续快速增长,前几天,在旧金山的TechCrunch Disrupt活动上,创始人Durov说现在Teleg ...
- 硬盘变成RAW的修复过程
可能在不知道为什么的情况下,移动硬盘或者本地磁盘的每个分区变成了RAW格式.其在Win系统下的无损修复过程如下: 用“win”+“R”打开“运行”小窗口: 键入“CMD”: 键入命令“CHKDSK P ...
- 通过sftp实现文件分发功能
1 环境: 分发服务器:ubuntu server 64bit,192.168.56.22 接受服务器:windows server 2008,192.168.56.102 2 ...
- MX4连接后adb无法识别解决方法
1. 使用android SDK目录中的 android SDK目录\tools 下的android脚本,命令行中执行 android update adb,成功运行后,会在用户名录下产生,C:\Us ...
- JAVA基础学习day23--GUI基础
一.GUI概述 1.1.GUI概述 Graphical User Interface(图形用户接口) 用图形的方式,来显示计算机操作的界面, CLI: Command line User Interf ...
- IOS 杂笔-18 (let 与 var)
var 是 variable的缩写形式,是变量的意思 ,是可改变的,并不是数据类型. let 是常量的意思,不可改变的.
- iOS开发笔记2:单例模式(singleton)
每一个app有且仅有一个UIApplication,类似UIApplication“ [UIApplication sharedApplication]”这种一个类有且仅有唯一实例的设计即单例模式. ...
- 在Dynamics CRM 2015中通过3CX插件(以及3CX windows phone)拨出电话
背景 在On-premises部署的Dynamics CRM中实现通过网页拨通客户电话的功能 要点 3CX 提供了开箱即用的Dynamics CRM Solution,只需要在Microsoft Dy ...
- 怎么录制Android或IOS动画教程
前一篇文章介绍了用DemoCreator制作Android视频教程,今天再介绍一种方法. 那就是用GifCam软件录制,此软件录制导出成Gif动画图片,可直接放在你的文章里面,效果比flash要好. ...