β μ£Όλ‘ ν΄λΌμ΄μΈνΈμμ μλ² μͺ½μΌλ‘ μ μ‘νλ μμ² λ°μ΄ν°λ₯Ό μ λ¬ λ°μ λ, μλ²μμ ν΄λΌμ΄μΈνΈ μͺ½μΌλ‘ μ μ‘νλ μλ΅ λ°μ΄ν°λ₯Ό μ μ‘νκΈ° μν μ©λ
βοΈ Request Body
β μμ² λ°μ΄ν° μ€ bodyμ ν΄λΉλλ λ°μ΄ν°
( μ¬κΈ°μ λ§νλ μμ² λ°μ΄ν°λ€μ λͺ¨λ Request Bodyλ₯Ό λ§νλ κ² )
ν΄λΌμ΄μΈνΈμ 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 ν΄λμ€μ λ©€λ² λ³μλ‘ μΆκ° νκ³ , κ° λ©€λ² λ³μμ ν΄λΉνλ getter μΆκ°
But, setter λ©μλλ νμμ μν μ νμ¬ν !
setter λ©μλ μμ΄ getter λ©μλλ§ μμ΄λJSON β κ°μ²΄
μ λ³νμ΄ κ°λ₯ !
[μ°Έκ³ ] https://stackoverflow.com/questions/70955984/why-requestbody-works-without-setters
νΈλ€λ¬ λ©μλ μμ @RequestParam μͺ½ μ½λλ₯Ό DTO κ°μ²΄λ‘ μμ
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
μ λν
μ΄μ
π‘ Spring MVCμμ νΈλ€λ¬ λ©μλμ @ResponseBody μ λν μ΄μ μ΄ λΆκ±°λ, νΈλ€λ¬ λ©μλμ 리ν΄κ°μ΄ ResponseEntityμΌ κ²½μ° λ΄λΆμ μΌλ‘ HttpMessageConverterκ° λμνκ² λμ΄ μλ΅ κ°μ²΄λ₯Ό JSON νμμΌλ‘ λ°κΏμ€
β
( 리ν΄κ°μ΄ ResponseEntityμΌ κ²½μ° @ResponseBody μ λν μ΄μ λΆμ΄λ©΄ μλμΌλ‘ λ°κΏμ€ )
βοΈ JSON μ§λ ¬ν(Serialization)
Java κ°μ²΄ β JSON νμ
βοΈ JSON μμ§λ ¬ν(Deserialization)
JSON νμ β Java κ°μ²΄
β
( β μ¬κΈ°μ Java κ°μ²΄λ DTO κ°μ ν΄λμ€λ₯Ό λ§νλ κ² ! )
μΌλ°μ μΌλ‘ ν΄λΌμ΄μΈνΈμκ² μμ² λ°μ΄ν°κ° μ λ¬λ λ, μ°λ¦¬νν
λμ΄μ€λ κ·Έ λ°μ΄ν°λ 1μ°¨μ μΌλ‘ μ ν¨μ± κ²μ¦μ΄ μ§νλ λ°μ΄ν°μ
But, μ΄ κ°μ μ‘°μν μ μμ΄ λ°λμ μ ν¨ν κ°μ΄λΌ λ³Ό μ μκΈ° λλ¬Έμ
μλ² μͺ½μμ λ°λμ νλ² λ μ ν¨μ± κ²μ¬λ₯Ό ν΄μΌν¨
μλ² μͺ½μμ μ ν¨ν λ°μ΄ν°λ₯Ό μ λ¬ λ°κΈ° μν΄ λ°μ΄ν°λ₯Ό κ²μ¦νλ κ²
π‘ νΈλ€λ¬ λ©μλ λ΄μ μ ν¨μ± κ²μ¦μ νκ² λλ©΄, μμ² λ°μ΄ν°μ κ°μλ§νΌ λ©μλ λ΄μ κ²μ¦ λ‘μ§μ΄ λμ³λκ² λ¨
β μ½λ 볡μ‘λ λμμ§
β
νΈλ€λ¬ λ©μλλ μμ²μ μ λ¬λ°λ κ²μ΄ μ£Ό λͺ©μ μ΄λΌ μ΅λν κ°κ²°νκ² μμ±ν΄μΌνκΈ°μ
β
DTO ν΄λμ€μ μ ν¨μ± κ²μ¦ μ λν μ΄μ μ μ΄μ©νμ¬
μ ν¨μ± κ²μ¦ λ‘μ§μ DTO ν΄λμ€λ‘ λΉΌλ΄μ΄ νΈλ€λ¬ λ©μλμ κ°κ²°ν¨ μ μ§ κ°λ₯
β
π‘ DTO ν΄λμ€μμ μ ν¨μ± κ²μ¦ μ,
ν΄λΌμ΄μΈνΈμ μμ² λ°μ΄ν°μ μ ν¨νμ§ μμ λ°μ΄ν°κ° μλ€λ©΄ μ ν¨μ± κ²μ¦μ μ€ν¨
β ν΄λΌμ΄μΈνΈμ μμ²μ΄ κ±°λΆλ¨
build.gradle
μ dependencies νλͺ©
μ λ°λ‘ μλμ μμ‘΄μ±μ μΆκ°ν΄μ€μΌ μλμ μ λν
μ΄μ
λ€μ μ¬μ© κ°λ₯ν¨ β¬οΈimplementation 'org.springframework.boot:spring-boot-starter-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λ§ κ°λ₯
[μ°Έκ³ ] 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μ μ λν μ΄μ μ μ¬μ©ν΄μ μ ν¨μ± κ²μ¦μ ν μ μλ€ !
[μ κ·ννμ μ°Έκ³ λ§ν¬]
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κ°λ§ νμ©
π‘ μ κ· ννμ(Regular Expression)μ μ±λ₯μ μΈ λ©΄μμ λλ‘λ λΉμΌ λΉμ©μ μΉλ€μΌ λ κ°λ₯μ±μ΄ μμ
β λͺ¨λ λ‘μ§μ μ κ·ννμ μμ£Όλ‘ μμ±νλ κ²μ μ’μ κ°λ° λ°©μμ΄ μλκΈ°μ
μν©μ λ°λΌ Custom Validator μ¬μ©νκΈ°
Custom Annotationμ μ μ
μ μν Custom Annotationμ λ°μΈλ© λλ Custom Validator ꡬν
μ ν¨μ± κ²μ¦μ΄ νμν DTO ν΄λμ€μ λ©€λ² λ³μμ Custom Annotation μΆκ°
μ΄μ μ€λ μ§μ ν΄λ³΄κ³ ν¬μ€νΈλ§¨μΌλ‘ νμΈν΄λ³΄λκ² μ¬λ°μλ€ !!γ γ