简介
这个功能写成了一个springboot项目,部署在taptap的云引擎上。
taptap云引擎官方文档
使用了官方提供的命令行工具,创建项目和部署到云引擎。命令行文档
他生成的项目实际是springboot的改版,添加了一些他们独有的功能。比如云函数等。
实际开发与平时一致(他们提供的功能其实基本没用到,或许以后会用到。
另外,要吐槽的一个点就是:
项目生成默认配置使用的是Java11,但是部署到云引擎时,报错。
换成Java8后正常运行。
版本问题,影响不大。新版任你发,我用Java 8。
可复用模块
从请求中获取ip地址
Remote Address:
Remote Address代表HTTP请求的远程地址,即请求的源地址。http协议在三次握手时时用的就是这个Remote Address地址,发送响应报文时也是使用的这个Remote Address地址。
所以,Remote Address地址是不能伪造的,否则请求者会收不到响应报文。
但是,http请求经过代理服务器转发时,用户真实ip会丢失。所以有了
X-Forwarded-For
获取ip的方式。
X-Forwarded-For:
为了避免真实ip的丢失,代理服务器会增加叫X-Forwarded-For的头信息。将客户端ip记录到其中,以保证服务器可以获取到客户端真实ip。
X-Forwarded-For是一个拓展头。虽然HTTP/1.1(RFC 2616)协议并没有对它的定义,但它已经成为事实上的标准(都在用
X-Forwarded-For请求头格式:X-Forwarded-For: client, proxy1, proxy2
第一个便是请求的原始ip,后面则是代理服务器的ip。
由于请求头可以伪造,所以不要相信请求头中携带的ip信息。
直接对外提供服务的 Web 应用,在进行与安全有关的操作时,只能通过 Remote Address 获取 IP,不能相信任何请求头;
使用 Nginx 等 Web Server 进行反向代理的 Web 应用,在配置正确的前提下,要用 X-Forwarded-For 最后一节 或 X-Real-IP 来获取 IP(因为 Remote Address 得到的是 Nginx 所在服务器的内网 IP);同时还应该禁止 Web 应用直接对外提供服务;
在与安全无关的场景,例如通过 IP 显示所在地天气,可以从 X-Forwarded-For 靠前的位置获取 IP,但是需要校验 IP 格式合法性;
参考文章:
关于X-Forwarded-For的介绍
HTTP 请求头中的 X-Forwarded-For
代码:
1 | /** |
密码的md5加密
MD5,全称 消息摘要算法第五版(Message Digest Algorithm 5)
不多介绍,详见MD5百度百科
关于加密算法的改进:
- 加盐
即在原来的明文中加入一组随机串,再通过加密算法加密,将密文存入数据库。 - 加次数
即多加密几次,增加破解难度。不过会消耗更多计算资源。
jdk自带api:
1 | /** |
spring的DigestUtils工具类
1 | public static String md5(String password) { |
发送mail邮件
使用JavaMail发送邮件
依赖:
1 | <!--javamail的依赖--> |
代码:
1 | //邮件服务器地址(比如smtp.qq.com |
参考文章:
使用JavaMail创建邮件和发送邮件
使用springboot集成的mail模块
依赖:
1 | <dependency> |
配置:
1 | spring.mail.protocol= |
代码:
1 |
|
jdbc数据库连接池(鸽了)
因为建立数据库连接与关闭数据库连接是非常耗时的事情,如果每次查询都建立连接、关闭连接会产生很大的性能开销。
所以有了连接池的出现来解决这一问题。
即在程序启动时,初始化连接池(连接数据库,创建多个连接)。在需要使用时从连接池中获取连接,使用结束放回连接池。
以减少性能开销。
代码:
1 | 先鸽了 |
附DataSource的产出背景:
DataSource,一个被严重低估的接口
bug及解决方案
session变化
现象
ajax请求及其余请求在前几次请求时,session会发送变化。导致存在session中的数据获取不到。
原因
通过HttpServletRequest获取session对象时,使用 request.getSession()
方法。
getSession方法会检测当前是否有session存在,默认不存在会创建一个新的session,存在则返回。
ajax请求跨域请求默认不携带cookie信息。即获取不到session
解决方案(未解决)
调用getSession方法时传入参数false或true
例如:request.getSession(false);
为true时,先查看请求时是否有sessionID。如果没有,则创建一个新的session对象。如果有则根据sessionID查找对应的session对象,找到了就返回该session对象,没找到就创建新的session对象。
为false时,先查看请求中是否有sessionID,没有则返回null。有则根据sessionID查找对应的session对象,找到了就返回该session对象,没找到就创建新的session对象。
默认为true
建议:
往session中写入参数时使用 request.getSession();
从session中读取参数时使用 request.getSession(false);
附session其他操作:
设置值:session.setAttribute(String name,Object obj);
读取值:session.getAttribute(String name);
删除session:session.invalidate();
让ajax请求携带参数
添加属性:xhr.withCredentials=true
附js原生实现ajax请求:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
var Ajax = {
get: function (url, callback) {
// XMLHttpRequest对象用于在后台与服务器交换数据
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.onreadystatechange = function () {
// readyState == 4说明请求已完成
if (xhr.readyState == 4) {
if (xhr.status == 200 || xhr.status == 304) {
console.log(xhr.responseText);
callback(xhr.responseText);
}
}
}
xhr.send();
},
// data应为'a=a1&b=b1'这种字符串格式,在jq里如果data为对象会自动将对象转成这种字符串格式
post: function (url, data, callback) {
var xhr = new XMLHttpRequest();
xhr.open('POST', url, false);
// 跨域携带cookie
xhr.withCredentials=true
// 添加http头,发送信息至服务器时内容编码类型
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200 || xhr.status === 304) {
// console.log(xhr.responseText);
callback(xhr.responseText);
}
}
}
xhr.send(data);
}
}
1 | var Ajax = { |
说明:
这个bug其实并未解决,因为部署到tap云引擎时,是一个springboot项目。所有的请求应该都是同源的,不会出现跨域的情况。
而session变化原因,就是getSession会创建新的session对象。
将getSession传入false,同时改完ajax属性后,这个bug依旧会出现。
在部署到生产环境后,依旧有用户偶尔会出现了session为null的情况。
2022-08-12 暂未解决。
总结
第一次使用平台提供的自动化的部署和管理功能。
有部署状态(预备环境和生产环境)、请求统计、日志、及环境变量各种设置等。
taptap云服务还是很成熟的。相比自己在腾讯云服务器上使用要方便很多,不管是部署还是监控。
官方文档也相对很齐全,参看文档来使用是完全可以的。