总结
本文从基础到高级再到实战,由浅入深,把MySQL讲的清清楚楚,明明白白,这应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!
MySQL50道高频面试题整理:
先简单说一下什么 JS-SDK 的作用,企业微信 JS-SDK 是企业微信面向网页开发者提供的基于企业微信内的网页开发工具包,具体详情查看企业微信官方文档:JS-SDK
关于微信和企业微信调用屏蔽功能之间的区别:微信内置浏览器有自带的私有接口可直接调用 WeixinJSBridge(关于这个接口的介绍可查看博主的上一篇文章“微信开发:屏蔽分享功能”)我原本以为这个接口是企业微信和微信可以共用的后来才发现,这个接口仅限于“微信内置浏览器”
测试工具及文档
1.签名效验工具
配置 wx.config
第一步:引入 jweixin-1.2.0.js 文件,在那个页面用就引入到那个页面,(支持 https):点击下载,注意这个地方不支持微信的 jweixin-1.6.0.js 版本
第二步:配置 wx.config,这个地方有个需要注意的点,为了安全起见不建议使用 ajax 回调的方式获取签名参数,推荐进入页面时获取。
wx.config({
beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: ‘’, // 必填,企业微信的corpID
timestamp: , // 必填,生成签名的时间戳
nonceStr: ‘’, // 必填,生成签名的随机串
signature: ‘’,// 必填,签名,见 附录-JS-SDK使用权限签名算法
jsApiList: [] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
});
第三步:这个地方比较重要,所有调用的 wx.config 成功的接口一定要写到这个里边 wx.ready(),相当于是一个处理成功验证
wx.ready(function(){
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
第四步:这个就没啥好介绍的。。error 接口处理失败验证
wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
具体参数的介绍差不多也就这些。。下边就是我们的实践操作
这个地方我们先写后台获取签名等配置,这个地方的配置参数要和我们 wx.config 对应,一定不要错!!
1.获取 timestamp 参数(获取随机时间戳)
// 时间戳
String timestamp = Long.toString((new Date().getTime()) / 1000);
2.获取 nonceStr 参数(获取随机字符串)
// 随机串
String nonceStr = UUID.randomUUID().toString();
3.获取 ticket 参数,先获取 access_tocken,然后通过 tocker 参数获取 ticket,获取 tocken 可借鉴 企业微信开发:access_tocken
// 获取 access_token
AccessToken accessToken = AccessTokenAPI.getAccessToken(CORPID,SECRET);
// 根据 tocker 获取 jstl
String urlStr = “https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=”+accessToken.getToken();
JSONObject jsonObject = HttpRequestUtil.httpRequest(urlStr, EnumMethod.GET.name(), null);
String ticket = jsonObject.getString(“ticket”);
4.获取 signature 参数,signature 参数是通过“随机字符串+ticket+随机时间戳+当前页面路径”进行 sha1 加密得来的值,这个地方最需要注意的就是你的 url 参数,一定是获取当前页面的 url !!! 并且必须是可信域名,关于可信域名配置可借鉴:企业微信开发:自建应用配置可信域名
String signature = getsig(nonceStr,ticket,timestamp,url);
已使用的工具类
// 使用随机字符串+ticket+随机时间戳+当前页面路径
public static String getsig(String noncestr,String jsapi_ticket,String timestamp,String url){
String[] paramArr = new String[] { “jsapi_ticket=” + jsapi_ticket,
“timestamp=” + timestamp, “noncestr=” + noncestr, “url=” + url };
Arrays.sort(paramArr);
// 将排序后的结果拼接成一个字符串
String content = paramArr[0].concat(“&”+paramArr[1]).concat(“&”+paramArr[2])
.concat(“&”+paramArr[3]);
String gensignature = null;
try {
MessageDigest md = MessageDigest.getInstance(“SHA-1”);
// 对拼接后的字符串进行 sha1 加密
System.out.println(“拼接加密签名:”+content.toString());
byte[] digest = md.digest(content.toString().getBytes());
gensignature = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 将 sha1 加密后的字符串与 signature 进行对比
if (gensignature != null) {
return gensignature;// 返回signature
} else {
return “false”;
}
}
/**
-
将字节数组转换为十六进制字符串
-
@param byteArray
-
@return
*/
private static String byteToStr(byte[] byteArray) {
String strDigest = “”;
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
-
将字节转换为十六进制字符串
-
@param mByte
-
@return
*/
private static String byteToHexStr(byte mByte) {
char[] Digit = { ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘A’,
‘B’, ‘C’, ‘D’, ‘E’, ‘F’ };
char[] tempArr = new char[2];
tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
tempArr[1] = Digit[mByte & 0X0F];
String s = new String(tempArr);
return s;
}
到这后台的配置就算是完成了,我们看一下完整的后台代码
@Controller
@RequestMapping(“/index”)
public class TestController {
private String CORPID = “xxxxx”;
private String SECRET = “xxxxx”;
// 跳转到主页
@RequestMapping(value = “getIndex”,method = {RequestMethod.GET,RequestMethod.POST})
public String getIndex( Model model){
Map<String,Object> map = signature(request);
model.addAttribute(“appId”,map.get(“appId”));
model.addAttribute(“timestamp”,map.get(“timestamp”));
model.addAttribute(“nonceStr”,map.get(“nonceStr”));
model.addAttribute(“signature”,map.get(“signature”));
return “index”;
总结
虽然我个人也经常自嘲,十年之后要去成为外卖专员,但实际上依靠自身的努力,是能够减少三十五岁之后的焦虑的,毕竟好的架构师并不多。
架构师,是我们大部分技术人的职业目标,一名好的架构师来源于机遇(公司)、个人努力(吃得苦、肯钻研)、天分(真的热爱)的三者协作的结果,实践+机遇+努力才能助你成为优秀的架构师。
如果你也想成为一名好的架构师,那或许这份Java成长笔记你需要阅读阅读,希望能够对你的职业发展有所帮助。
(吃得苦、肯钻研)、天分(真的热爱)的三者协作的结果,实践+机遇+努力才能助你成为优秀的架构师。
如果你也想成为一名好的架构师,那或许这份Java成长笔记你需要阅读阅读,希望能够对你的职业发展有所帮助。
[外链图片转存中…(img-m4XvLPm3-1715102303566)]