0%

web如何取得用户信息

之前说过SecurityContextHolder默认使用的是ThreadLocal来进行存储的,而且每次都会清除,但是web每次请求都会验证用户权限,这是如何做到的呢?

这是通过SecurityContextPersistenceFilter来实现的,每次请求过来都会session中来获取SecurityContext,然后设置到SecurityContextHolder中,请求结束后再清除掉

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
37
38
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;

if (request.getAttribute(FILTER_APPLIED) != null) {
// ensure that filter is only applied once per request
chain.doFilter(request, response);
return;
}

request.setAttribute(FILTER_APPLIED, Boolean.TRUE);


HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,
response);
// 从session获取SecurityContext
SecurityContext contextBeforeChainExecution = repo.loadContext(holder);

try {
// 将SecurityContext存入SecurityContextHolder
SecurityContextHolder.setContext(contextBeforeChainExecution);

chain.doFilter(holder.getRequest(), holder.getResponse());

}
finally {
SecurityContext contextAfterChainExecution = SecurityContextHolder
.getContext();
// Crucial removal of SecurityContextHolder contents - do this before anything
// else.
SecurityContextHolder.clearContext();
// 存储SecurityContext
repo.saveContext(contextAfterChainExecution, holder.getRequest(),
holder.getResponse());
request.removeAttribute(FILTER_APPLIED);
}
}
阅读全文 »

存储表情符号

默认mysql的字符集是utf8,排序规则为 utf8_general_ci

1
INSERT INTO department (name) VALUES ('😄')

在存储表情的时候会报 1366 - Incorrect string value: '\xF0\x9F\x98\x84' for column 'name' at row 1, Time: 0.007000s

这时需要修改字符集

1
ALTER TABLE department MODIFY name varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '部门名称';

这时就可以了

utf8和utf8mb4的区别

MySQL中的utf8其实是utf8mb3,最多只用3个字节存储字符,存储不了表情。如果要支持表情,需要使用完整的utf8字符集utf8mb4,可用4个字节来存储

分页查询

之前在基本操作中说过分页查询使用from+size来进行查询,对于数据量不大的可以这么用,但是对于数据量大的深度分页这样会造成性能问题

from+size分页查询

size是返回的条数,from是跳过的条数

1
GET _search?size=20&from=100

或者使用dsl请求

1
2
3
4
5
6
GET _search

{
"size":20,
"from":100
}

这里是需要去每个分片去进行查询的,假如设置from为100,size为20,此时每个分片都需要先取出from+size=120条数据,然后将各分片数据聚合之后在进行一次全局排序,获取出120条数据,在从第100条开始,往后选20条数据。

如果翻页过深的话,需要从各分片筛选出大量的数据,那如何解决深度分页的问题呢?可以使用scroll游标

阅读全文 »

Pipeline和Value

Pipeline是管道,而Value就是管道中的阀门,Request和Response对象在管道中通过各个阀门的处理和控制。

每一个容器中都包含有管道

1
protected final Pipeline pipeline = new StandardPipeline(this);

且管道中都有一个必不可少的basic value,StandardContext对应的basic value为StandardContextValve,StandardEngine对应的basic value为StandardEngineValve,StandardHost对应的basic value为StandardHostValve,StandardWrapper对应的basic value为StandardWrapperValve

value存储

value是链式存储的,通过getNext、setNext来实现链式关系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void addValve(Valve valve) {

// Add this Valve to the set associated with this Pipeline
if (first == null) {
first = valve;
valve.setNext(basic);
} else {
Valve current = first;
while (current != null) {
if (current.getNext() == basic) {
current.setNext(valve);
valve.setNext(basic);
break;
}
current = current.getNext();
}
}

container.fireContainerEvent(Container.ADD_VALVE_EVENT, valve);
}

maven编码格式

在使用maven进行构建的时候,发现打印的日志中显示maven的编码格式使用的是GBK

1
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!

这可不行,我的项目使用的都是UTF-8,得改一下编码格式

如何修改呢?

在环境变量中新建变量MAVEN_OPTS值为 -Dfile.encoding=UTF-8

修改后再去使用mvn --version看一下,,发现变成UTF-8了

1
2
Default locale: zh_CN, platform encoding: UTF-8
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"