Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
Baeseoha authored Dec 7, 2021
1 parent a8cdf21 commit 055479b
Showing 1 changed file with 386 additions and 7 deletions.
393 changes: 386 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,389 @@
# ICTeam - Shopping Mall
# :pushpin: I.C Shopping Mall
> ์‹ ์„ ์‹ํ’ˆ ํŒ๋งค ์‡ผํ•‘๋ชฐ
>http://15.164.244.62:8080/icmall/all/vegetable
## ๐Ÿ“Œ ์ฐธ์—ฌ
### ํŒ€์žฅ : ๊น€์ข…์›
### ํŒ€์› : ๊ฐ•์ง„, ์ •์žฌ์šฑ, ๋ฐฐ์„œํ•˜
</br>

### ๊ธฐ๊ฐ„: 2021.09.18 ~ 10.14
### ์ฃผ์š” ์‚ฌ์šฉ ๊ธฐ์ˆ :
Java11, JSON, springboot, MySQL5, Javascript, jsoup, MyBatis, JSTL, KakaoAPI, Security
## 1. ์ œ์ž‘ ๊ธฐ๊ฐ„ & ์ฐธ์—ฌ ์ธ์›
- 2021๋…„ 9์›” 18์ผ ~ 10์›” 14์ผ
- ํŒ€์žฅ: ๊น€์ข…์›
- ํŒ€์›: ๊ฐ•์ง„, ์ •์žฌ์šฑ, ๋ฐฐ์„œํ•˜

</br>

## 2. ์‚ฌ์šฉ ๊ธฐ์ˆ 
#### `Back-end`
- Java 11
- Spring Boot 4.12.1
- MyBatipse 1.2.4
- Jsoup
- MySQL 8.0.26
- Spring Security
#### `Front-end`
- HTML, CSS, Jquery
- Javascript

</br>

## 3. ERD ์„ค๊ณ„
![ERD](https://user-images.githubusercontent.com/65885458/144964958-a7af2267-ffef-4019-b87b-af70776ca96d.png)


## 4. ํ•ต์‹ฌ ๊ธฐ๋Šฅ
์ด ์„œ๋น„์Šค์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์€ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.
์‚ฌ์šฉ์ž๋Š” ๋‹จ์ง€ ์ปจํ…์ธ ์˜ ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ์„ ํƒํ•˜๊ณ , URL๋งŒ ์ž…๋ ฅํ•˜๋ฉด ๋์ž…๋‹ˆ๋‹ค.
์ด ๋‹จ์ˆœํ•œ ๊ธฐ๋Šฅ์˜ ํ๋ฆ„์„ ๋ณด๋ฉด, ์„œ๋น„์Šค๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<details>
<summary><b>ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์„ค๋ช… ํŽผ์น˜๊ธฐ</b></summary>
<div markdown="1">

### 4.1. ์ „์ฒด ํ๋ฆ„
![](https://zuminternet.github.io/images/portal/post/2019-04-22-ZUM-Pilot-integer/flow1.png)

### 4.2. ์‚ฌ์šฉ์ž ์š”์ฒญ
![](https://zuminternet.github.io/images/portal/post/2019-04-22-ZUM-Pilot-integer/flow_vue.png)

- **URL ์ •๊ทœ์‹ ์ฒดํฌ** :pushpin: [์ฝ”๋“œ ํ™•์ธ](https://github.com/Integerous/goQuality/blob/b587bbff4dce02e3bec4f4787151a9b6fa326319/frontend/src/components/PostInput.vue#L67)
- Vue.js๋กœ ๋ Œ๋”๋ง๋œ ํ™”๋ฉด๋‹จ์—์„œ, ์‚ฌ์šฉ์ž๊ฐ€ ๋“ฑ๋ก์„ ์‹œ๋„ํ•œ URL์˜ ๋ชจ์–‘์ƒˆ๋ฅผ ์ •๊ทœ์‹์œผ๋กœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
- URL์˜ ๋ชจ์–‘์ƒˆ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ, ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ๋„์›๋‹ˆ๋‹ค.

- **Axios ๋น„๋™๊ธฐ ์š”์ฒญ** :pushpin: [์ฝ”๋“œ ํ™•์ธ]()
- URL์˜ ๋ชจ์–‘์ƒˆ์ธ ๊ฒฝ์šฐ, ์ปจํ…์ธ ๋ฅผ ๋“ฑ๋กํ•˜๋Š” POST ์š”์ฒญ์„ ๋น„๋™๊ธฐ๋กœ ๋‚ ๋ฆฝ๋‹ˆ๋‹ค.

### 4.3. Controller

![](https://zuminternet.github.io/images/portal/post/2019-04-22-ZUM-Pilot-integer/flow_controller.png)

- **์š”์ฒญ ์ฒ˜๋ฆฌ** :pushpin: [์ฝ”๋“œ ํ™•์ธ](https://github.com/Integerous/goQuality/blob/b2c5e60761b6308f14eebe98ccdb1949de6c4b99/src/main/java/goQuality/integerous/controller/PostRestController.java#L55)
- Controller์—์„œ๋Š” ์š”์ฒญ์„ ํ™”๋ฉด๋‹จ์—์„œ ๋„˜์–ด์˜จ ์š”์ฒญ์„ ๋ฐ›๊ณ , Service ๊ณ„์ธต์— ๋กœ์ง ์ฒ˜๋ฆฌ๋ฅผ ์œ„์ž„ํ•ฉ๋‹ˆ๋‹ค.

- **๊ฒฐ๊ณผ ์‘๋‹ต** :pushpin: [์ฝ”๋“œ ํ™•์ธ]()
- Service ๊ณ„์ธต์—์„œ ๋„˜์–ด์˜จ ๋กœ์ง ์ฒ˜๋ฆฌ ๊ฒฐ๊ณผ(๋ฉ”์„ธ์ง€)๋ฅผ ํ™”๋ฉด๋‹จ์— ์‘๋‹ตํ•ด์ค๋‹ˆ๋‹ค.

### 4.4. Service

![](https://zuminternet.github.io/images/portal/post/2019-04-22-ZUM-Pilot-integer/flow_service1.png)

- **Http ํ”„๋กœํ† ์ฝœ ์ถ”๊ฐ€ ๋ฐ trim()** :pushpin: [์ฝ”๋“œ ํ™•์ธ]()
- ์‚ฌ์šฉ์ž๊ฐ€ URL ์ž…๋ ฅ ์‹œ Http ํ”„๋กœํ† ์ฝœ์„ ์ƒ๋žตํ•˜๊ฑฐ๋‚˜ ๊ณต๋ฐฑ์„ ๋„ฃ์€ ๊ฒฝ์šฐ,
์˜ฌ๋ฐ”๋ฅธ URL์ด ๋  ์ˆ˜ ์žˆ๋„๋ก Http ํ”„๋กœํ† ์ฝœ์„ ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ , ๊ณต๋ฐฑ์„ ์ œ๊ฑฐํ•ด์ค๋‹ˆ๋‹ค.

- **URL ์ ‘์† ํ™•์ธ** :pushpin: [์ฝ”๋“œ ํ™•์ธ]()
- ํ™”๋ฉด๋‹จ์—์„œ ๋ชจ์–‘์ƒˆ๋งŒ ํ™•์ธํ•œ URL์ด ์‹ค์ œ ๋ฆฌ์†Œ์Šค๋กœ ์—ฐ๊ฒฐ๋˜๋Š”์ง€ HttpUrlConnection์œผ๋กœ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค.
- ์ด ๋•Œ, ๋น ๋ฅธ ์‘๋‹ต์„ ์œ„ํ•ด Request Method๋ฅผ GET์ด ์•„๋‹Œ HEAD๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
- (HEAD ๋ฉ”์†Œ๋“œ๋Š” GET ๋ฉ”์†Œ๋“œ์˜ ์‘๋‹ต ๊ฒฐ๊ณผ์˜ Body๋Š” ๊ฐ€์ ธ์˜ค์ง€ ์•Š๊ณ , Header๋งŒ ํ™•์ธํ•˜๊ธฐ ๋•Œ๋ฌธ์— GET ๋ฉ”์†Œ๋“œ์— ๋น„ํ•ด ์‘๋‹ต์†๋„๊ฐ€ ๋น ๋ฆ…๋‹ˆ๋‹ค.)

![](https://zuminternet.github.io/images/portal/post/2019-04-22-ZUM-Pilot-integer/flow_service2.png)

- **Jsoup ์ด๋ฏธ์ง€, ์ œ๋ชฉ ํŒŒ์‹ฑ** :pushpin: [์ฝ”๋“œ ํ™•์ธ]()
- URL ์ ‘์† ํ™•์ธ๊ฒฐ๊ณผ ์œ ํšจํ•˜๋ฉด Jsoup์„ ์‚ฌ์šฉํ•ด์„œ ์ž…๋ ฅ๋œ URL์˜ ์ด๋ฏธ์ง€์™€ ์ œ๋ชฉ์„ ํŒŒ์‹ฑํ•ฉ๋‹ˆ๋‹ค.
- ์ด๋ฏธ์ง€๋Š” Open Graphic Tag๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ํŒŒ์‹ฑํ•˜๊ณ , ์—†์„ ๊ฒฝ์šฐ ์ฒซ ๋ฒˆ์งธ ์ด๋ฏธ์ง€์™€ ์ œ๋ชฉ์„ ํŒŒ์‹ฑํ•ฉ๋‹ˆ๋‹ค.
- ์ปจํ…์ธ ์— ์ด๋ฏธ์ง€๊ฐ€ ์—†์„ ๊ฒฝ์šฐ, ๋ฏธ๋ฆฌ ์„ค์ •ํ•ด๋‘” ๊ธฐ๋ณธ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ์ œ๋ชฉ์ด ์—†์„ ๊ฒฝ์šฐ ์ƒ๋žตํ•ฉ๋‹ˆ๋‹ค.


### 4.5. Repository

![](https://zuminternet.github.io/images/portal/post/2019-04-22-ZUM-Pilot-integer/flow_repo.png)

- **์ปจํ…์ธ  ์ €์žฅ** :pushpin: [์ฝ”๋“œ ํ™•์ธ]()
- URL ์œ ํšจ์„ฑ ์ฒดํฌ์™€ ์ด๋ฏธ์ง€, ์ œ๋ชฉ ํŒŒ์‹ฑ์ด ๋๋‚œ ์ปจํ…์ธ ๋Š” DB์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
- ์ €์žฅ๋œ ์ปจํ…์ธ ๋Š” ๋‹ค์‹œ Repository - Service - Controller๋ฅผ ๊ฑฐ์ณ ํ™”๋ฉด๋‹จ์— ์†ก์ถœ๋ฉ๋‹ˆ๋‹ค.

</div>
</details>

</br>

## 5. ํ•ต์‹ฌ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…
### 5.1. ์ปจํ…์ธ  ํ•„ํ„ฐ์™€ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ ๋ฌธ์ œ
- ์ €๋Š” ์ด ์„œ๋น„์Šค๊ฐ€ ํŽ˜์ด์Šค๋ถ์ด๋‚˜ ์ธ์Šคํƒ€๊ทธ๋žจ ์ฒ˜๋Ÿผ ๊ฐ€๋ณ๊ฒŒ, ์ž์ฃผ ์‚ฌ์šฉ๋˜๊ธธ ๋ฐ”๋ผ๋Š” ๋งˆ์Œ์œผ๋กœ ๊ฐœ๋ฐœํ–ˆ์Šต๋‹ˆ๋‹ค.
๋•Œ๋ฌธ์— ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ๋„ ๋ฌดํ•œ ์Šคํฌ๋กค์„ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

- ํ•˜์ง€๋งŒ [๋ฌดํ•œ์Šคํฌ๋กค, ํŽ˜์ด์ง• ํ˜น์€ โ€œ๋”๋ณด๊ธฐโ€ ๋ฒ„ํŠผ? ์–ด๋–ค ๊ฑธ ์จ์•ผํ• ๊นŒ](https://cyberx.tistory.com/82) ๋ผ๋Š” ๊ธ€์„ ์ฝ๊ณ  ๋ฌดํ•œ ์Šคํฌ๋กค์˜ ๋‹จ์ ๋“ค์„ ์•Œ๊ฒŒ ๋˜์—ˆ๊ณ ,
๋‹ค์–‘ํ•œ ๊ธฐ์ค€(์นดํ…Œ๊ณ ๋ฆฌ, ์‚ฌ์šฉ์ž, ๋“ฑ๋ก์ผ, ์ธ๊ธฐ๋„)์˜ ๊ฒŒ์‹œ๋ฌผ ํ•„ํ„ฐ ๊ธฐ๋Šฅ์„ ๋„ฃ์–ด์„œ ์ด๋ฅผ ๋ณด์™„ํ•˜๊ณ ์ž ํ–ˆ์Šต๋‹ˆ๋‹ค.

- ๊ทธ๋Ÿฐ๋ฐ ๊ฒŒ์‹œ๋ฌผ์ด ํ•„ํ„ฐ๋ง ๋œ ์ƒํƒœ์—์„œ ๋ฌดํ•œ ์Šคํฌ๋กค์ด ๋™์ž‘ํ•˜๋ฉด,
ํ•„ํ„ฐ๋ง ๋œ ๊ฒŒ์‹œ๋ฌผ๋“ค๋งŒ DB์— ์š”์ฒญํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜์˜ **๊ธฐ์กด ์ฝ”๋“œ** ์ฒ˜๋Ÿผ ๊ฐ ํ•„ํ„ฐ๋ณ„๋กœ ๋‹ค๋ฅธ Query๋ฅผ ๋‚ ๋ ค์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

<details>
<summary><b>๊ธฐ์กด ์ฝ”๋“œ</b></summary>
<div markdown="1">

~~~java
/**
* ๊ฒŒ์‹œ๋ฌผ Top10 (๊ธฐ์ค€: ๋Œ“๊ธ€ ์ˆ˜ + ์ข‹์•„์š” ์ˆ˜)
* @return ์ธ๊ธฐ์ˆœ ์ƒ์œ„ 10๊ฐœ ๊ฒŒ์‹œ๋ฌผ
*/
public Page<PostResponseDto> listTopTen() {

PageRequest pageRequest = PageRequest.of(0, 10, Sort.Direction.DESC, "rankPoint", "likeCnt");
return postRepository.findAll(pageRequest).map(PostResponseDto::new);
}

/**
* ๊ฒŒ์‹œ๋ฌผ ํ•„ํ„ฐ (Tag Name)
* @param tagName ๊ฒŒ์‹œ๋ฌผ ๋ฐ•์Šค์—์„œ ํด๋ฆญํ•œ ํƒœ๊ทธ ์ด๋ฆ„
* @param pageable ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ๊ฐ์ฒด
* @return ํ•ด๋‹น ํƒœ๊ทธ๊ฐ€ ํฌํ•จ๋œ ๊ฒŒ์‹œ๋ฌผ ๋ชฉ๋ก
*/
public Page<PostResponseDto> listFilteredByTagName(String tagName, Pageable pageable) {

return postRepository.findAllByTagName(tagName, pageable).map(PostResponseDto::new);
}

// ... ๊ฒŒ์‹œ๋ฌผ ํ•„ํ„ฐ (Member) ์ƒ๋žต

/**
* ๊ฒŒ์‹œ๋ฌผ ํ•„ํ„ฐ (Date)
* @param createdDate ๊ฒŒ์‹œ๋ฌผ ๋ฐ•์Šค์—์„œ ํด๋ฆญํ•œ ๋‚ ์งœ
* @return ํ•ด๋‹น ๋‚ ์งœ์— ๋“ฑ๋ก๋œ ๊ฒŒ์‹œ๋ฌผ ๋ชฉ๋ก
*/
public List<PostResponseDto> listFilteredByDate(String createdDate) {

// ๋“ฑ๋ก์ผ 00์‹œ๋ถ€ํ„ฐ 24์‹œ๊นŒ์ง€
LocalDateTime start = LocalDateTime.of(LocalDate.parse(createdDate), LocalTime.MIN);
LocalDateTime end = LocalDateTime.of(LocalDate.parse(createdDate), LocalTime.MAX);

return postRepository
.findAllByCreatedAtBetween(start, end)
.stream()
.map(PostResponseDto::new)
.collect(Collectors.toList());
}
~~~

</div>
</details>

- ์ด ๋•Œ ์นดํ…Œ๊ณ ๋ฆฌ(tag)๋กœ ๊ฒŒ์‹œ๋ฌผ์„ ํ•„ํ„ฐ๋ง ํ•˜๋Š” ๊ฒฝ์šฐ,
๊ฐ ๊ฒŒ์‹œ๋ฌผ์€ ์ตœ๋Œ€ 3๊ฐœ๊นŒ์ง€์˜ ์นดํ…Œ๊ณ ๋ฆฌ(tag)๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์–ด ํ•ด๋‹น ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ํฌํ•จํ•˜๋Š” ๋ชจ๋“  ๊ฒŒ์‹œ๋ฌผ์„ ์งˆ์˜ํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—
- ์•„๋ž˜ **๊ฐœ์„ ๋œ ์ฝ”๋“œ**์™€ ๊ฐ™์ด QueryDSL์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์†Œ ๋ณต์žกํ•œ Query๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ๋„ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

<details>
<summary><b>๊ฐœ์„ ๋œ ์ฝ”๋“œ</b></summary>
<div markdown="1">

~~~java
/**
* ๊ฒŒ์‹œ๋ฌผ ํ•„ํ„ฐ (Tag Name)
*/
@Override
public Page<Post> findAllByTagName(String tagName, Pageable pageable) {

QueryResults<Post> results = queryFactory
.selectFrom(post)
.innerJoin(postTag)
.on(post.idx.eq(postTag.post.idx))
.innerJoin(tag)
.on(tag.idx.eq(postTag.tag.idx))
.where(tag.name.eq(tagName))
.orderBy(post.idx.desc())
.limit(pageable.getPageSize())
.offset(pageable.getOffset())
.fetchResults();

return new PageImpl<>(results.getResults(), pageable, results.getTotal());
}
~~~

</div>
</details>

</br>

## 6. ๊ทธ ์™ธ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…
<details>
<summary>npm run dev ์‹คํ–‰ ์˜ค๋ฅ˜</summary>
<div markdown="1">

- Webpack-dev-server ๋ฒ„์ „์„ 3.0.0์œผ๋กœ ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ๋กœ ํ•ด๊ฒฐ
- `$ npm install โ€”save-dev webpack-dev-server@3.0.0`

</div>
</details>

<details>
<summary>vue-devtools ํฌ๋กฌ์ต์Šคํ…์…˜ ์ธ์‹ ์˜ค๋ฅ˜ ๋ฌธ์ œ</summary>
<div markdown="1">

- main.js ํŒŒ์ผ์— `Vue.config.devtools = true` ์ถ”๊ฐ€๋กœ ํ•ด๊ฒฐ
- [https://github.com/vuejs/vue-devtools/issues/190](https://github.com/vuejs/vue-devtools/issues/190)

</div>
</details>

<details>
<summary>ElementUI input ๋ฐ•์Šค์—์„œ `v-on:keyup.enter="๋ฉ”์†Œ๋“œ๋ช…"`์ด ์ •์ƒ ์ž‘๋™ ์•ˆํ•˜๋Š” ๋ฌธ์ œ</summary>
<div markdown="1">

- `v-on:keyup.enter.native=""` ์™€ ๊ฐ™์ด .native ์ถ”๊ฐ€๋กœ ํ•ด๊ฒฐ

</div>
</details>

<details>
<summary> Post ๋ชฉ๋ก ์ถœ๋ ฅ์‹œ์— Member ๊ฐ์ฒด ์ถœ๋ ฅ ์—๋Ÿฌ </summary>
<div markdown="1">

- ์—๋Ÿฌ ๋ฉ”์„ธ์ง€(500์—๋Ÿฌ)
- No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.SerializationFeature.FAIL_ON_EMPTY_BEANS)
- ํ•ด๊ฒฐ
- Post ์—”ํ‹ฐํ‹ฐ์— @ManyToOne ์—ฐ๊ด€๊ด€๊ณ„ ๋งคํ•‘์„ LAZY ์˜ต์…˜์—์„œ ๊ธฐ๋ณธ(EAGER)์˜ต์…˜์œผ๋กœ ์ˆ˜์ •

</div>
</details>

<details>
<summary> ํ”„๋กœ์ ํŠธ๋ฅผ git init์œผ๋กœ ์ƒ์„ฑ ํ›„ ๋ฐœ์ƒํ•˜๋Š” npm run dev/build ์˜ค๋ฅ˜ ๋ฌธ์ œ </summary>
<div markdown="1">

```jsx
$ npm run dev
npm ERR! path C:\Users\integer\IdeaProjects\pilot\package.json
npm ERR! code ENOENT
npm ERR! errno -4058
npm ERR! syscall open
npm ERR! enoent ENOENT: no such file or directory, open 'C:\Users\integer\IdeaProjects\pilot\package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\integer\AppData\Roaming\npm-cache\_logs\2019-02-25T01_23_19_131Z-debug.log
```

- ๋‹จ์ˆœํžˆ npm run dev/build ๋ช…๋ น์„ ์ž…๋ ฅํ•œ ๊ฒฝ๋กœ๊ฐ€ ๋ฌธ์ œ์˜€๋‹ค.

</div>
</details>

<details>
<summary> ํƒœ๊ทธ ์„ ํƒํ›„ ๋“ฑ๋กํ•˜๊ธฐ ๋ˆ„๋ฅผ ๋•Œ `object references an unsaved transient instance - save the transient instance before flushing` ์˜ค๋ฅ˜</summary>
<div markdown="1">

- Post ์—”ํ‹ฐํ‹ฐ์˜ @ManyToMany์— ์˜์†์„ฑ ์ „์ด(cascade=CascadeType.ALL) ์ถ”๊ฐ€
- JPA์—์„œ Entity๋ฅผ ์ €์žฅํ•  ๋•Œ ์—ฐ๊ด€๋œ ๋ชจ๋“  Entity๋Š” ์˜์†์ƒํƒœ์—ฌ์•ผ ํ•œ๋‹ค.
- CascadeType.PERSIST ์˜ต์…˜์œผ๋กœ ๋ถ€๋ชจ์™€ ์ž์‹ Enitity๋ฅผ ํ•œ ๋ฒˆ์— ์˜์†ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.
- ์ฐธ๊ณ 
- [https://stackoverflow.com/questions/2302802/object-references-an-unsaved-transient-instance-save-the-transient-instance-be/10680218](https://stackoverflow.com/questions/2302802/object-references-an-unsaved-transient-instance-save-the-transient-instance-be/10680218)

</div>
</details>

<details>
<summary> JSON: Infinite recursion (StackOverflowError)</summary>
<div markdown="1">

- @JsonIgnoreProperties ์‚ฌ์šฉ์œผ๋กœ ํ•ด๊ฒฐ
- ์ฐธ๊ณ 
- [http://springquay.blogspot.com/2016/01/new-approach-to-solve-json-recursive.html](http://springquay.blogspot.com/2016/01/new-approach-to-solve-json-recursive.html)
- [https://stackoverflow.com/questions/3325387/infinite-recursion-with-jackson-json-and-hibernate-jpa-issue](https://stackoverflow.com/questions/3325387/infinite-recursion-with-jackson-json-and-hibernate-jpa-issue)

</div>
</details>

<details>
<summary> H2 ์ ‘์†๋ฌธ์ œ</summary>
<div markdown="1">

- H2์˜ JDBC URL์ด jdbc:h2:~/test ์œผ๋กœ ๋˜์–ด์žˆ์œผ๋ฉด jdbc:h2:mem:testdb ์œผ๋กœ ๋ณ€๊ฒฝํ•ด์„œ ์ ‘์†ํ•ด์•ผ ํ•œ๋‹ค.

</div>
</details>

<details>
<summary> ์ปจํ…์ธ ์ˆ˜์ • ๋ชจ๋‹ฌ์ฐฝ์—์„œ ํƒœ๊ทธ ์…€๋ ‰ํŠธ๋ฐ•์Šค ๋“œ๋ž๋‹ค์šด์ด ๋’ค์ชฝ์— ๋ณด์ด๋Š” ๋ฌธ์ œ</summary>
<div markdown="1">

- ElementUI์˜ Global Config์— ์˜ต์…˜ ์ถ”๊ฐ€ํ•˜๋ฉด ํ•ด๊ฒฐ
- main.js ํŒŒ์ผ์— `Vue.us(ElementUI, { zIndex: 9999 });` ์˜ต์…˜ ์ถ”๊ฐ€(9999 ์ดํ•˜๋ฉด ์•ˆ๋Œ)
- ์ฐธ๊ณ 
- [https://element.eleme.io/#/en-US/component/quickstart#global-config](https://element.eleme.io/#/en-US/component/quickstart#global-config)

</div>
</details>

<details>
<summary> HTTP delete Request์‹œ ๊ฐœ๋ฐœ์ž๋„๊ตฌ์˜ XHR(XMLHttpRequest )์—์„œ delete์š”์ฒญ์ด 2๋ฒˆ์”ฉ ์ฐํžˆ๋Š” ์ด์œ </summary>
<div markdown="1">

- When you try to send a XMLHttpRequest to a different domain than the page is hosted, you are violating the same-origin policy. However, this situation became somewhat common, many technics are introduced. CORS is one of them.

In short, server that you are sending the DELETE request allows cross domain requests. In the process, there should be a **preflight** call and that is the **HTTP OPTION** call.

So, you are having two responses for the **OPTION** and **DELETE** call.

see [MDN page for CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS).

- ์ถœ์ฒ˜ : [https://stackoverflow.com/questions/35808655/why-do-i-get-back-2-responses-of-200-and-204-when-using-an-ajax-call-to-delete-o](https://stackoverflow.com/questions/35808655/why-do-i-get-back-2-responses-of-200-and-204-when-using-an-ajax-call-to-delete-o)

</div>
</details>

<details>
<summary> ์ด๋ฏธ์ง€ ํŒŒ์‹ฑ ์‹œ og:image ๊ฒฝ๋กœ๊ฐ€ ๋‹ฌ๋ผ์„œ ์ œ๋Œ€๋กœ ํŒŒ์‹ฑ์ด ์•ˆ๋˜๋Š” ๊ฒฝ์šฐ</summary>
<div markdown="1">

- UserAgent ์„ค์ •์œผ๋กœ ํ•ด๊ฒฐ
- [https://www.javacodeexamples.com/jsoup-set-user-agent-example/760](https://www.javacodeexamples.com/jsoup-set-user-agent-example/760)
- [http://www.useragentstring.com/](http://www.useragentstring.com/)

</div>
</details>

<details>
<summary> ๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ์œผ๋กœ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์ด ์Šคํ”„๋ง 2.0๋Œ€ ๋ฒ„์ „์—์„œ ๋‹ฌ๋ผ์ง„ ๊ฒƒ</summary>
<div markdown="1">

- 1.5๋Œ€ ๋ฒ„์ „์—์„œ๋Š” Controller์˜ ์ธ์ž๋กœ Principal์„ ๋„˜๊ธฐ๋ฉด principal.getName(0์—์„œ ๋ฐ”๋กœ ๊บผ๋‚ด์„œ ์“ธ ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ, 2.0๋Œ€ ๋ฒ„์ „์—์„œ๋Š” principal.getName()์˜ ๊ฒฝ์šฐ principal ๊ฐ์ฒด.toString()์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
- 1.5๋Œ€ ๋ฒ„์ „์—์„œ principal์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ
- ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด,

```jsx
@RequestMapping("/sso/user")
@SuppressWarnings("unchecked")
public Map<String, String> user(Principal principal) {
if (principal != null) {
OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) principal;
Authentication authentication = oAuth2Authentication.getUserAuthentication();
Map<String, String> details = new LinkedHashMap<>();
details = (Map<String, String>) authentication.getDetails();
logger.info("details = " + details); // id, email, name, link etc.
Map<String, String> map = new LinkedHashMap<>();
map.put("email", details.get("email"));
return map;
}
return null;
}
```

- 2.0๋Œ€ ๋ฒ„์ „์—์„œ๋Š”
- ์•„๋ž˜์™€ ๊ฐ™์ด principal ๊ฐ์ฒด์˜ ๋‚ด์šฉ์„ ๊บผ๋‚ด ์“ธ ์ˆ˜ ์žˆ๋‹ค.

```jsx
UsernamePasswordAuthenticationToken token =
(UsernamePasswordAuthenticationToken) SecurityContextHolder
.getContext().getAuthentication();
Map<String, Object> map = (Map<String, Object>) token.getPrincipal();

String email = String.valueOf(map.get("email"));
post.setMember(memberRepository.findByEmail(email));
```

</div>
</details>

<details>
<summary> ๋žญํ‚น ๋™์ ์ž ์ฒ˜๋ฆฌ ๋ฌธ์ œ</summary>
<div markdown="1">

- PageRequest์˜ Sort๋ถ€๋ถ„์—์„œ properties๋ฅผ "rankPoint"๋ฅผ ์ฃผ๊ณ  "likeCnt"๋ฅผ ์ค˜์„œ ๋Œ“๊ธ€์ˆ˜๋ณด๋‹ค ์ข‹์•„์š”์ˆ˜๊ฐ€ ์šฐ์„ ์ˆœ์œ„ ๊ฐ–๋„๋ก ์„ค์ •.
- ์ข‹์•„์š” ์ˆ˜๋„ ๋˜‘๊ฐ™๋‹ค๋ฉด..........

</div>
</details>

</br>

## 6. ํšŒ๊ณ  / ๋Š๋‚€์ 
>ํ”„๋กœ์ ํŠธ ๊ฐœ๋ฐœ ํšŒ๊ณ  ๊ธ€: https://zuminternet.github.io/ZUM-Pilot-integer/

0 comments on commit 055479b

Please sign in to comment.