详解微信开发微信jsapi与java初步接入方法

参数名

http://www.jb51.cc/wiki/835.html target=_blank>width=346 valign=top style=word-break:break-all> 描述
appId应用ID 登录微信公众号管理平台可查询
timestamp 必填,生成签名的时间戳
nonceStr必填,生成签名的随机串
signature必填,签名,见附录1

上述表格中的参数,我们在前一章节已经说的很明白,之所以做出一个表格是因为如果想要成功接入微信jsapi这四个参数是凭证,也就是相当于一个门必须要有四把钥匙才能打开,缺一不可 。

接下来的案例采用java的servlet做的跳转页面,没有用到springMVC,大家可把请求的路径更换成controller路径即可。

WxJsAPIServlet代码:

package com.test;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Map;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.test.util.JsapiTicketUtil;

import com.test.util.Sign;

public class WxJsAPIServlet extends HttpServlet {

/**

* Constructor of the object.

*/

public WxJsAPIServlet() {

super();

}

/**

* Destruction of the servlet. <br>

*/

public void destroy() {

super.destroy(); // Just puts destroy string in log

// Put your code here

}

/**

* 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 {

System.out.println(wxJSAPI====================);

String jsapi_ticket =JsapiTicketUtil.getJSApiTicket();;

Map<String,String> map = Sign.sign(jsapi_ticket, http://www.vxzsk.com/weChat/wxJsAPIServlet);

String timestamp = map.get(timestamp);

String nonceStr = map.get(nonceStr);

String signature = map.get(signature);

String appId = 应用Id;

request.setAttribute(appId, appId);

request.setAttribute(timestamp, timestamp);

request.setAttribute(signature,signature);

request.setAttribute(nonceStr, nonceStr);

request.getRequestDispatcher(jsapi/jsapi.jsp).forward(request, response);

}

/**

* 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 {

this.doGet(request, response);

}

/**

* Initialization of the servlet. <br>

*

* @throws ServletException if an error occurs

*/

public void init() throws ServletException {

// Put your code here

}

}

第44行是生成 jsapi_ticket的工具类,在下面有贴出工具类的代码。

第45行 Sign类的sign方法,把表格中的最后三个参数封装放到Map集合中了。其中参数就是请求的servlet地址并跳转到调用微信jsapi的jsp界面。

第49行 appId替换成你自己的应用id,如果不知道应用id 可登陆微信公众平台管理中心查询。

servlet对应的web.xml代码

<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>WxJsAPIServlet</servlet-name>

<servlet-class>com.test.WxJsAPIServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>WxJsAPIServlet</servlet-name>

<url-pattern>/wxJsAPIServlet</url-pattern>

</servlet-mapping>

生成签名算法类Sign代码:

package com.test.util;

/***

* V型知识库 www.vxzsk.com

*/

import java.util.UUID;

import java.util.Map;

import java.util.HashMap;

import java.util.Formatter;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.io.UnsupportedEncodingException;

public class Sign {

public static Map<String, String> sign(String jsapi_ticket, String url) {

Map<String, String> ret = new HashMap<String, String>();

String nonce_str = create_nonce_str();

String timestamp = create_timestamp();

String string1;

String signature = ;

//注意这里参数名必须全部小写,且必须有序

string1 = jsapi_ticket= + jsapi_ticket +

&noncestr= + nonce_str +

&timestamp= + timestamp +

&url= + url;

System.out.println(string1);

try

{

MessageDigest crypt = MessageDigest.getInstance(SHA-1);

crypt.reset();

crypt.update(string1.getBytes(UTF-8));

signature = byteToHex(crypt.digest());

}

catch (NoSuchAlgorithmException e)

{

e.printStackTrace();

}

catch (UnsupportedEncodingException e)

{

e.printStackTrace();

}

ret.put(url, url);

ret.put(jsapi_ticket, jsapi_ticket);

ret.put(nonceStr, nonce_str);

ret.put(timestamp, timestamp);

ret.put(signature, signature);

return ret;

}

private static String byteToHex(final byte[] hash) {

Formatter formatter = new Formatter();

for (byte b : hash)

{

formatter.format(%02x, b);

}

String result = formatter.toString();

formatter.close();

return result;

}

private static String create_nonce_str() {

return UUID.randomUUID().toString();

}

private static String create_timestamp() {

return Long.toString(System.currentTimeMillis() / 1000);

}

public static void main(String[] args) {

String jsapi_ticket =JsapiTicketUtil.getJSApiTicket();

// 注意 URL 一定要动态获取,不能 hardcode

String url = http://www.vxzsk.com/xx/x.do;//url是你请求的一个action或者controller地址,并且方法直接跳转到使用jsapi的jsp界面

Map<String, String> ret = sign(jsapi_ticket, url);

for (Map.Entry entry : ret.entrySet()) {

System.out.println(entry.getKey() + , + entry.getValue());

}

};

}

生成jsapi_ticket参数的工具类JsapiTicketUtil代码

package com.test.util;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.MalformedURLException;

import java.net.URL;

import java.net.URLConnection;

import net.sf.json.JSONObject;

import com.test.weixin.TestAcessToken;

public class JsapiTicketUtil {

/***

* 模拟get请求

* @param url

* @param charset

* @param timeout

* @return

*/

public static String sendGet(String url, String charset, int timeout)

{

String result = ;

try

{

URL u = new URL(url);

try

{

URLConnection conn = u.openConnection();

conn.connect();

conn.setConnectTimeout(timeout);

BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));

String line=;

while ((line = in.readLine()) != null)

{

result = result + line;

}

in.close();

} catch (IOException e) {

return result;

}

}

catch (MalformedURLException e)

{

return result;

}

return result;

}

public static String getAccessToken(){

String appid=你公众号基本设置里的应用id;//应用ID

String appSecret=你公众号基本设置里的应用密钥;//(应用密钥)

String url =https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=+appid+&secret=+appSecret+;

String backData=TestAcessToken.sendGet(url, utf-8, 10000);

String accessToken = (String) JSONObject.fromObject(backData).get(access_token);

return accessToken;

}

public static String getJSApiTicket(){

//获取token

String acess_token= JsapiTicketUtil.getAccessToken();

String urlStr = https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=+acess_token+&type=jsapi;

String backData=TestAcessToken.sendGet(urlStr, utf-8, 10000);

String ticket = (String) JSONObject.fromObject(backData).get(ticket);

return ticket;

}

public static void main(String[] args) {

String jsapiTicket = JsapiTicketUtil.getJSApiTicket();

System.out.println(调用微信jsapi的凭证票为:+jsapiTicket);

}

}

上述代码中有个获取access_token的方法,请读者更换自己的参数即可

jsapi.jsp代码

<%@ page language=java import=java.util.* pageEncoding=utf-8%>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+://+request.getServerName()+:+request.getServerPort()+path+/;

%>

<!DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN>

<html>

<head>

<base href=<%=basePath%>>

<title>微信jsapi测试-V型知识库</title>

<meta name=viewport content=width=320.1,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no>

<script src=http://res.wx.qq.com/open/js/jweixin-1.1.0.js> </script>

</head>

<body>

<center><h3>欢迎来到微信jsapi测试界面-V型知识库</h3></center>

<br>

<p>timestamp:${ timestamp}</p>

<p>nonceStr:${ nonceStr}</p>

<p>signature:${ signature}</p>

<p>appId:${ appId}</p>

<input type=button value=upload onclick=uploadImg();/>

<input type=button value=获取当前位置 onclick=getLocation();/>

<br>

<script type=text/javascript>

wx.config({

debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。

appId: '${appId}', // 必填,公众号的唯一标识

timestamp: '${ timestamp}' , // 必填,生成签名的时间戳

nonceStr: '${ nonceStr}', // 必填,生成签名的随机串

signature: '${ signature}',// 必填,签名,见附录1

jsApiList: ['chooseImage','getLocation','openLocation'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2

});

wx.ready(function(){

alert(ready);

});

wx.error(function (res) {

alert(调用微信jsapi返回的状态:+res.errMsg);

});

function uploadImg() {

wx.checkJsApi({

jsApiList: ['chooseImage','openLocation','getLocation'], // 需要检测的JS接口列表,所有JS接口列表见附录2,

success: function(res) {

// 以键值对的形式返回,可用的api值true,不可用为false

// 如:{checkResult:{chooseImage:true},errMsg:checkJsApi:ok}

alert(res);

wx.chooseImage({

count: 1, // 默认9

sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有

sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有

success: function (res) {

var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片

alert(localIds);

}

});

}

});

}

function getLocation() {

var latitude = ;

var longitude = ;

wx.getLocation({

type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'

success: function (res) {

latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90

longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。

var speed = res.speed; // 速度,以米/每秒计

var accuracy = res.accuracy; // 位置精度

wx.openLocation({

latitude: latitude, // 纬度,浮点数,范围为90 ~ -90

longitude: longitude, // 经度,浮点数,范围为180 ~ -180。

name: '你当前的位置', // 位置名

address: 'currentLocation', // 地址详情说明

scale: 26, // 地图缩放级别,整形值,范围从1~28。默认为最大

infoUrl: '' // 在查看位置界面底部显示的超链接,可点击跳转

});

}

});

}

</script>

</body>

</html>


测试场景:打开微信公众号,点击菜单回复带有请求servlet地址,跳转到jsapi.jsp界面链接地址,然后界面会弹出调用微信jsapi成功或失败的窗口信息,所以还需要接下来的代码:

WeChatServlet为微信接入的servlet,不清楚的同学可学习我们的微信开发教程。

package com.test;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Date;

import java.util.Map;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.test.message.resp.TextMessage;

import com.test.util.MessageUtil;

/**

* 核心请求处理类

* doGet方法里 有个weixinTest,这个是公众管理平台里面自己设置的token 大家根据自己的token替换

*/

public class WeChatServlet extends HttpServlet {

private static final long serialVersionUID = 1508798736675904038L;

/**

* 确认请求来自微信服务器

*/

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

System.out.println(V型知识库原创www.vxzsk.com);

// 微信加密签名

String signature = request.getParameter(signature);

System.out.println(微信加密签名signature:-----------------------+signature);

// 时间戳

String timestamp = request.getParameter(timestamp);

System.out.println(时间戳timestamp:-----------------------+timestamp);

// 随机数

String nonce = request.getParameter(nonce);

System.out.println(随机数nonce:-----------------------+nonce);

// 随机字符串

String echostr = request.getParameter(echostr);

System.out.println(随机字符串echostr:-----------------------+echostr);

//System.out.println(token-----------------------:+token);

PrintWriter out = response.getWriter();

// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败

if (SignUtil.checkSignature(weixinTest, signature, timestamp, nonce)) {

out.print(echostr);

//System.out.println(这是:+echostr);

}

out.close();

out = null;

}

/**

* 处理微信服务器发来的消息

* 实例源码在文章顶部有下载连接

*/

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

System.out.println(V型知识库原创www.vxzsk.com);

System.out.println(微信服务器发来消息------------);

// 将请求、响应的编码均设置为UTF-8(防止中文乱码)

request.setCharacterEncoding(UTF-8);

response.setCharacterEncoding(UTF-8);

String respMessage = null;

try{

//xml请求解析

Map<String, String> requestMap = MessageUtil.parseXml(request);//接收微信发过来的xml格式

//发送方帐号(open_id)

String fromUserName = requestMap.get(FromUserName);

//公众帐号

String toUserName = requestMap.get(ToUserName);

//消息类型

String msgType = requestMap.get(MsgType);

//消息创建时间

String createTime = requestMap.get(CreateTime);

//微信服务器post过来的内容

String weixinContent = requestMap.get(Content);

System.out.println(公众号用户发送过来的文本消息内容:+weixinContent);

//接下来我们用上一章节自己封装好的工具类

if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {//文本类型 用户回复 “hh” 微信自动回复此条消息

//回复换行的文本消息

TextMessage textMessage = new TextMessage();

textMessage.setToUserName(fromUserName);

textMessage.setFromUserName(toUserName);

textMessage.setCreateTime(new Date().getTime());

textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);

textMessage.setFuncFlag(0);

//回复用户的换行字符串 \n表示换行

StringBuffer buffer = new StringBuffer();

if(weixinContent.equals(hh)){//如果用户发送”hh“

buffer.append(欢迎访问).append(\n);

buffer.append(<a href=\http://www.vxzsk.com/weChat/wxJsAPIServlet\>微信jsapi测试界面</a>).append(\n\n);

buffer.append(回复'hh'二字即可能显示此条消息);

}else{

buffer.append(您好我是V型知识库);

}

textMessage.setContent(buffer.toString());

respMessage = MessageUtil.textMessageToXml(textMessage);//转换成xml格式

}

// 响应回复消息

PrintWriter out = response.getWriter();

out.print(respMessage);

out.close();

}catch(Exception e){

e.printStackTrace();

}

}

}

MessageUtil工具类

package com.test.util;

import java.io.InputStream;

import java.io.Writer;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;

import org.dom4j.Element;

import org.dom4j.io.SAXReader;

import com.test.message.resp.Article;

import com.test.message.resp.MusicMessage;

import com.test.message.resp.NewsMessage;

import com.test.message.resp.TextMessage;

import com.thoughtworks.xstream.XStream;

import com.thoughtworks.xstream.core.util.QuickWriter;

import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;

import com.thoughtworks.xstream.io.xml.XppDriver;

/**

* 消息工具类

*/

public class MessageUtil {

/**

* 返回消息类型:文本

*/

public static final String RESP_MESSAGE_TYPE_TEXT = text;

/**

* 返回消息类型:音乐

*/

public static final String RESP_MESSAGE_TYPE_MUSIC = music;

/**

* 返回消息类型:图文

*/

public static final String RESP_MESSAGE_TYPE_NEWS = news;

/**

* 请求消息类型:文本

*/

public static final String REQ_MESSAGE_TYPE_TEXT = text;

/**

* 请求消息类型:图片

*/

public static final String REQ_MESSAGE_TYPE_IMAGE = image;

/**

* 请求消息类型:链接

*/

public static final String REQ_MESSAGE_TYPE_LINK = link;

/**

* 请求消息类型:地理位置

*/

public static final String REQ_MESSAGE_TYPE_LOCATION = location;

/**

* 请求消息类型:音频

*/

public static final String REQ_MESSAGE_TYPE_VOICE = voice;

/**

* 请求消息类型:推送

*/

public static final String REQ_MESSAGE_TYPE_EVENT = event;

/**

* 事件类型:subscribe(订阅)

*/

public static final String EVENT_TYPE_SUBSCRIBE = subscribe;

/**

* 事件类型:unsubscribe(取消订阅)

*/

public static final String EVENT_TYPE_UNSUBSCRIBE = unsubscribe;

/**

* 事件类型:CLICK(自定义菜单点击事件)

*/

public static final String EVENT_TYPE_CLICK = CLICK;

/**

* 解析微信发来的请求(XML)

*

* @param request

* @return

* @throws Exception

*/

@SuppressWarnings(unchecked)

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;

}

/**

* 文本消息对象转换成xml

* @param textMessage 文本消息对象

* @return xml

*/

public static String textMessageToXml(TextMessage textMessage) {

xstream.alias(xml, textMessage.getClass());

return xstream.toXML(textMessage);

}

/**

* 音乐消息对象转换成xml

* @param musicMessage 音乐消息对象

* @return xml

*/

public static String musicMessageToXml(MusicMessage musicMessage) {

xstream.alias(xml, musicMessage.getClass());

return xstream.toXML(musicMessage);

}

/**

* 图文消息对象转换成xml

* @param newsMessage 图文消息对象

* @return xml

*/

public static String newsMessageToXml(NewsMessage newsMessage) {

xstream.alias(xml, newsMessage.getClass());

xstream.alias(item, new Article().getClass());

return xstream.toXML(newsMessage);

}

/**

* 扩展xstream,使其支持CDATA块

* @date

*/

private static XStream xstream = new XStream(new XppDriver() {

public HierarchicalStreamWriter createWriter(Writer out) {

return new PrettyPrintWriter(out) {

// 对所有xml节点的转换都增加CDATA标记

boolean cdata = true;

@SuppressWarnings(unchecked)

public void startNode(String name, Class clazz) {

super.startNode(name, clazz);

}

protected void writeText(QuickWriter writer, String text) {

if (cdata) {

writer.write(<![CDATA[);

writer.write(text);

writer.write(]]>);

} else {

writer.write(text);

}

}

};

}

});

}

TextMessage代码

package com.test.message.resp;

public class TextMessage extends BaseMessage {

// 回复的消息内容

private String Content;

public String getContent() {

return Content;

}

public void setContent(String content) {

Content = content;

}

}

BaseMessage代码

package com.test.message.resp;

/**

* 消息基类(公众帐号 -> 普通用户)

*/

public class BaseMessage {

// 接收方帐号(收到的OpenID)

private String ToUserName;

// 开发者微信号

private String FromUserName;

// 消息创建时间 (整型)

private long CreateTime;

// 消息类型(text/music/news)

private String MsgType;

// 位0x0001被标志时,星标刚收到的消息

private int FuncFlag;

public String getToUserName() {

return ToUserName;

}

public void setToUserName(String toUserName) {

ToUserName = toUserName;

}

public String getFromUserName() {

return FromUserName;

}

public void setFromUserName(String fromUserName) {

FromUserName = fromUserName;

}

public long getCreateTime() {

return CreateTime;

}

public void setCreateTime(long createTime) {

CreateTime = createTime;

}

public String getMsgType() {

return MsgType;

}

public void setMsgType(String msgType) {

MsgType = msgType;

}

public int getFuncFlag() {

return FuncFlag;

}

public void setFuncFlag(int funcFlag) {

FuncFlag = funcFlag;

}

}

效果如下:

详解微信开发微信jsapi与java初步接入方法

详解微信开发微信jsapi与java初步接入方法

详解微信开发微信jsapi与java初步接入方法

详解微信开发微信jsapi与java初步接入方法

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


网页授权获取用户信息的方法
报错config:invalid signature的解决方案
微信开发百思不得姐实战教程
详解微信开发input输入框
教你libco是如何支撑巨大数据信息量的
微信二次开发之文本消息请求与发送
微信开发H5轻游戏
scroll-view完成列表页的方法详解
Java微信开发之自定义菜单的创建
微信开发之input控件的实例详解
微信开发Emoji表情的实例教程
微信开发中详解textarea的使用方法
微信开发中使元素占满全屏的方法介绍
微信开发之数据访问的方法详解
微信二次开发之各类型消息封装
微信开发之数据库操作
如何获取微信好友的地理位置信息
分享3款微信开发开源框架
微信开发之获取服务器IP
微信开发之公交换乘功能代码详解