-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
soojinleed
committed
Aug 30, 2024
1 parent
c54a3b1
commit bb2814e
Showing
2 changed files
with
173 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// PUT _template/sip-incident-history-template | ||
{ | ||
"index_patterns": ["sip-incident-history_*"], | ||
"settings": {}, | ||
"mappings": { | ||
"properties": { | ||
"id": { | ||
"type": "keyword" | ||
}, | ||
"message": { | ||
"type": "text" | ||
}, | ||
"incident": { | ||
"properties": { | ||
"updatedBy": { | ||
"type": "keyword" | ||
}, | ||
"level": { | ||
"type": "keyword" | ||
}, | ||
"templateCode": { | ||
"type": "keyword" | ||
}, | ||
"title": { | ||
"type": "text" | ||
}, | ||
"receiverGroups": { | ||
"type": "nested", | ||
"properties": { | ||
"subId": { | ||
"type": "keyword" | ||
}, | ||
"createdAt": { | ||
"format": "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", | ||
"type": "date" | ||
}, | ||
"updatedBy": { | ||
"type": "keyword" | ||
}, | ||
"receivers": { | ||
"type": "nested", | ||
"properties": { | ||
"subId": { | ||
"type": "keyword" | ||
}, | ||
"groupType": { | ||
"type": "keyword" | ||
}, | ||
"receiverId": { | ||
"type": "keyword" | ||
}, | ||
"id": { | ||
"type": "long" | ||
}, | ||
"media": { | ||
"type": "keyword" | ||
} | ||
} | ||
}, | ||
"level": { | ||
"type": "keyword" | ||
}, | ||
"createdBy": { | ||
"type": "keyword" | ||
}, | ||
"service": { | ||
"type": "keyword" | ||
}, | ||
"id": { | ||
"type": "long" | ||
}, | ||
"updatedAt": { | ||
"format": "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", | ||
"type": "date" | ||
} | ||
} | ||
}, | ||
"createdAt": { | ||
"format": "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", | ||
"type": "date" | ||
}, | ||
"contents": { | ||
"type": "text" | ||
}, | ||
"createdBy": { | ||
"type": "keyword" | ||
}, | ||
"service": { | ||
"type": "keyword" | ||
}, | ||
"name": { | ||
"type": "keyword" | ||
}, | ||
"id": { | ||
"type": "long" | ||
}, | ||
"statusCode": { | ||
"type": "keyword" | ||
}, | ||
"updatedAt": { | ||
"format": "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", | ||
"type": "date" | ||
} | ||
} | ||
}, | ||
"typeCode": { | ||
"type": "integer" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# 240830 ThreadLocal로 유저 정보 처리하기 | ||
|
||
## Problem | ||
|
||
CRUD를 구현하다보면, call을 한 유저 정보를 db에 함께 저장해줘야한다. | ||
기존에 구현된 방식은 token이 들어오면 filter에서 토큰 정보를 parsing해서 api의 parameter에 조작해서 넣어주게 되어있었다. | ||
|
||
이 방법으로 Controller에서 필요한 param을 Service method들로 넘겨주어 사용할 수 있었지만, | ||
거의 모든 Service method에 parameter로 유저정보를 넘겨줘야해서 코드가 지저분해졌다. | ||
|
||
```java | ||
@GetMapping | ||
public PageImpl<ResponseDto> getPosts( | ||
@Valid @RequestParam(value = "code", required = true) String code, | ||
@Valid @RequestParam(value = "id", required = true) String id, | ||
@Valid @RequestParam(value = "name", required = true) String name, | ||
@Valid @RequestParam(value = "blahblah", required = false, defaultValue = "") String blahblah, | ||
PageRequest pageRequest, @RequestBody RequestDto requestDto) { | ||
return postService.getPosts(code, id, name, blahblah, pageRequest, requestDto); | ||
} | ||
``` | ||
|
||
그리고 이렇게 되면,, 머리로는 알지만 코드 자체로는 어떤 값을 받는지 명세가 불분명해진다 ㅜ | ||
|
||
## Solution | ||
|
||
Spring Security를 사용하면 ThreadLocal을 사용한 Context를 제공하기 때문에, ThreadLocal을 직접 사용해서 유저 정보를 저장해서 사용하기로 했다. | ||
|
||
``` | ||
ThreadLocal : 현재 Thread에서만 사용할 수 있는 Local variable 제공!! | ||
``` | ||
|
||
Filter에서 token으로 parsing한 유저 정보를 setUserInfo()로 ThreadLocal에 저장해두고, | ||
Service method에서는 getUserInfo()로 ThreadLocal에서 정보를 가져와서 사용하면 parameter로 넘겨주어야하는 번거로움을 해결할 수 있다:) | ||
|
||
```java | ||
public class UserContext { | ||
|
||
private static final ThreadLocal<UserInfo> userHolder = new ThreadLocal<>(); | ||
|
||
public static void setUserInfo(UserInfo userInfo) { | ||
userHolder.set(userInfo); | ||
} | ||
|
||
public static UserInfo getUserInfo() { | ||
return userHolder.get(); | ||
} | ||
|
||
public static void clear() { | ||
userHolder.remove(); | ||
} | ||
} | ||
``` | ||
|
||
마지막으로 기존에는 Detail한 유저정보가 필요하면 그때마다 조회해서 사용했는데, filter에서 넣을 때 한번에 조회해서 UserInfo에 정보를 채워두면 언제든지 가져다 쓸 수 있어서 좋았다. | ||
그리고 권한처리도 Custom Annotation으로 Controller에 붙여서 사용하고 있어서 Controller에서 불러오는 Param의 순서도 영향을 받았었는데(아래처럼 args로 받아서 사용) | ||
|
||
```java | ||
@Before("@annotation(serviceAuthority) && args(typeCode,..)") | ||
``` | ||
|
||
이젠 ThreadLocal로 가지고 오면 되기 때문에, 이 annotation을 사용하기 위해서 어떤 셋팅이 필요한지 모르는 다른 개발자가 순서를 바꾸거나 누락하는 등 실수하는 위험을 막을 수 있었다! |