Skip to content

Latest commit

ย 

History

History
218 lines (162 loc) ยท 10.9 KB

Ch_2.md

File metadata and controls

218 lines (162 loc) ยท 10.9 KB

2์žฅ. ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœํ•˜๊ธฐ

ํ•ด๋‹น ๊ธ€์€ ํฌ๋ ˆ์ด๊ทธ ์›”์ฆˆ๋‹˜์ด ์“ฐ๊ณ , ์‹ฌ์žฌ์ฒ ๋‹˜์ด ์˜ฎ๊ธด Spring in Action ์ œ 5ํŒ์„ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž„์„ ๋ฏธ๋ฆฌ ์•Œ๋ฆฝ๋‹ˆ๋‹ค.

๐Ÿ“– ๋ฐฐ์šฐ๋Š” ๋‚ด์šฉ

  • ๋ชจ๋ธ ๋ฐ์ดํ„ฐ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ณด์—ฌ์ฃผ๊ธฐ
  • ํผ ์ž…๋ ฅ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ฒ€์‚ฌํ•˜๊ธฐ
  • ๋ทฐ ํ…œํ”Œ๋ฆฟ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ ํƒํ•˜๊ธฐ

2.1 ์ •๋ณด ๋ณด์—ฌ์ฃผ๊ธฐ

1์žฅ์—์„œ ์ปจํŠธ๋กค๋Ÿฌ์˜ ์—ญํ• ์„ ๋Œ€๋žต์ ์œผ๋กœ ์•Œ์•„๋ณด์•˜๋‹ค. ๋‹ค์‹œํ•œ๋ฒˆ ์ƒ๊ธฐ ์‹œ์ผœ๋ณด์ž๋ฉด, ์Šคํ”„๋ง ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์š”์ฒญ์„ ๋ฐ›์•„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์ด๋ฅผ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋ทฐ์—๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ธฐ๊ฒŒ ๋œ๋‹ค. ์ดํ›„ ๋ทฐ์—์„œ๋Š” ์ „๋‹ฌ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋กœ ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•œ๋‹ค. ์ด ํ๋ฆ„์„ ๋ณด๊ธฐ ์‰ฝ๊ฒŒ ๋‚˜ํƒ€๋‚ด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

๋„๋ฉ”์ธ ์„ค์ •

์ฑ…์—์„œ ๋„๋ฉ”์ธ์„ ํ•ด๋‹น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ดํ•ด์— ํ•„์š”ํ•œ ๊ฐœ๋…์„ ๋‹ค๋ฃจ๋Š” ์˜์—ญ์ด๋ผ๊ณ  ์„ค๋ช…ํ•˜๊ณ  ์žˆ๋‹ค. ๋˜ํ•œ ์ฃผ์„์œผ๋กœ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„๋ฅผ ์ฐธ๊ณ  ํ•˜๋ผ๊ณ  ์ ํ˜€์žˆ๋‹ค. ๊ฐ„๋‹จํ•˜๊ฒŒ DDD(Domain-Driven Design)์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ  ๊ฐ€์ž.

DDD์—์„œ์˜ ๋„๋ฉ”์ธ์€ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๊ฒƒ์„ ์ง€์นญํ•œ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด ์ฑ…์—์„œ ๋‹ค๋ฃจ๊ณ  ์žˆ๋Š” ํƒ€์ฝ”, ํƒ€์ฝ”๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์‹์žฌ๋ฃŒ, ํƒ€์ฝ”๋ฅผ ์ฃผ๋ฌธํ•˜๋Š” ์‚ฌ๋žŒ์˜ ์ •๋ณด ๋“ฑ ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋“ค์–ด์™€ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋“ค์„ ๋„๋ฉ”์ธ์ด๋ผ๊ณ  ํ•œ๋‹ค.(์ฐธ๊ณ  - ๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„(Domain-Driven Design) in Real Project โ€” ๋„๋ฉ”์ธ)

๊ทธ๋ ‡๋‹ค๋ฉด ๊ฐ„๋‹จํ•˜๊ฒŒ ํƒ€์ฝ”์— ๋“ค์–ด๊ฐ€๋Š” ์‹์ž์žฌ๋ฅผ ์ •์˜ํ•ด ๋ณด์ž.

// ์‹์ž์žฌ
@Data
public class Ingredient {
    private final String id;
    private final String name;
    private final Type type;

    public static enum Type {
        WRAP, PROTEIN, VEGGIES, CHEESE, SAUCE
    }
}

์‹์ž์žฌ ๋งˆ๋‹ค์˜ ํŠน๋ณ„ํ•œ id, ์ด๋ฆ„, ํƒ€์ž…์ด ์กด์žฌํ•  ๊ฒƒ์ด๋‹ค. ์ด์™ธ์—๋„ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ถ”๊ฐ€ํ•  ๊ฒƒ๋“ค๋„ ์žˆ๊ฒ ์ง€๋งŒ, ์ค‘์š”ํ•œ ๊ฒƒ์€ @Data ์• ๋…ธํ…Œ์ด์…˜์ด๋‹ค. ํ•ด๋‹น ์• ๋…ธํ…Œ์ด์…˜์€ Lombok์ด๋ž€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์œผ๋กœ, 1์žฅ์—์„œ ์˜์กด์„ฑ์— ์ถ”๊ฐ€ํ–ˆ์—ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋กฌ๋ณต์€ ์ € ํ•˜๋‚˜์˜ ์• ๋…ธํ…Œ์ด์…˜์œผ๋กœ ๊ฒŒํ„ฐ, ์„ธํ„ฐ, toString ๋ฉ”์†Œ๋“œ๋“ฑ ํ•„์š”ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

// Ingredient.class
public class Ingredient {
    private final String id;
    private final String name;
    private final Ingredient.Type type;

    public Ingredient(String id, String name, Ingredient.Type type) {
        this.id = id;
        this.name = name;
        this.type = type;
    }

    public String getId() {
        return this.id;
    }

    public String getName() {
        return this.name;
    }

    public Ingredient.Type getType() {
        return this.type;
    }

    public boolean equals(Object o) {
        ...
    }

    protected boolean canEqual(Object other) {
        return other instanceof Ingredient;
    }

    public int hashCode() {
        ...
    }

    public String toString() {
        ...
    }

    public static enum Type {
        WRAP,
        PROTEIN,
        VEGGIES,
        CHEESE,
        SAUCE;

        private Type() {
        }
    }
}

์ปดํŒŒ์ผ ๋œ ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ IDE๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ๋กœ ์‚ดํŽด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‹ค์ œ๋กœ ์ •์˜ํ•˜์ง€ ์•Š์€ ๋ฉ”์„œ๋“œ๋“ค์ด ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋œ๋‹ค. ์ฐธ๊ณ ๋กœ ์—ฌ๊ธฐ์„œ ์„ธํ„ฐ๊ฐ€ ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์€ ๊ฒƒ์€ ๋ณ€์ˆ˜ ์„ ์–ธ์— final ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๋ ‡๊ฒŒ ๋กฌ๋ณต์€ ๋Ÿฐํƒ€์ž„ ์‹œ์— ์›ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋…์„ฑ๊ณผ ์ƒ์‚ฐ์„ฑ์„ ๋†’ํž ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ, ๋Œ ๋‹ค๋ฆฌ๋„ ๋‘๋“ค๊ฒจ ๋ณด๊ณ  ๋„˜์–ด๊ฐ€๋ž€ ๋ง์ด ์žˆ๋“ฏ ์–ด๋Š ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ์ž˜ ์•Œ์•„๋ณด๊ณ  ์‚ฌ์šฉํ•ด์•ผ ๋œ๋‹ค. ๋กฌ๋ณต ๋˜ํ•œ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ž˜ ์•Œ์•„๋ณด๊ณ  ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ ์œ„์—์„œ ์‚ฌ์šฉํ–ˆ๋˜ @Data ์• ๋…ธํ…Œ์ด์…˜ ํ˜น์€ @ToString ์• ๋…ธํ…Œ์ด์…˜์œผ๋กœ toString ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์„ฑํ–ˆ์„ ๋•Œ, ์ˆœํ™˜ ์ฐธ์กฐ ๋ฌธ์ œ๋กœ ์ธํ•ด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ @Data ๊ฐ™์ด ํ•œ๋ฒˆ์— ์—ฌ๋Ÿฌ๊ฐ€์ง€๋ฅผ ๋š๋”ฑ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์• ๋…ธํ…Œ์ด์…˜์€ ์ง€์–‘ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ์ด์™ธ์—๋„ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ƒ๊ฐํ•  ์ ๋“ค์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฐธ๊ณ ํ•˜์—ฌ ์ž˜ ์‚ฌ์šฉํ•ด๋ณด์ž.(์ฐธ๊ณ  - ์‹ค๋ฌด์—์„œ Lombok ์‚ฌ์šฉ๋ฒ•)

์š”์ฒญ ์ฒ˜๋ฆฌ

์–ด๋– ํ•œ ์ปจํŠธ๋กค๋Ÿฌ์— URL์„ ๋งตํ•‘ํ•˜๋Š” @RequestMapping ์• ๋…ธํ…Œ์ด์…˜์„ ์ž˜ ์•Œ๊ณ  ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์ด๋Š” ์Šคํ”„๋ง 4.3๋ฒ„์ „ ์ด์ „์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์œผ๋กœ GET ํ˜น์€ POST ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” method ์†์„ฑ์„ ์„ค์ •ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

@RequestMapping(value="/" mehtod=RequestMehod.GET)

์Šคํ”„๋ง 4.3๋ถ€ํ„ฐ๋Š” ๊ฐ ์š”์ฒญ ๋ฉ”์†Œ๋“œ์— ํŠนํ™”๋œ ์• ๋…ธํ…Œ์ด์…˜๋“ค์ด ๋“ฑ์žฅํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

์• ๋…ธํ…Œ์ด์…˜ ์„ค๋ช…
@RequestMapping ๋‹ค๋ชฉ์ ์œผ๋กœ ์š”์ฒญ์„ ์ฒ˜๋ฆฌ
@GetMapping HTTP GET ์š”์ฒญ ์ฒ˜๋ฆฌ
@PostMapping HTTP POST์š”์ฒญ ์ฒ˜๋ฆฌ
@PutMapping HTTP PUT ์š”์ฒญ ์ฒ˜๋ฆฌ
@DeleteMapping HTTP DELETE ์š”์ฒญ ์ฒ˜๋ฆฌ
@PatchMapping HTTP PATCH ์š”์ฒญ ์ฒ˜๋ฆฌ

2.2 ํผ ์ œ์ถœ ์ฒ˜๋ฆฌํ•˜๊ธฐ

ํผ ํƒœ๊ทธ์˜ ๊ฒฝ์šฐ, method ์†์„ฑ์ด POST๋กœ ์„ค์ •ํ•ด๋„ action ์†์„ฑ์ด ์„ ์–ธ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด, GET ์š”์ฒญ๊ณผ ๊ฐ™์€ ๊ฒฝ๋กœ๋กœ ์„œ๋ฒ„์— POST ์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋œ๋‹ค.

<!-- localhost:8080/example -->
<form method="POST">
  <!-- /example ์œผ๋กœ POST ์š”์ฒญ -->
</form>

<form method="GET">
  <!-- /example ์œผ๋กœ GET ์š”์ฒญ -->
</form>

๋ฆฌ๋‹ค์ด๋ ‰์…˜

์•ž์„œ์„œ ์ปจํŠธ๋กค๋Ÿฌ๋“ค์„ ๋งŒ๋“ค์—ˆ์„ ๋•Œ ๋ฆฌํ„ด ๊ฐ’์œผ๋กœ ๋ทฐ์˜ ์ด๋ฆ„์„ ์ง€์ •ํ–ˆ๋‹ค. ์ด๋•Œ ์•„๋ž˜์™€ ๊ฐ™์ด "redirection:"์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ๊ฒฝ๋กœ๋กœ ์žฌ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋„๋ก ์œ ๋„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

@PostMapping
public String redirectMethod() {
  return "redirection:/dest";
}

2.3 ํผ ์ž…๋ ฅ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌํ•˜๊ธฐ

๋งŒ์•ฝ ์‚ฌ์šฉ์ž๊ฐ€ ํผ์— ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•˜๋‹ค ์กฐ๊ฑด์— ๋งž์ง€ ์•Š๋Š” ๋‚ด์šฉ์„ ์ž‘์„ฑํ•˜๊ฑฐ๋‚˜, ์•„์— ์ž…๋ ฅํ•˜์ง€ ์•Š์€ ๋ถ€๋ถ„์€ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•ด์•ผ ๋ ๊นŒ? ํ”„๋ก ํŠธ ๋‹จ์—์„œ ๋จผ์ € ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ•˜์—ฌ ์ „์†ก์„ ๋ง‰์„ ์ˆ˜๋„ ์žˆ๊ณ , ์„œ๋ฒ„ ๋‹จ์—์„œ ์ €์žฅ์ด ๋˜์ง€ ์•Š๋„๋ก ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์Šคํ”„๋ง์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ์šฐ๋ฆฌ๋Š” ์„œ๋ฒ„ ๋‹จ์—์„œ ์ด๋ฅผ ์–ด๋–ป๊ฒŒ ๊ฒ€์‚ฌํ• ์ง€ ์•Œ์•„๋ณด์ž.

์Šคํ”„๋ง์—์„œ๋Š” ์ž๋ฐ”์˜ ๋นˆ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ API๋ฅผ ์ง€์›ํ•˜๊ธฐ์— if/else ๋ธ”๋ก๋“ค์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ๋„ ์‰ฝ๊ฒŒ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” spring-boot-starter-validation ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด์ฃผ๋„๋ก ํ•œ๋‹ค(๊ตฌํ˜„์ฒด๋กœ Hibernate Validator ์‚ฌ์šฉ). ์ฑ…์—์„œ๋Š” ํ•ด๋‹น ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋Š” 2.2.X ๋ฒ„์ „์—์„œ๋Š” spring-boot-starter-validation ๊ฐ€ ์กด์žฌํ•˜์˜€์ง€๋งŒ, 2.3.X ๋ถ€ํ„ฐ๋Š” ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์• ๋…ธํ…Œ์ด์…˜ ๊ธฐ๋Šฅ
@AssertFalse flase ๊ฐ’ ์ฒดํฌ
@AssertTrue true ๊ฐ’ ์ฒดํฌ
@DecimalMax(value=) ์ง€์ •๋œ ๊ฐ’ ์ดํ•˜์˜ ์‹ค์ˆ˜๋งŒ
@DecimalMin(value=) ์ง€์ •๋œ ๊ฐ’ ์ด์ƒ์˜ ์‹ค์ˆ˜๋งŒ
@Digits(integer=, fraction=) ์ง€์ •๋œ ์ •์ˆ˜์™€ ์†Œ์ˆ˜ ์ž๋ฆฌ์ˆ˜๋ณด๋‹ค ์ž‘์„ ๊ฒฝ์šฐ
@Future ๋Œ€์ƒ ๋‚ ์งœ๊ฐ€ ํ˜„์žฌ๋ณด๋‹ค ๋ฏธ๋ž˜์ผ ๊ฒฝ์šฐ๋งŒ
@Past ๋Œ€์ƒ ๋‚ ์งœ๊ฐ€ ํ˜„์žฌ๋ณด๋‹ค ๊ณผ๊ฑฐ์ผ ๊ฒฝ์šฐ๋งŒ
@Max(value=) ์ง€์ •๋œ ๊ฐ’๋ณด๋‹ค ์ž‘์„ ๊ฒฝ์šฐ
@Min(value=) ์ง€์ •๋œ ๊ฐ’๋ณด๋‹ค ํด ๊ฒฝ์šฐ
@NotNull null ๊ฐ’์ด ์•„๋‹ ๊ฒฝ์šฐ
@Null null์ผ ๊ฒฝ์šฐ
@Pattern(regex=, flag=) ํ•ด๋‹น ์ •๊ทœ์‹์„ ๋งŒ์กฑํ•˜๋Š” ๊ฒฝ์šฐ
@Size(min=, max=) ๋ฌธ์ž์—ด ๋˜๋Š” ๋ฐฐ์—ด์ด min๊ณผ max ์‚ฌ์ด์ผ ๊ฒฝ์šฐ
@Valid ๋Œ€์ƒ ๊ฐ์ฒด์˜ ํ™•์ธ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•  ๊ฒฝ์šฐ ํ†ต๊ณผ
@NotBlank ๋ฌธ์ž์—ด์ด๋‚˜ ๋ฐฐ์—ด์ด null์ด ์•„๋‹ˆ๊ณ  ๊ธธ์ด๊ฐ€ 0์ด ์•„๋‹ ๊ฒฝ์šฐ
@Email ์ด๋ฉ”์ผ ํ˜•์‹ ์ฒดํฌ
@CreditCardNumber Luhn(๋ฃฌ) ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ์˜ํ•œ ์‹ ์šฉ์นด๋“œ ๋ฒˆํ˜ธ ์ฒดํฌ

2.4 ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์ž‘์—…ํ•˜๊ธฐ

@Controller
@RequestMapping("/simple")
public class SimpleController {
  @GetMapping
  public String simple() {
    return "simple";
  }
}

์œ„์™€ ๊ฐ™์ด ๋ชจ๋ธ ๋ฐ์ดํ„ฐ ํ˜น์€ ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์ด ํ•„์š”์—†๋Š” ๊ฐ„๋‹จํ•œ ์ปจํŠธ๋กค๋Ÿฌ์˜ ๊ฒฝ์šฐ, ์•„๋ž˜์˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ(๋ทฐ์— ์š”์ฒญ ์ „๋‹ฌ๋งŒ ํ•˜๋Š” ์—ญํ• )๋กœ ์ •์˜๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

@Configuration
public class webCofig implements WebMvcConfigurer {
  @Override
  public void addViewController(ViewControllerRegistry registry) {
    registry.addViewController("/simple").setViewName("simple");
  }
}

WebMvcConfigurer ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ดํŽด๋ณด๋ฉด ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฉ”์„œ๋“œ๋“ค์ด default๋กœ ์„ ์–ธ๋˜์–ด์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์›ํ•˜๋Š” ์„ค์ •์„ ํ•˜๊ธฐ ์œ„ํ•ด ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋งŒ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.


2.5 ๋ทฐ ํ…œํ”Œ๋ฆฟ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ ํƒํ•˜๊ธฐ

์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ ์ž๋™-๊ตฌ์„ฑ ์ง€์›๋˜๋Š” ํ…œํ”Œ๋ฆฟ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

ํ…œํ”Œ๋ฆฟ ์Šคํƒ€ํ„ฐ ์˜์กด์„ฑ
FreeMarker spring-boot-starter-freemarker
Groovy spring-boot-starter-groovy-templates
Java Server Pages(JSP) ์—†์Œ
Mustache spring-boot-starter-mustache
Thymeleaf spring-boot-starter-thymeleaf

ํ…œํ”Œ๋ฆฟ์ค‘์—์„œ JSP๋Š” ์˜์กด์„ฑ์„ ์ง€์ •ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ๊ทธ ์ด์œ ๋Š” ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ์—์„œ JSP ๋ช…์„ธ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋กœ ์ง€์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ JSP๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๊ณ ๋ คํ•  ์‚ฌํ•ญ์ด ์ƒ๊ธด๋‹ค. ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ /WEB-INF ํ•˜์œ„์—์„œ JSP ์ฝ”๋“œ๋ฅผ ์ฐพ๊ฒŒ ๋˜๋Š”๋ฐ, JAR ํŒŒ์ผ๋กœ ์ƒ์„ฑํ–ˆ์„ ๊ฒฝ์šฐ ์ด๊ฐ€ ์—†๋‹ค. ๋”ฐ๋ผ์„œ WAR ํŒŒ์ผ๋กœ ํŒจํ‚ค์ง•ํ•˜๋Š” ํ”„๋กœ์ ํŠธ์—์„œ JSP๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ๋‹ค๋ฅธ ํ…œํ”Œ๋ฆฟ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์ด ์ข‹๋‹ค.