๐ ์ค๋ ๋ฐฐ์ด ๋ด์ฉ!
- DTO ํด๋์ค
- ์ ํจ์ฑ ๊ฒ์ฌ
โ๏ธ DTO (Data Transfer Object)
- ๋ฐ์ดํฐ ์ ์ก์ ์ํ ์ฉ๋์ ๊ฐ์ฒด
( ์์ฒญ ๋ฐ์ดํฐ์ ์๋ต ๋ฐ์ดํฐ์์ ์ฌ์ฉ )
โ ์ฃผ๋ก ํด๋ผ์ด์ธํธ์์ ์๋ฒ ์ชฝ์ผ๋ก ์ ์กํ๋ ์์ฒญ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ ๋ฐ์ ๋, ์๋ฒ์์ ํด๋ผ์ด์ธํธ ์ชฝ์ผ๋ก ์ ์กํ๋ ์๋ต ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๊ธฐ ์ํ ์ฉ๋
โ๏ธ Request Body
โ ์์ฒญ ๋ฐ์ดํฐ ์ค body์ ํด๋น๋๋ ๋ฐ์ดํฐ
( ์ฌ๊ธฐ์ ๋งํ๋ ์์ฒญ ๋ฐ์ดํฐ๋ค์ ๋ชจ๋ Request Body๋ฅผ ๋งํ๋ ๊ฒ )
โ DTO๊ฐ ํ์ํ ์ด์
- ํด๋ผ์ด์ธํธ์ Request Body๋ฅผ ํ๋์ ๊ฐ์ฒด๋ก ๋ชจ๋ ์ ๋ฌ ๋ฐ์ ์ ์๊ธฐ๋๋ฌธ์ ์ฝ๋ ์์ฒด๊ฐ ๊ฐ๊ฒฐ
- Request Body์ ๋ฐ์ดํฐ ์ ํจ์ฑ(Validation) ๊ฒ์ฆ์ด ๋จ์ํด์ง
๐ก ์๋ ์ค์ต ๋ด์ฉ์์ Map์ผ๋ก ์์ฒญ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์๋๋ฐ
์ด ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฅผ ํ๋ํ๋ ๋ฐ์ ๋ ๋ง๋ค @RequestParam ์ ๋ํ ์ด์ ์ ์จ์ค์ผํจ
โ ๋ฐ์ดํฐ๊ฐ ๋ง์์ง ์๋ก ๋ถํธ
โ โ
๋ฐ๋ผ์ DTO ํด๋์ค๋ฅผ ์ด์ฉํ์ฌ DTO ํด๋์ค์ ์์ฒญ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ณ ,
๊ทธ DTO ํด๋์ค๋ฅผ ResponseEntity ๊ฐ์ฒด์ ์์ฑ์ ํ๋ผ๋ฏธํฐ๋ก ๋๊ฒจ์ฃผ๋ฉด ์ฝ๋๊ฐ ํจ์ฌ ๊ฐ๊ฒฐํด์ง
โ๏ธ ResponseEntity
- HttpEntity์ ํ์ฅ ํด๋์ค๋ก์จ HttpStatus ์ํ ์ฝ๋๋ฅผ ์ถ๊ฐํ ์ ์ฒด HTTP ์๋ต(์ํ ์ฝ๋, ํค๋ ๋ฐ ๋ณธ๋ฌธ)์ ํํํ๋ ํด๋์ค
[์ฐธ๊ณ ] https://itvillage.tistory.com/44
โ๏ธ @RequestMapping
[์ฐธ๊ณ ] https://dzone.com/articles/using-the-spring-requestmapping-annotation
โ DTO์ ์ฌ์ฉ ๋ชฉ์
- HTTP ์์ฒญ์ ์๋ฅผ ์ค์ด๊ธฐ ์ํจ (๊ฐ์ฅ ์ค์ํ ๋ชฉ์ )
โ ๊ทธ ์์ฒญ์ ์ฌ์ฉ๋๋ ๋น์ฉ์ ์ค์ด๊ธฐ ์ํด
โ DTO์ ๋จ์
- DTO ํด๋์ค๋ฅผ ๋ง๋ค ๋ ํด๋น Contoller ํด๋์ค ์์ DTO ํด๋์ค ์์ฑ์ด ๊ฐ๋ฅํ ํธ๋ค๋ฌ ๋ฉ์๋์ ๊ฐ์๋งํผ ์์ฑํ๊ฒ ๋๋๋ฐ,
- Controller ํด๋์ค๊ฐ ๋์ด๋จ์ ๋ฐ๋ผ ์ฐ๋ฆฌ๊ฐ ์์ฑํ DTO ํด๋์ค๋ ๋๋ฐฐ๋ก ๋์ด๋๊ฒ ๋จ !!
โ ์ด ๋ถ๋ถ์ ๊ณตํต๋ ๋ฉค๋ฒ ๋ณ์์ ์ถ์ถ ๋ฐ ๋ด๋ถ ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋์ ๋ ๊ฐ์ ์ด ๊ฐ๋ฅ !
โ๏ธ DTO ํด๋์ค ์ ์ฉ์ ์ํ ์ฝ๋ ๋ฆฌํฉํ ๋ง ๊ณผ์
1. ๊ฐ ํธ๋ค๋ฌ ๋ฉ์๋์ ์์ฒญ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ DTO ํด๋์ค ์์ฑ
( ์ฌ๊ธฐ์ DTO ํด๋์ค ์์ฑ์ด ๊ฐ๋ฅํ ํธ๋ค๋ฌ ๋ฉ์๋๋ ๋ฆฌ์์ค์ ์ถ๊ฐ๊ฐ ๋ฐ์ํ ๋๋ง ๊ฐ๋ฅ
Ex. POST , PATCH, PUT ๋ฑ
2. ์์ฒญ ๋ฐ์ดํฐ ํญ๋ชฉ๋ค์ DTO ํด๋์ค์ ๋ฉค๋ฒ ๋ณ์๋ก ์ถ๊ฐ ํ๊ณ , ๊ฐ ๋ฉค๋ฒ ๋ณ์์ ํด๋นํ๋ getter ์ถ๊ฐ
But, setter ๋ฉ์๋๋ ํ์์ ์ํ ์ ํ์ฌํญ !
setter ๋ฉ์๋ ์์ด getter ๋ฉ์๋๋ง ์์ด๋ JSON โ ๊ฐ์ฒด ์ ๋ณํ์ด ๊ฐ๋ฅ !
[์ฐธ๊ณ ] https://stackoverflow.com/questions/70955984/why-requestbody-works-without-setters
3. ํธ๋ค๋ฌ ๋ฉ์๋ ์์ @RequestParam ์ชฝ ์ฝ๋๋ฅผ DTO ๊ฐ์ฒด๋ก ์์
4. Map ๊ฐ์ฒด๋ก ์์ฑ๋์ด ์๋ Response Body ๋ฅผ DTO ํด๋์ค ๊ฐ์ฒด๋ก ๋ณ๊ฒฝ
๐ก ํฌ์คํธ๋งจ์ผ๋ก ์ ์ ๋ฌ๋ฐ๊ณ ์๋์ง ํ์ธํ ๋,
์ ๋ฌ ๋ฐ๋ HTTP Request Body๊ฐ JSON ํ์์ด์ด์ผ ํ๊ธฐ ๋๋ฌธ์
ํด๋ผ์ด์ธํธ ์ชฝ์์ ์ ๋ฌํ๋ Request Body ์ญ์ JSON ํ์์ผ๋ก ์ ๋ ฅ ํด์ผ ํจ
โ๏ธ @RequestBody
์ ๋ํ
์ด์
- JSON ํ์์ Request Body โ MemberPostDto ํด๋์ค์ ๊ฐ์ฒด๋ก ๋ณํ
( ์ฌ๊ธฐ์ Request Body - ํด๋ผ์ด์ธํธ์๊ฒ ๋ฐ์ ์์ฒญ ๋ฐ์ดํฐ ) - JSON ํ์์ด ์๋ ๋ค๋ฅธ ํ์์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ๊ฒฝ์ฐ, ์๋ฌ ๋ฉ์ธ์ง๋ฅผ ํฌํจํ ์๋ต์ ์ ๋ฌ
- @RequestBody๋ก ์์ฒญ์ ๋ฐ๋๋ค๋ ๊ฒ
โ JSON ํ์์ผ๋ก ๋ฐ์์ ๋ฐํ
- @RequestParam์ผ๋ก ์์ฒญ์ ๋ฐ๋๋ค๋ ๊ฒ
โ JSON ํ์์ด ์๋ key value ํ์์ ๋ฐ์์ ๋ฐํ
โ๏ธ @ResponseBody
์ ๋ํ
์ด์
- DTO ํด๋์ค์ ๊ฐ์ฒด โ Response Body๋ก ๋ณํ
( ์ฌ๊ธฐ์ Response Body - ํด๋ผ์ด์ธํธ์๊ฒ ๋ณด๋ผ ์๋ต ๋ฐ์ดํฐ )
๐ก Spring MVC์์ ํธ๋ค๋ฌ ๋ฉ์๋์ @ResponseBody ์ ๋ํ ์ด์ ์ด ๋ถ๊ฑฐ๋, ํธ๋ค๋ฌ ๋ฉ์๋์ ๋ฆฌํด๊ฐ์ด ResponseEntity์ผ ๊ฒฝ์ฐ
๋ด๋ถ์ ์ผ๋ก HttpMessageConverter๊ฐ ๋์ํ๊ฒ ๋์ด ์๋ต ๊ฐ์ฒด๋ฅผ JSON ํ์์ผ๋ก ๋ฐ๊ฟ์ค
โ
( ๋ฆฌํด๊ฐ์ด ResponseEntity์ผ ๊ฒฝ์ฐ @ResponseBody ์ ๋ํ ์ด์ ๋ถ์ด๋ฉด ์๋์ผ๋ก ๋ฐ๊ฟ์ค )
โ๏ธ JSON ์ง๋ ฌํ(Serialization)
Java ๊ฐ์ฒด → JSON ํ์
โ๏ธ JSON ์ญ์ง๋ ฌํ(Deserialization)
JSON ํ์ → Java ๊ฐ์ฒด}
โ
( โ ์ฌ๊ธฐ์ Java ๊ฐ์ฒด๋ DTO ๊ฐ์ ํด๋์ค๋ฅผ ๋งํ๋ ๊ฒ ! )
โ๏ธ ์ ํจ์ฑ(Validation) ๊ฒ์ฆ
- ์ผ๋ฐ์ ์ผ๋ก ํด๋ผ์ด์ธํธ์๊ฒ ์์ฒญ ๋ฐ์ดํฐ๊ฐ ์ ๋ฌ๋ ๋, ์ฐ๋ฆฌํํ
๋์ด์ค๋ ๊ทธ ๋ฐ์ดํฐ๋ 1์ฐจ์ ์ผ๋ก ์ ํจ์ฑ ๊ฒ์ฆ์ด ์งํ๋ ๋ฐ์ดํฐ์
But, ์ด ๊ฐ์ ์กฐ์ํ ์ ์์ด ๋ฐ๋์ ์ ํจํ ๊ฐ์ด๋ผ ๋ณผ ์ ์๊ธฐ ๋๋ฌธ์
์๋ฒ ์ชฝ์์ ๋ฐ๋์ ํ๋ฒ ๋ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ํด์ผํจ - ์๋ฒ ์ชฝ์์ ์ ํจํ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ ๋ฐ๊ธฐ ์ํด ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ฆํ๋ ๊ฒ
๐ก ํธ๋ค๋ฌ ๋ฉ์๋ ๋ด์ ์ ํจ์ฑ ๊ฒ์ฆ์ ํ๊ฒ ๋๋ฉด, ์์ฒญ ๋ฐ์ดํฐ์ ๊ฐ์๋งํผ ๋ฉ์๋ ๋ด์ ๊ฒ์ฆ ๋ก์ง์ด ๋์ณ๋๊ฒ ๋จ
โ ์ฝ๋ ๋ณต์ก๋ ๋์์ง
โ
ํธ๋ค๋ฌ ๋ฉ์๋๋ ์์ฒญ์ ์ ๋ฌ๋ฐ๋ ๊ฒ์ด ์ฃผ ๋ชฉ์ ์ด๋ผ ์ต๋ํ ๊ฐ๊ฒฐํ๊ฒ ์์ฑํด์ผํ๊ธฐ์
โ
DTO ํด๋์ค์ ์ ํจ์ฑ ๊ฒ์ฆ ์ ๋ํ ์ด์ ์ ์ด์ฉํ์ฌ
์ ํจ์ฑ ๊ฒ์ฆ ๋ก์ง์ DTO ํด๋์ค๋ก ๋นผ๋ด์ด ํธ๋ค๋ฌ ๋ฉ์๋์ ๊ฐ๊ฒฐํจ ์ ์ง ๊ฐ๋ฅ
โ
๐ก DTO ํด๋์ค์์ ์ ํจ์ฑ ๊ฒ์ฆ ์,
ํด๋ผ์ด์ธํธ์ ์์ฒญ ๋ฐ์ดํฐ์ ์ ํจํ์ง ์์ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ฉด ์ ํจ์ฑ ๊ฒ์ฆ์ ์คํจ
โ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ด ๊ฑฐ๋ถ๋จ
โ ์ ํจ์ฑ(validation) ๊ฒ์ฆ ์ ๋ํ ์ด์ ์ ์ฌ์ฉ
- Spring Boot 2.3๋ฒ์ ๋ถํฐ javax.validation์ด spring-boot-starter-web์ ํฌํจ๋์ด ์์ง ์๊ธฐ ๋๋ฌธ์,
build.gradle
์dependencies ํญ๋ชฉ
์ ๋ฐ๋ก ์๋์ ์์กด์ฑ์ ์ถ๊ฐํด์ค์ผ ์๋์ ์ ๋ํ ์ด์ ๋ค์ ์ฌ์ฉ ๊ฐ๋ฅํจ โฌ๏ธimplementation 'org.springframework.boot:spring-boot-starter-validation'
โ๏ธ java.validation ์ ๋ํ ์ด์
- @NotNull - Null ๋ถ๊ฐ
@Null
- Null๋ง ์ ๋ ฅ ๊ฐ๋ฅ@NotEmpty
- Null, ๋น ๋ฌธ์์ด ๋ถ๊ฐ@NotBlank
- Null, ๋น ๋ฌธ์์ด, ์คํ์ด์ค๋ง ์๋ ๋ฌธ์์ด ๋ถ๊ฐ ( String ํ์ ์๋ง ์ฌ์ฉ )@Size(min =,max =)
- ๋ฌธ์์ด, ๋ฐฐ์ด๋ฑ์ ํฌ๊ธฐ ์ง์ @Pattern(regex =)
- ์ ๊ท์์ ๋ง์กฑํ๋๊ฐ@Max(์ซ์)
- ๋ฐ์ ์ ์๋ ์ต๋๊ฐ ์ง์ @Min(์ซ์)
- ๋ฐ์ ์ ์๋ ์ต์๊ฐ ์ง์ @Future
- ํ์ฌ ๋ณด๋ค ๋ฏธ๋์ ์๊ฐ(๋ ์ง, ์๊ฐ)๋ง ๋ฐ๋๋ก ์ง์ @Past
- ํ์ฌ ๋ณด๋ค ๊ณผ๊ฑฐ์ ์๊ฐ(๋ ์ง, ์๊ฐ)๋ง ๋ฐ๋๋ก ์ง์ @Positive
- ์์๋ง ๊ฐ๋ฅ@PositiveOrZero
- ์์์ 0๋ง ๊ฐ๋ฅ@Negative
- ์์๋ง ๊ฐ๋ฅ@NegativeOrZero
- ์์์ 0๋ง ๊ฐ๋ฅ@Email
- ์ด๋ฉ์ผ ํ์๋ง ๊ฐ๋ฅ
[์ฐธ๊ณ ] https://en.wikipedia.org/wiki/Email_address@Digits(integer =, fraction =)
- ๋์ ์๊ฐ ์ง์ ๋ ์ ์์ ์์ ์๋ฆฌ ์ ๋ณด๋ค ์์๊ฐ?@DecimalMax(value =)
- ์ง์ ๋ ๊ฐ(์ค์) ์ดํ์ธ๊ฐ?@DecimalMin(value =)
- ์ง์ ๋ ๊ฐ(์ค์) ์ด์์ธ๊ฐ?@AssertFalse
- ๊ฐ์ false๋ง ๋ฐ๋๋ก ์ง์ @AssertTrue
- ๊ฐ์ true๋ง ๋ฐ๋๋ก ์ง์
โ โ
( ์์ ์ ๋ํ ์ด์ ๋ค์ ๋ชจ๋ Jakarta Bean Validation์ด๋ผ๋ ์ ํจ์ฑ ๊ฒ์ฆ์ ์ํ ํ์ค ์คํ์์ ์ง์ํ๋ ๋ด์ฅ ์ ๋ํ ์ด์ ๋ค์ )
โ๏ธ ๊ฐ ์ ๋ํ ์ด์ ์๋ ๊ณตํต์ ์ผ๋ก message ์์ฑ ์ ์ฉ ๊ฐ๋ฅ
( message - ์ ํจ์ฑ ๊ฒ์ฌ์ ์คํจํ ๊ฒฝ์ฐ, ๋ ๋๋ง ๋๋ ๋ฉ์์ง )
Ex. @NotNull (message = "ํด๋น ๊ฐ์ด Null์ ๋๋ค.")
โ๏ธ ์ ํจ์ฑ ๊ฒ์ฆ ์ ๋ํ ์ด์ ์ด ์ถ๊ฐ๋ DTO ํด๋์ค์์ ์ ํจ์ฑ ๊ฒ์ฆ ๋ก์ง์ด ์คํ๋๊ฒ ํ๊ธฐ ์ํด์๋
ํด๋น Contoller ํด๋์ค์ ํธ๋ค๋ฌ ๋ฉ์๋ ํ๋ผ๋ฏธํฐ์ @Valid ์ ๋ํ ์ด์ ์ ์ถ๊ฐํด์ผํจ
โ๏ธ ํธ๋ค๋ฌ ๋ฉ์๋์ URI path์์ ์ฌ์ฉ๋๋ Id์ ์ ํจ์ฑ ์ ํ์ ๋๋ @PathVariable ์ ๋ํ ์ด์ ์ด ๋ถ์ ๊ฒฝ์ฐ,
ํด๋์ค ๋ ๋ฒจ์ @Validated ์ ๋ํ ์ด์ ์ ๋ฐ๋์ ๋ถ์ฌ์ฃผ์ด์ผํจ
[์ฐธ๊ณ ] https://immose93.tistory.com/139
[์ฐธ๊ณ ] https://hyeran-story.tistory.com/81
โ๏ธ Jakarta Bean Validation
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ API๊ฐ ์๋ ์คํ(์ฌ์, Specification) ์์ฒด
- ์ด ์คํ์ ๊ตฌํํ ๊ตฌํ์ฒด๊ฐ Hibernate Validator
โ Java Bean ์คํ์ ์ค์ํ๋ Java ํด๋์ค๋ผ๋ฉด Jakarta Bean Validation์ ์ ๋ํ ์ด์ ์ ์ฌ์ฉํด์ ์ ํจ์ฑ ๊ฒ์ฆ์ ํ ์ ์๋ค !
โ ์ ๊ทํํ์ (Reqular Experssion)
[์ ๊ทํํ์ ์ฐธ๊ณ ๋งํฌ]
https://www.w3schools.com/java/java_regex.asp
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Regular_Expressions
https://learn.microsoft.com/ko-kr/dotnet/standard/base-types/best-practices
https://moonong.tistory.com/31
https://jamesdreaming.tistory.com/201
https://highcode.tistory.com/6
Ex. “^\\S+(\\s?\\S+)*$” โ ๋ฌธ์์ด๋ค ์ฌ์ด์ ๊ณต๋ฐฑ 0~1๊ฐ๋ง ํ์ฉ
โ๏ธ Custom Validator
- ๋ด ๋ชฉ์ ์ ๋ง๋ ์ ๋ํ
์ด์
์ด Jakarta Bean Validation์ ๋ด์ฅ๋(Built-in) ์ ๋ํ
์ด์
์ค์ ์์ ์ ์์
โ ์ง์ ๋ง๋ค์ด์ ์ ํจ์ฑ ๊ฒ์ฆ์ ์ ์ฉ ๊ฐ๋ฅ !
๐ก ์ ๊ท ํํ์(Regular Expression)์ ์ฑ๋ฅ์ ์ธ ๋ฉด์์ ๋๋ก๋ ๋น์ผ ๋น์ฉ์ ์น๋ค์ผ ๋ ๊ฐ๋ฅ์ฑ์ด ์์
โ ๋ชจ๋ ๋ก์ง์ ์ ๊ทํํ์ ์์ฃผ๋ก ์์ฑํ๋ ๊ฒ์ ์ข์ ๊ฐ๋ฐ ๋ฐฉ์์ด ์๋๊ธฐ์
์ํฉ์ ๋ฐ๋ผ Custom Validator ์ฌ์ฉํ๊ธฐ
โ๏ธ Custom Validator๋ฅผ ๊ตฌํํ๊ธฐ ์ํ ์ ์ฐจ
- Custom Annotation์ ์ ์
- ์ ์ํ Custom Annotation์ ๋ฐ์ธ๋ฉ ๋๋ Custom Validator ๊ตฌํ
- ์ ํจ์ฑ ๊ฒ์ฆ์ด ํ์ํ DTO ํด๋์ค์ ๋ฉค๋ฒ ๋ณ์์ Custom Annotation ์ถ๊ฐ
๐ DTO ์ถ๊ฐ ์ค์ต
- projects ํด๋ Section2-Week1 ์ฐธ๊ณ !
๐ ๋๋์
์ด์ ์ค๋ ์ง์ ํด๋ณด๊ณ ํฌ์คํธ๋งจ์ผ๋ก ํ์ธํด๋ณด๋๊ฒ ์ฌ๋ฐ์๋ค !!ใ ใ
( ๋ณธ ๊ฒ์๋ฌผ์ 2022/10/23์ ์์ฑํ ๊ธ์ ์ฎ๊ธด ๊ธ์ ๋๋ค. ์๋ฌธ์ ์๊ธฐ์ ์์! )
'โข CodeStates BootCamp > Section 3' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๐ [Section3] 6. [ Spring MVC ] Spring Data JDBC 2 (1) | 2023.04.10 |
---|---|
๐ [Section3] 5. [ Spring MVC ] Spring Data JDBC 1 (0) | 2023.04.10 |
๐ [Section3] 4. [ Spring MVC ] ์์ธ ์ฒ๋ฆฌ (0) | 2023.04.10 |
๐ [Section3] 3. [ Spring MVC ] ์๋น์ค ๊ณ์ธต (0) | 2023.04.10 |
๐ [Section3] 1. [ Spring MVC ] API ๊ณ์ธต 1 (0) | 2023.04.09 |