`

移动开发:微信公众平台消息接口-java-jsp版(转)

 
阅读更多

转载自: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的格式和消息的发送方式等。

 

分享到:
评论

相关推荐

    微信公众平台 客服接口发消息的实现代码(Java接口开发)

    微信公众平台技术文档:客服消息 一、接口说明 当用户和公众号产生特定动作的交互时(具体动作列表请见下方说明),微信将会把消息数据推送给开发者,开发者可以在一段时间内(目前修改为48小时)调用客服接口,通过...

    微信公众平台应用开发:方法、技巧与案例.(机械工业.柳峰)

    他还是一位资深的Java软件开发工程师和Android/iOS移动应用开发工程师,活跃于CocoaChina、开源中国、CSDN等社区,CSDN博客专家,在CSDN博客撰写了系列微信公众平台二次开发的教程,深受欢迎并被广泛传播,也因此...

    微信公众平台 发送模板消息(Java接口开发)

    微信公众平台技术文档:模板消息接口 一、概述 模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等。不支持广告等营销类消息以及其它所有可能对...

    微信公众号:微信SDK JAVA(公众平台,开放平台,商户平台,服务商平台)

    开放平台(网页应用,移动应用,公众号第三方平台开发) 商户平台(支付) 服务商平台(代支付) 专家 &lt; groupId&gt;com.github.liyiorg&lt;/ groupId&gt; &lt; artifactId&gt;weixin-popular &lt; version&gt;2.8.30 &lt;/ dependenc

    微信公众平台开发入门

    通过本课程的学习,学员能够入门微信公众平台开发,能够胜任企业级的订阅号、服务号、企业号的应用开发工作。通过本课程的学习,学员能够对微信公众平台有一个清晰的、系统性的认识。例如,公众号是什么,它有什么...

    Java基于微信平台的4S店智能管理系统的设计与实现

    内容概要:本文结合移动应用开发技术、手机地图服务和HTML前端开发技术,构建了基于 微信公众平台的汽车4S店的智能管理系统,该系统包含微信客户端和后台管理端两个 部分。本文首先釆用Java语言和SpringBoot框架技术...

    Java微信公众平台开发模式+自定义按钮

    doGet返回exhostr,给微信平台。  这里我只写第二种方式的请求(这里的请求是以get方式请求),代码如下: import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import ...

    基于Java的微信公众平台开发框架,包括基础消息收发核心框架,基础API框架,以及应用层的web框架.zip

    包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。 包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python...

    微信公众平台开发教程①获取用户Openid及个人信息图文详解

    本文实例讲述了微信公众平台开发获取用户Openid及个人信息。分享给大家供大家参考,具体如下: 前言: 初次尝试微信公众号的开发,对于学习方法的探索都是来源于网上的博客、问答,对于参差不齐的信息,自己也是有...

    微信支付微信扫码支付java版

    现在所有的web端网页商城常用的支付方式之一。web网站开发课程,web网站要实现支付的话,必须学习微信扫码支付。内容逻辑清晰,包你一会就会

    微信公众号开发入门模式启用与消息回复一学就会java版

    微信开发系列的入门,包括模式启用和各类的消息回复,让大家对微信开发有基本的理解,也为大家进行其他微信公众号接口开发打开大门

    微信公众号开发客服消息与模板消息开发一会就会java版

    及时和用户进行沟通以及反馈也是微信公众号开发的一个重要内容,那么微信客服和模板就解决了这个问题,本套课程带领大家一起去学习客服消息和模板消息

    基于微信小程序的智慧流调微信小程序(java) cx11.zip

    智慧流调微信小程序是一款基于微信小程序平台开发的应用程序,旨在帮助用户更有效地进行流行病学调查。该程序采用Java编程语言进行开发,具有以下特点:用户友好的界面设计:智慧流调微信小程序采用了简洁明了的用户...

    ionic混合开发APP

    可以快速开发移动APP、移动WEB页面、微信公众平台应用,混合APP WEB页面。 2.1.2 Ionic和cordova、Angular关系 Ionic = cordova + Angular + ionic Css Ionic 是完全基于谷歌的 Angular 框架,在 Angular 基础...

    微信公众号开发自定义菜单一会就会java版

    微信公众号的自定义菜单是微信开发基础课程之一,不论是订阅号还是服务号都必须学会和精通自定义菜单

    基于区块链的开放、去中心化生态系统。.zip

    集微信公众平台,微信小程序,h5网页端,pc端,app及ios端,百度小程序,阿里小程序等与一体的开发框架。 完善的更新机制,应用发布体制及售后维护系统,为整个生态助力。 软件开发设计:PHP、QT、应用软件开发、...

    微信公众号生成带参数二维码一学就会Java版

    为了满足用户渠道推广分析和用户帐号绑定等场景的需要,也就是推广和微商城分销的一个知识点,当你需要知道你的这个客户是谁推广的时候,当你为你的商城设计了分销的模式的时候,你就会发现这个知识点很好用

    最新最全微信支付集成SDK.zip

    包含基础支付功能(网页授权、各种签名、统一下单、退款、对账单、用户信息获取)、验收用例指引(沙箱支付、支付验收、免充值产品开通)、商户平台(现金红包、企业付款到用户、代金券或立减优惠)、公众平台(微信...

    WODECMS开源内容管理系统 v1.1.zip

    目前已经广泛应用于移动开发,电商平台,微信公众平台等领域。它完全能胜任和满足大中型平台站点的需求。其中CMS只起到一个抛砖引玉的作用,基于此框架和我的CMS系统上,可以解决移动APP后台服务、多媒体信息、O2O、...

    WODECMS开源内容管理系统

    目前已经广泛应用于移动开发,电商平台,微信公众平台等领域。它完全能胜任和满足大中型平台站点的需求。其中CMS只起到一个抛砖引玉的作用,基于此框架和我的CMS系统上,可以解决移动APP后台服务、多媒体信息、O2O、...

Global site tag (gtag.js) - Google Analytics