微信内嵌网页 签名生成 js-sdk开发

最近完成了微信内嵌网页调用js-sdk接口开发,现将经验奉上。讲讲走过的坑 微信内嵌网页开发做的过程感觉好麻烦  做完后却感觉很简单

1:微信公众号/企业号配置  关于这种配置网上大把大把的资源,首先你得有服务器 域名等  这点如果已经参与工作公司应该是有服务器的,而没的人也不要担心,

去看看网上有关于这方面教程吧,这里就讲下大致的流程和重要的地方,进入公众号开发选项后只需要关注几点,我做的公众号是基于公众号里面菜单的  而这个菜单是自己可以图形化操作添加上去的,不会编程都会,毕竟微信这个公众号平台的话还是挺完善的,这个菜单添加上我们项目链接就好了,然后还得配安全域名呀,还得把那个什么个txt文件下下来放在我们微信项目上去,这里准备工作大致就是酱,一般能第一次配成功的算是叼的  嘿嘿  这里再说说出问题的几个原因吧  域名错误,自己好好看看域名格式是不是对的  没事自己换换吧。

2:正式调用微信js-sdk从而使用其中的一些东西,比如调用手机摄像头呀  图片呀  扫码呀  一大堆东西  具体的去看看开发文档吧,这里就主要说下签名生成 一大把一大把的人都是签名生成错误(哈 哈 哈)我当初被签名错误折磨好多天了 下面我介绍下签名生成流程(很多人用微信那个签名检测工具是对的然而还是签名错误  蛋疼吧  哈 哈 哈)

一般微信内嵌网页由于项目代码量比较少 轻量 项目架构用的比较简单  我的项目架构就用的jsp+servlet+jdbc 简单吧 

获取签名流程无非就是  getAccessToken  >  getJSApiTicket >得到一系列东西  然后其中有一点就是那个accesstoken两个小时就过期了  所以得自己改代码  知道更新token值 然后看了下网上有很多种方法  线程 ,数据库什么的  感觉这样好麻烦一切从简  利用TimerTask类即可,现在就上代码吧 代码就上重要部分 你总不能叫我把页面,包呀都发上来吧

开发流程

(1):前端流程:首先说到微信菜单  也就是我们这个项目进入的地方(比如拿下面这图表示)你可以跳页面然后加载页面的时候请求到后台拿到签名然后返回前台(我就是用这啊种,你也可以连接改成请求比如点击“菜单一”它的href为:http://xxx/xx/xx.action)到后台然后后台处理把签名返回到前台,我这代码跟其他人都一样都一样流程 前台获取链接url到后台去 这里我的appid就直接放在前台了 没通过后台传过来,安全性的话没怎么考虑 不过我这里js有部分处理是判断当前页面是否在手机端 如果在手机端就页面渲染 否则网页会打不开 不显示 给些什么提示 右键查看源码也看不到appid,这是后话了。

<script type="text/javascript">
var str = "";
var openid="";
var checkFlag = false;
//var appId = "";
$(document)
.ready(
function() {
$.ajax({
type : "GET",
url : "GoIndex",
data : {
"url" : str
},
dataType : "text",
success : function(data) {
var timestamp = JSON.parse(data).timestamp;
var nonceStr = JSON.parse(data).nonceStr;
var signature = JSON.parse(data).signature;
wx.config({
debug : false,
appId : "xxxxxx",
timestamp : timestamp,
nonceStr : nonceStr,
signature : signature,
jsApiList : [ 'checkJsApi', 'scanQRCode' ]
});//end_config  
wx.error(function(res) {

webToast("出错了:" + res.errMsg,"middle",3000);
});
}
});
wx.ready(function() {
wx.checkJsApi({
jsApiList : [ 'scanQRCode' ],
success : function(res) {
}
});
//扫描二维码  
document.querySelector('#scanQRCode').onclick = function() {
wx.scanQRCode({
needResult : 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,  
scanType : [ "qrCode","barCode" ], // 可以指定扫二维码还是一维码,默认二者都有  
success : function(res) {

}
});
};//end_document_scanQRCode  
});

});
//获取整个地址栏 
function getUrl() {
var name, value;
str = location.href; //取得整个地址栏
}


</script>



(2):后台首先第一个类Taskinit就是个servlet  配置文件只配置 这个servlet 在项目启动时就执行 并且过一个小时就重新执行一次 重新获取一系列东西

其他代码跟网上的几乎一样(我不会告诉你我是copy下来然后改点东西的)这点东西没什么好讲的 毕竟就这么点东西 实现方法就酱了  我要说的是个整体上的流程

整体上的布局大家知道这个就好了  后台获取凭证都是通过myTaskGetToken这个类 这个类用来存储   jsapi_ticket;
accesstoken;和生成凭证的,然后底层那些掉接口生成东西的就不讲了 大概就这么多了  我还是不太希望大家全部复制粘贴  还是自己写写比较好  如果直接复制的话估计效果出不来  只要按流程来一般是没什么问题  自己多写写代码吧  接口调用了 然后你就可以调页面了 开发正式开始你可以开始表演了  源码也发到资源库去吧

<!-- 定时获取token -->
<servlet>
<servlet-name>Taskinit</servlet-name>
<servlet-class>weixin.rokin.action.Taskinit</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>


public class Taskinit extends HttpServlet {
private TimerTaskGetToken  myTaskGetToken;
public Taskinit() {
super();
}
public void init() throws ServletException {
System.out.println("开启定时器");
Timer timer = new Timer();
myTaskGetToken = new TimerTaskGetToken();
        timer.schedule(myTaskGetToken, 0, 1000*60*60);
}


}




private TimerTaskGetToken  myTaskGetToken;

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");   
        PrintWriter out=response.getWriter();   
/*String url = request.getScheme()+"://"+request.getServerName()+":"+
request.getContextPath()+request.getServletPath()+"?"+request.getQueryString();*/
//StringBuffer url=GetUrl.geturlanddata(request);
String url=request.getParameter("url");
TimerTaskGetToken.getSignature(url.toString());
System.out.println("servlet:"+url);
Map<String, String> map = myTaskGetToken.getmap;
if(map.size()>0&&map!=null){
timestamp = map.get("timestamp");
nonceStr = map.get("nonceStr");
signature = map.get("signature");
}
System.out.println("servlet值:"+timestamp+"||"+nonceStr+"||"+signature);
/*request.setAttribute("timestamp", timestamp);
request.setAttribute("signature", signature);
request.setAttribute("nonceStr", nonceStr);*/
Map<String, String> map2=new HashMap<String, String>();
map2.put("timestamp", timestamp);
map2.put("signature", signature);
map2.put("nonceStr", nonceStr);
JSONObject jsonmap2=JSONObject.fromObject(map2);
out.write(jsonmap2.toString());
out.close();
}



public class TimerTaskGetToken extends TimerTask{
public static Map<String, String> getmap;
public static String getjsapi_ticket;
public static String getaccesstoken;
@Override
public void  run() {
// TODO Auto-generated method stub
getaccesstoken=JsapiTicketUtil.getAccessToken();
getjsapi_ticket = JsapiTicketUtil.getJSApiTicket(getaccesstoken);
System.out.println("定时任务开启 重新生成一系列凭证=================getaccesstoken======"+getaccesstoken+"getjsapi_ticket:"+getjsapi_ticket);
}
public static void getSignature(String url){
System.out.println(getaccesstoken+"||"+getjsapi_ticket);
getmap = Sign.sign(getjsapi_ticket,
url);
String timestamp = getmap.get("timestamp");
String nonceStr = getmap.get("nonceStr");
String signature = getmap.get("signature");
System.out.println("===timestamp:"+timestamp+"nonceStr:"+nonceStr+"signature"+signature);
}
}


public class JsapiTicketUtil {


/***
* AccessToken

* @return
*/
public static String getAccessToken() {
String appid = "xxxxx";
String appSecret = "xxxxx";
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
+ appid + "&secret=" + appSecret + "";
String backData = JsapiTicketUtil.sendGet(url, "utf-8", 10000);
String accessToken = (String) JSONObject.fromObject(backData).get(
"access_token");
Date data=new Date();
SimpleDateFormat simp=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("=生成token时间=="+simp.format(data)+"==============看这里==需要改变token值为:" + accessToken);
return accessToken;
}


/***
* Ticket

* @return
*/
public static String getJSApiTicket(String acess_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 = JsapiTicketUtil.sendGet(urlStr, "utf-8", 10000);
String ticket = (String) JSONObject.fromObject(backData).get("ticket");
return ticket;


}
public static String sendGet(String Strurl, String endCoding, int time) {
try {
URL url = new URL(Strurl);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.connect();
OutputStreamWriter out = new OutputStreamWriter(
connection.getOutputStream(), endCoding);
out.flush();
out.close();


BufferedReader reader = new BufferedReader(new InputStreamReader(
connection.getInputStream(),endCoding));
String lines;
StringBuffer sb = new StringBuffer();
while ((lines = reader.readLine()) != null) {
//lines = new String(lines.getBytes(), "utf-8");
sb.append(lines);
}
reader.close();
System.out.println("" + sb.toString());
return sb.toString();


} catch (IOException e) {
System.out.println("Error" + e.getMessage());
e.printStackTrace();
}
return "-1";
}
}


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==================="+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) {
// TODO Auto-generated method stub
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;


}


private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
// TODO Auto-generated method stub
}


private static String create_nonce_str() {
return UUID.randomUUID().toString();
// TODO Auto-generated method stub

}


其中用到的几个文件去我的资源下载吧  最好是自己看着教程做出来  拿到源码看的懂跟摸索出来是完全不一样的

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值