Day 6

ํ…œํ”Œ๋ฆฟ ์—”์ง„

  • ์ง€์ •๋œ ํ…œํ”Œ๋ฆฟ ์–‘์‹๊ณผ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•ฉ์ณ์ ธ์„œ HTML๋ฌธ์„œ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” sw๋ฅผ ์•ผ๊ธฐํ•œ๋‹ค

  • ์„œ๋ฒ„์—์„œ ๊ตฌ๋™๋œ๋‹ค

  • ์„œ๋ฒ„ ํ…œํ”Œ๋ฆฟ ์—”์ง„์„ ์ด์šฉํ•œ ํ™”๋ฉด ์ƒ์„ฑ์€ ์„œ๋ฒ„์—์„œ Java ์ฝ”๋“œ๋กœ ๋ฌธ์ž์—ด์„ ๋งŒ๋“  ๋’ค, ์ด ๋ฌธ์ž์—ด์„ HTML์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๋กœ ์ „๋‹ฌ

    • ์„œ๋ฒ„ โ†’ ํ…Œํ”Œ๋ฆฟ โ†’ java์ฝ”๋“œ โ†’ HTML โ†’ ๋ธŒ๋ผ์šฐ์ €์ „๋‹ฌ

๋จธ์Šคํ…Œ์น˜

  • ์ˆ˜ ๋งŽ์€ ์–ธ์–ด๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฐ€์žฅ ์‹ฌํ”Œํ•œ ํ…œํ”Œ๋ฆฟ ์—”์ง„

  • ๋ฌธ๋ฒ•์ด ๋‹ค๋ฅธ ํ…œํ”Œ๋ฆฟ ์—”์ง„๋ณด๋‹ค ์‹ฌํ”Œ

  • ๋กœ์ง ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์—†์Œ โ‡’ View/Server์˜ ์—ญํ• ์ด ๋ถ„๋ช…ํ•˜๊ฒŒ ๋‚˜๋ˆ ์ง

  • .js์™€ .java ์ด๋ ‡๊ฒŒ 2๊ฐ€์ง€๊ฐ€ ์žˆ์–ด์„œ ํ•˜๋‚˜์˜ ๋ฌธ๋ฒ•์œผ๋กœ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๋ชจ๋‘ ์‚ฌ์šฉ๊ฐ€๋Šฅ

ํ…œํ”Œ๋ฆฟ ์—”์ง„์€ ํ™”๋ฉด ์—ญํ• ์— ์ถฉ์‹คํ•ด์•ผ ํ•œ๋‹ค!!

build.gradle

compile('org.springframework.boot:spring-boot-starter-mustache')

๋จธ์Šคํ…Œ์น˜ ์Šคํƒ€ํ„ฐ ์˜์กด์„ฑ์„ ๋“ฑ๋ก(์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ ๊ณต์‹์œผ๋กœ ์ง€์›ํ•˜๋Š” ํ…œํ”Œ๋ฆฟ ์—”์ง„)

ํŒŒ์ผ ์œ„์น˜ : src/main/resource/templates

src/main/resource/templates/index.mustache

<!DOCTYPE HTML>
<html>
<head>
    <title>์Šคํ”„๋ง ๋ถ€ํŠธ ์›น์„œ๋น„์Šค</title>
    <meta http-equiv="Content-Type" content="text/html"; charset="UTF-8" />
</head>
<body>
    <h1>์Šคํ”„๋ง ๋ถ€ํŠธ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์›น ์„œ๋น„์Šค</h1>
</body>
</html>

index.mustache๋ฅผ ๋ Œ๋”๋งํ•ด์ฃผ๋Š” ์ปจํŠธ๋กค๋Ÿฌ

src/main/java/web/dto/IndexController.class

package com.kyu.book.springboot.web.dto;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class IndexController {
    @GetMapping("/")
    public String index(){
        return "index";
    }
}
  • mustache ์Šคํƒ€ํ„ฐ ๋•๋ถ„์— ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•  ๋•Œ

    • ์•ž์˜ ๊ฒฝ๋กœ(src/main/resources/template)

    • ๋’ค์˜ ํŒŒ์ผ ํ™•์žฅ์ž(.mustache)

    • ์ด 2๊ฐœ๋Š” ์ž๋™์œผ๋กœ ์ง€์ •

  • ๋ฆฌํ„ด ๊ฐ’์ธ "index"๋Š” src/main/resources/templates/index.mustache๋กœ ๋ณ€ํ™˜๋˜์–ด View Resolver๊ฐ€ ์ฒ˜๋ฆฌ

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

src/test/java/com/kyu/book/springboot/web/IndexControllerTest.class

package com.kyu.book.springboot.web;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class IndexControllerTest {
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void mainPageLoad(){
        String body = this.restTemplate.getForObject("/", String.class);

        assertThat(body).contains("์Šคํ”„๋ง ๋ถ€ํŠธ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์›น ์„œ๋น„์Šค");
    }
}
  • ์‹ค์ œ๋กœ URL์ด ํ˜ธ์ถœ๋˜์—ˆ์„ ๋–„, ๋‚ด์šฉ์ด ์ œ๋Œ€๋กœ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ํ…Œ์ŠคํŠธ

    • "์Šคํ”„๋ง ๋ถ€ํŠธ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์›น ์„œ๋น„์Šค"๋ผ๋Š” ๋ฌธ์žฅ์ด ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธ

๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก ํ™”๋ฉด ๋งŒ๋“ค๊ธฐ

๋ถ€ํŠธ์ŠคํŠธ๋žฉ์„ ์ด์šฉ

  • ์™ธ๋ถ€ CDN์„ ์‚ฌ์šฉ โ†’ ํ”„๋กœ์ ํŠธ์— ๋‹ค์šด๋กœ๋“œ ๋ฐ›์„ ํ•„์š”x, ๋‹จ์ง€ ์ฝ”๋“œ ํ•œ ์ค„๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ใ…‡ใ…‹

    • ํ•˜์ง€๋งŒ ์‹ค์ œ ์„œ๋น„์Šค์—์„œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค โ‡’ CDN์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋ฉด ์„œ๋น„์Šค์—๋„ ๋ฌธ์ œ์ƒ๊น€(์•ˆ์ข‹์Œ)

  • ์ง์ ‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ฐ›์•„์„œ ์‚ฌ์šฉ

๋ถ€ํŠธ์ŠคํŠธ๋žฉ๊ณผ ์ œ์ด์ฟผ๋ฆฌ๋ฅผ index.mustache์— ์ถ”๊ฐ€ โ†’ ๋ ˆ์ด์•„์›ƒ ๋ฐฉ์‹์„ ํ™œ์šฉ

  • ๋ ˆ์ด์•„์›ƒ ๋ฐฉ์‹ : ๊ณตํ†ต ์˜์—ญ์„ ๋ณ„๋„์˜ ํŒŒ์ผ๋กœ ๋ถˆ๋ฆฌํ•˜์—ฌ ํ•„์š”ํ•œ ๊ณณ์—์„œ ๊ฐ€์ ธ๋‹ค ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹

src/main/resources/templates/layout์— footer.mustache, header.mustache๋ฅผ ์ถ”๊ฐ€

css๋Š” header์—, js๋Š” footer์— โ‡’ ํŽ˜์ด์ง€์˜ ๋กœ๋”ฉ์†๋„๋ฅผ ๋†’ํžˆ๊ธฐ ์œ„ํ•ด

  • head๊ฐ€ ๋‹ค ๋ถˆ๋Ÿฌ์ง€์ง€ ์•Š์œผ๋ฉด ์‚ฌ์šฉ์ž ์ชฝ์—์„  ๋ฐฑ์ง€ ํ™”๋ฉด๋งŒ ๋…ธ์ถœ

  • js์˜ ์šฉ๋Ÿ‰์ด ํฌ๋ฉด ํด์ˆ˜๋ก body๋ถ€๋ถ„์˜ ์‹คํ–‰์ด ๋Šฆ์–ด์ง โ‡’ js๋Š” body ํ•˜๋‹จ์— ๋‘์–ด ํ™”๋ฉด์ด ๋‹ค ๊ทธ๋ ค์ง„ ๋’ค์— ํ˜ธ์ถœ

  • css๋Š” ํ™”๋ฉด์„ ๊ทธ๋ฆฌ๋Š” ์—ญํ• ์ด๊ธฐ ๋–„๋ฌธ์— head์—์„œ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ์ด ์ข‹์Œ

  • ๋ถ€ํŠธ์ŠคํŠธ๋žฉ์€ ์ œ์ด์ฟผ๋ฆฌ๊ฐ€ ๊ผญ ์žˆ์–ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถ€ํŠธ์ŠคํŠธ๋žฉ๋ณด๋‹ค ๋จผ์ € ํ˜ธ์ถœํ•˜๋„๋ก

footer์™€ header์˜ ์ถ”๊ฐ€๋กœ index์—๋Š” ์ง„์งœ ํ•„์š”ํ•œ ์ฝ”๋“œ๋งŒ ๋‚จ๊ฒŒ ๋จ

src/main/resources/templates/index.mustache

{{>layout/header}}
    <h1>์Šคํ”„๋ง ๋ถ€ํŠธ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์›น ์„œ๋น„์Šค</h1>
    <div class="col-md-12">
        <div class="col-md-6">
            <a href="/posts/save" role="button" class="btn btn-primary">๊ธ€ ๋“ฑ๋ก</a>
        </div>
    </div>
{{>layout/footer}}
  • {{>}}๋Š” ํ˜„์žฌ mustacheํŒŒ์ผ์˜ ๊ธฐ์ค€์œผ๋กœ ๋‹ค๋ฅธ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ

Last updated

Was this helpful?