零碎知识点
WEB-INF/web.xml
繁琐的配置
1 | <web-app> |
特殊字符、转义字符
1 | <bean id="entity" class="entity.TestEntity"> |
XML 中预定义的实体 <(<) >(>) &(&) ‘(‘) “(“)
分页
方式一
thymeleaf局部刷新分页
mapper.java
1
2
3
4//按条件分页
List<XXX> selectXXXByTypeWithPage(约束条件,开始的索引,步长) //@param
//记录数
Int selectRowsByXXX(约束条件)mapper.xml
按条件分页,返回List,关键字limit
返回记录数,count(xxx)
- Service层
导入mapper
Web层
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//视图至少需要传入(model、当前页数、约束、布尔值的是否刷新)
(Model model,Integer page,boolean refresh,约束条件)
//进来先判断传入的页数是否为空,否则设为1
page = page == null?1:page;
//定义固定的每页数
int pageSize = 6;
//每页起始记录号 = (当前页数 - 1)* 每页数
int startIndex=(page-1)*pageSize;
// 查出总记录数
int rows = XXXService.queryRowsByXXX(约束);
// 查出页面内容
List<XXX> XXXs = XXXService.queryXXXByTypeWithPage(约束, startIndex, pageSize);
// 总页数 = 总记录数 / 每页数 (通常这么表达)
int pageCount=(int)Math.ceil((double)rows/pageSize);
// 保存返回,(页面内容、总页数、总记录数、当前页)
model.addAttribute('',xxx);
// 判断前端传来的布尔值是否刷新,否则正常加载
// refresh:前端传来的自定义值
// myIncome:自定义视图
if (refresh){
return "myIncome::refresh";
}else{
return "myIncome";
}前端
1
2
3
4// 翻页功能,定义函数 refresh 和 id的refresh
function refresh(page){
$("#refresh").load("myIncome",{page:page,refresh:true})
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<!-- html页面需要加入th -->
<html xmlns:th="http://www.thymeleaf.org">
<!-- 需要翻页的地方加入 fragment 属性 -->
<div th:fragment="refresh" id="refresh">
<!-- 需要刷新的内容。。。。 -->
<!-- th的特殊语法 -->
共[[${rows}]]条[[${pageCount}]]页 当前为第[[${page}]]页
<!-- 链接 -->
<a th:onclick="refresh(1)">首页</a>
<a th:onclick="refresh([[${page}-1]])">上一页</a>
<a th:onclick="refresh([[${page}+1]])">下一页 </a>
<a th:onclick="refresh([[${pageCount}]])">尾页</a>
</div>
方式二
bootstrap的插件
上传文件
1.文件解析器 commons-fileupload
2.<form method="post" encype="multipart/form-data">
3.参数MulitparFile
4.物理路劲
5.写文件
搜索自动补全
bootstrap的typeahead插件
afterSelect参数:作用回显
画图插件
https://echarts.apache.org/zh/index.html
excel文件上传与下载
此处以org.apache.poi
为例子,仅演示后端内容
日后学习视频:https://www.bilibili.com/video/BV1Ua4y1x7BK
- 基本概念:
工作簿—workbook
工作表—sheet
行—row
列—column
单元格—cell
区域/范围—rangel
导包
1 | <!--poi依赖(xls)HSSFWorkbook--> |
导出
1 | //导出excel文件 |
导入
1 | //导入excel文件 |
图形验证码
1 | //图形验证码 |
1 | // 发送验证码 |
1 | <img th:src="@{page/drawImg}" alt="" id="1" onclick="codePrint()"/> |
调用第三方解析
具体需要的参数看调用的接口
导包
1 | <dependency> |
发送请求—工具类
1 | package io.peng.money.utils; |
发送请求—执行方法
1 | //使用HttpClientUtil工具类,向远程接口api发送http请求 |
解析—xml
1 | <!-- 解析xml需要导包导包 --> |
1 | // 验证码=8179 |
解析—json
1 | // { |
注解
Spring + SpringMVC + SpringBoot
1 | 创建对象的: |
github搜索
1 | in:name 内容关键字 |
支付
1 | <!-- jsp需要导入的包 --> |
1 | // 表单自动提交 |
支付宝支付接口
支付宝开发平台
https://openhome.alipay.com/platform/home.htm
进入文档中心
https://openhome.alipay.com/docCenter/docCenter.htm?from=openhomemenu
搜索电脑网站产品支付
https://opendocs.alipay.com/open/270/105898
进入开发助手,下载开发助手工具生成密钥,apikey等
保存应用公钥,应用私钥,在沙箱中生成支付宝公钥,appid等
https://opendocs.alipay.com/open/291/introduce
快钱
pc端支付,开发者平台:https://open.99bill.com/menu!access.do?menuClass=1&mid=1&pid=1
Web认证
Cookie-Session
Cookie认证机制就是客户端发送请求时会在服务端创建一个Session对象,同时在客户端的浏览器端创建了一个Cookie对象;通过客户端带上来Cookie对象来与服务器端的session对象匹配来实现状态管理的。默认的,当我们关闭浏览器的时候,cookie会被删除。
Token-Auth
- 支持跨域访问: Cookie是不允许垮域访问的,Token传输的用户认证信息通过HTTP头传输,不存在跨域
- 无状态:Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储状态信息.
- 解耦特性: 不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可.
- 更适用于移动应用: 当你的客户端是一个原生平台(iOS, Android,Windows 8等)时,Cookie是不被支持的(你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。
- CSRF:因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范。
- 基于标准化:你的API可以采用标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby, Java,Python, PHP)
基于JWT的Token认证机制
JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。
组成
一个JWT实际上就是一个字符串,它由三部分组成,头部
、载荷
与签名
。
头部(Header)
JWT需要一个头部,头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。这也可以被表示成一个JSON对象。1
{ "type": "JWT", "alg": "HS256" }
载荷(Palyload)
1
{"sub":"accp","name":"gdglcadmin","roles":"admin" }
签名(Signature)
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。1
2<!-- 生成了如下的结果: -->
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM
实现
官方文档:https://github.com/jwtk/jjwt
Java中使用JJWT开源库;JJWT实现了JWT, JWS, JWE 和 JWA RFC规范;
导包
1
2
3
4
5<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>调用类库实现token
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public static String createJwtToken(){
long start=System.currentTimeMillis();
long exp=start+1000*60; //1分钟过期
JwtBuilder password = Jwts.builder().setId("999")//id
.setSubject("peng")//主体
.setIssuedAt(new Date())//开始时间
.setExpiration(new Date(exp))//结束时间
.claim("city", "guangzhou")//自定义cliam添加角色信息,可多个
.claim("gender", "male")
.signWith(SignatureAlgorithm.HS256, "io.peng");//签名密钥
System.out.println(password.compact());
// eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5OTkiLCJzdWIiOiJwZW5nIiwiaWF0IjoxNjM5MzA2OTE4LCJleHAiOjE2MzkzMDY5NzcsImNpdHkiOiJndWFuZ3pob3UiLCJnZW5kZXIiOiJtYWxlIn0.1aPl7iLj0Gu4F1Sw3xkSMTdmTCOKY9VuA_0fWRRZn2I
return null;
}解析token,获取用户信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public static String parseToken(){
String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5OTkiLCJzdWIiOiJwZW5nIiwiaWF0IjoxNjM5MzA2OTE4LCJleHAiOjE2MzkzMDY5NzcsImNpdHkiOiJndWFuZ3pob3UiLCJnZW5kZXIiOiJtYWxlIn0.1aPl7iLj0Gu4F1Sw3xkSMTdmTCOKY9VuA_0fWRRZn2I";
Claims body = Jwts.parser().setSigningKey("io.peng")//使用创建时的密钥
.parseClaimsJws(token).getBody();
System.out.println(body.getId());
System.out.println(body.getSubject());
System.out.println(body.getIssuedAt());
System.out.println(body);
//解析载荷
String city=(String)body.get("city");
System.out.println(city);
//999
//peng
//Sun Dec 12 19:03:20 CST 2021
//{jti=999, sub=peng, iat=1639307000, exp=1639307059, city=guangzhou, gender=male}
//guangzhou
return null;
}
request属性
getParameter()和getAttribute()
(1)request.getParameter()取得是通过容器的实现来取得通过类似post,get等方式传入的数据,request.setAttribute()和getAttribute()只是在web容器内部流转,仅仅是请求处理阶段。
(2)request.getParameter()方法传递的数据,会从Web客户端传到Web服务器端,代表HTTP请求数据。request.getParameter()方法返回String类型的数据。
request.setAttribute()和getAttribute()方法传递的数据只会存在于Web容器内部
还有一点就是,HttpServletRequest类有setAttribute()方法,而没有setParameter()方法。
例子1:假如两个WEB页面间为链接关系时,就是说要从1.jsp链接到2.jsp时,被链接的是2.jsp可以通过getParameter()方法来获得请求参数.getParameter()
1 | <!-- jsp1 --> |
例子2:但是如果两个WEB间为转发关系时,转发目的WEB可以用getAttribute()方法来和转发源WEB共享request范围内的数据,getAttribute()
1 | <% |
getHeader()
sql怎么根据字段找表
1 | SELECT |
mysql三元表达式
1 | select |
mybatis-plus
UpdateWrapper语句
1 | billsService.update(new UpdateWrapper<Bills>().lambda() |
shell + 自启动
每5分钟自适应监听443端口,不存在则执行java -jar命令
1 |
|
项目新版本发布脚本
1 | if [ `netstat -nap|grep 20195 | grep -v grep |wc -l` -gt 0 ];then |