java怎么验证微信token

Python09

java怎么验证微信token,第1张

token是密码,URL是你部署微信公众号服务器的地址。开发就是将高级功能接口文件部署在服务器上,使能被访问。接口文件在微信公众号帮助文档里面找。token是你在接口文件里自己设置的,设置后回到高级功能里来设置成一样的,目的是告诉公众平台,那个服务器是我的,不信你看token都是一样的,这个过程就是验证密码。

所以,token是你设置的

说明:

本次的教程主要是对微信公众平台开发者模式的讲解,网络上很多类似文章,但很多都让初学微信开发的人一头雾水,所以总结自己的微信开发经验,将微信开发的整个过程系统的列出,并对主要代码进行讲解分析,让初学者尽快上手。

在阅读本文之前,应对微信公众平台的官方开发文档有所了解,知道接收和发送的都是xml格式的数据。另外,在做内容回复时用到了图灵机器人的api接口,这是一个自然语言解析的开放平台,可以帮我们解决整个微信开发过程中最困难的问题,此处不多讲,下面会有其详细的调用方式。

1.1 在登录微信官方平台之后,开启开发者模式,此时需要我们填写url和token,所谓url就是我们自己服务器的接口,用WechatServlet.java来实现,相关解释已经在注释中说明,代码如下:

[java] view plain copy

package demo.servlet

import java.io.BufferedReader

import java.io.IOException

import java.io.InputStream

import java.io.InputStreamReader

import java.io.OutputStream

import javax.servlet.ServletException

import javax.servlet.http.HttpServlet

import javax.servlet.http.HttpServletRequest

import javax.servlet.http.HttpServletResponse

import demo.process.WechatProcess

/**

* 微信服务端收发消息接口

*

* @author pamchen-1

*

*/

public class WechatServlet extends HttpServlet {

/**

* The doGet method of the servlet. <br>

*

* This method is called when a form has its tag value method equals to get.

*

* @param request

*            the request send by the client to the server

* @param response

*            the response send by the server to the client

* @throws ServletException

*             if an error occurred

* @throws IOException

*             if an error occurred

*/

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

request.setCharacterEncoding("UTF-8")

response.setCharacterEncoding("UTF-8")

/** 读取接收到的xml消息 */

StringBuffer sb = new StringBuffer()

InputStream is = request.getInputStream()

InputStreamReader isr = new InputStreamReader(is, "UTF-8")

BufferedReader br = new BufferedReader(isr)

String s = ""

while ((s = br.readLine()) != null) {

sb.append(s)

}

String xml = sb.toString() //次即为接收到微信端发送过来的xml数据

String result = ""

/** 判断是否是微信接入激活验证,只有首次接入验证时才会收到echostr参数,此时需要把它直接返回 */

String echostr = request.getParameter("echostr")

if (echostr != null && echostr.length() > 1) {

result = echostr

} else {

//正常的微信处理流程

result = new WechatProcess().processWechatMag(xml)

}

try {

OutputStream os = response.getOutputStream()

os.write(result.getBytes("UTF-8"))

os.flush()

os.close()

} catch (Exception e) {

e.printStackTrace()

}

}

/**

* The doPost method of the servlet. <br>

*

* This method is called when a form has its tag value method equals to

* post.

*

* @param request

*            the request send by the client to the server

* @param response

*            the response send by the server to the client

* @throws ServletException

*             if an error occurred

* @throws IOException

*             if an error occurred

*/

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response)

}

}

1.2 相应的web.xml配置信息如下,在生成WechatServlet.java的同时,可自动生成web.xml中的配置。前面所提到的url处可以填写例如:http//服务器地址/项目名/wechat.do

[html] view plain copy

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.5"

xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<servlet>

<description>This is the description of my J2EE component</description>

<display-name>This is the display name of my J2EE component</display-name>

<servlet-name>WechatServlet</servlet-name>

<servlet-class>demo.servlet.WechatServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>WechatServlet</servlet-name>

<url-pattern>/wechat.do</url-pattern>

</servlet-mapping>

<welcome-file-list>

<welcome-file>index.jsp</welcome-file>

</welcome-file-list>

</web-app>

1.3 通过以上代码,我们已经实现了微信公众平台开发的框架,即开通开发者模式并成功接入、接收消息和发送消息这三个步骤。

下面就讲解其核心部分——解析接收到的xml数据,并以文本类消息为例,通过图灵机器人api接口实现智能回复。

2.1 首先看一下整体流程处理代码,包括:xml数据处理、调用图灵api、封装返回的xml数据。

[java] view plain copy

package demo.process

import java.util.Date

import demo.entity.ReceiveXmlEntity

/**

* 微信xml消息处理流程逻辑类

* @author pamchen-1

*

*/

public class WechatProcess {

/**

* 解析处理xml、获取智能回复结果(通过图灵机器人api接口)

* @param xml 接收到的微信数据

* @return  最终的解析结果(xml格式数据)

*/

public String processWechatMag(String xml){

/** 解析xml数据 */

ReceiveXmlEntity xmlEntity = new ReceiveXmlProcess().getMsgEntity(xml)

/** 以文本消息为例,调用图灵机器人api接口,获取回复内容 */

String result = ""

if("text".endsWith(xmlEntity.getMsgType())){

result = new TulingApiProcess().getTulingResult(xmlEntity.getContent())

}

/** 此时,如果用户输入的是“你好”,在经过上面的过程之后,result为“你也好”类似的内容

*  因为最终回复给微信的也是xml格式的数据,所有需要将其封装为文本类型返回消息

* */

result = new FormatXmlProcess().formatXmlAnswer(xmlEntity.getFromUserName(), xmlEntity.getToUserName(), result)

return result

}

}

2.2 解析接收到的xml数据,此处有两个类,ReceiveXmlEntity.java和ReceiveXmlProcess.java,通过反射的机制动态调用实体类中的set方法,可以避免很多重复的判断,提高代码效率,代码如下:

[java] view plain copy

package demo.entity

/**

* 接收到的微信xml实体类

* @author pamchen-1

*

*/

public class ReceiveXmlEntity {

private String ToUserName=""

private String FromUserName=""

private String CreateTime=""

private String MsgType=""

private String MsgId=""

private String Event=""

private String EventKey=""

private String Ticket=""

private String Latitude=""

private String Longitude=""

private String Precision=""

private String PicUrl=""

private String MediaId=""

private String Title=""

private String Description=""

private String Url=""

private String Location_X=""

private String Location_Y=""

private String Scale=""

private String Label=""

private String Content=""

private String Format=""

private String Recognition=""

public String getRecognition() {

return Recognition

}

public void setRecognition(String recognition) {

Recognition = recognition

}

public String getFormat() {

return Format

}

public void setFormat(String format) {

Format = format

}

public String getContent() {

return Content

}

public void setContent(String content) {

Content = content

}

public String getLocation_X() {

return Location_X

}

public void setLocation_X(String locationX) {

Location_X = locationX

}

public String getLocation_Y() {

return Location_Y

}

public void setLocation_Y(String locationY) {

Location_Y = locationY

}

public String getScale() {

return Scale

}

public void setScale(String scale) {

Scale = scale

}

public String getLabel() {

return Label

}

public void setLabel(String label) {

Label = label

}

public String getTitle() {

return Title

}

public void setTitle(String title) {

Title = title

}

public String getDescription() {

return Description

}

public void setDescription(String description) {

Description = description

}

public String getUrl() {

return Url

}

public void setUrl(String url) {

Url = url

}

public String getPicUrl() {

return PicUrl

}

public void setPicUrl(String picUrl) {

PicUrl = picUrl

}

public String getMediaId() {

return MediaId

}

public void setMediaId(String mediaId) {

MediaId = mediaId

}

public String getEventKey() {

return EventKey

}

public void setEventKey(String eventKey) {

EventKey = eventKey

}

public String getTicket() {

return Ticket

}

public void setTicket(String ticket) {

Ticket = ticket

}

public String getLatitude() {

return Latitude

}

public void setLatitude(String latitude) {

Latitude = latitude

}

public String getLongitude() {

return Longitude

}

public void setLongitude(String longitude) {

Longitude = longitude

}

public String getPrecision() {

return Precision

}

public void setPrecision(String precision) {

Precision = precision

}

public String getEvent() {

return Event

}

public void setEvent(String event) {

Event = event

}

public String getMsgId() {

return MsgId

}

public void setMsgId(String msgId) {

MsgId = msgId

}

public String getToUserName() {

return ToUserName

}

public void setToUserName(String toUserName) {

1.首先我们新建一个Java开发包WeiXinSDK

2.包路径:com.ansitech.weixin.sdk

测试的前提条件:

假如我的公众账号微信号为:vzhanqun

我的服务器地址为:http://www.vzhanqun.com/

下面我们需要新建一个URL的请求地址

我们新建一个Servlet来验证URL的真实性,具体接口参考

http://mp.weixin.qq.com/wiki/index.php?title=接入指南

3.新建com.ansitech.weixin.sdk.WeixinUrlFilter.java

这里我们主要是获取微信服务器法师的验证信息,具体验证代码如下

[java] view plain copy print?

package com.ansitech.weixin.sdk

import com.ansitech.weixin.sdk.util.SHA1

import java.io.IOException

import java.util.ArrayList

import java.util.Collections

import java.util.Comparator

import java.util.List

import javax.servlet.Filter

import javax.servlet.FilterChain

import javax.servlet.FilterConfig

import javax.servlet.ServletException

import javax.servlet.ServletRequest

import javax.servlet.ServletResponse

import javax.servlet.http.HttpServletRequest

import javax.servlet.http.HttpServletResponse

public class WeixinUrlFilter implements Filter {

//这个Token是给微信开发者接入时填的

//可以是任意英文字母或数字,长度为3-32字符

private static String Token = "vzhanqun1234567890"

@Override

public void init(FilterConfig config) throws ServletException {

System.out.println("WeixinUrlFilter启动成功!")

}

@Override

public void doFilter(ServletRequest req, ServletResponse res,

FilterChain chain) throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) req

HttpServletResponse response = (HttpServletResponse) res

//微信服务器将发送GET请求到填写的URL上,这里需要判定是否为GET请求

boolean isGet = request.getMethod().toLowerCase().equals("get")

System.out.println("获得微信请求:" + request.getMethod() + " 方式")

if (isGet) {

//验证URL真实性

String signature = request.getParameter("signature")// 微信加密签名

String timestamp = request.getParameter("timestamp")// 时间戳

String nonce = request.getParameter("nonce")// 随机数

String echostr = request.getParameter("echostr")//随机字符串

List<String>params = new ArrayList<String>()

params.add(Token)

params.add(timestamp)

params.add(nonce)

//1. 将token、timestamp、nonce三个参数进行字典序排序

Collections.sort(params, new Comparator<String>() {

@Override

public int compare(String o1, String o2) {

return o1.compareTo(o2)

}

})

//2. 将三个参数字符串拼接成一个字符串进行sha1加密

String temp = SHA1.encode(params.get(0) + params.get(1) + params.get(2))

if (temp.equals(signature)) {

response.getWriter().write(echostr)

}

} else {

//处理接收消息

}

}

@Override

public void destroy() {

}

}

好了,不过这里有个SHA1算法,我这里也把SHA1算法的源码给贴出来吧!

4.新建com.ansitech.weixin.sdk.util.SHA1.java

[java] view plain copy print?

/*

* 微信公众平台(JAVA) SDK

*

* Copyright (c) 2014, Ansitech Network Technology Co.,Ltd All rights reserved.

* http://www.ansitech.com/weixin/sdk/

*

* Licensed under the Apache License, Version 2.0 (the "License")

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package com.ansitech.weixin.sdk.util

import java.security.MessageDigest

/**

* <p>Title: SHA1算法</p>

*

* @author [email protected]>

*/

public final class SHA1 {

private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',

'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}

/**

* Takes the raw bytes from the digest and formats them correct.

*

* @param bytes the raw bytes from the digest.

* @return the formatted bytes.

*/

private static String getFormattedText(byte[] bytes) {

int len = bytes.length

StringBuilder buf = new StringBuilder(len * 2)

// 把密文转换成十六进制的字符串形式

for (int j = 0j <lenj++) {

buf.append(HEX_DIGITS[(bytes[j] >>4) &0x0f])

buf.append(HEX_DIGITS[bytes[j] &0x0f])

}

return buf.toString()

}

public static String encode(String str) {

if (str == null) {

return null

}

try {

MessageDigest messageDigest = MessageDigest.getInstance("SHA1")

messageDigest.update(str.getBytes())

return getFormattedText(messageDigest.digest())

} catch (Exception e) {

throw new RuntimeException(e)

}

}

}

5.把这个Servlet配置到web.xml中

[html] view plain copy print?

<filter>

<description>微信消息接入接口</description>

<filter-name>WeixinUrlFilter</filter-name>

<filter-class>com.ansitech.weixin.sdk.WeixinUrlFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>WeixinUrlFilter</filter-name>

<url-pattern>/api/vzhanqun</url-pattern>

</filter-mapping>

好了,接入的开发代码已经完成。

6.下面就把地址URL和密钥Token填入到微信申请成为开发者模式中吧。