[TIL] #7. 스프링 MVC - 웹 페이지 만들기 ①

kiteB·2021년 9월 17일
0

TIL-Spring3

목록 보기
6/7
post-thumbnail
post-custom-banner

프로젝트 생성

새로운 상품 관리 예제 시작!

🔗 전체 코드 확인하기


요구사항 분석

상품을 관리할 수 있는 서비스를 만들어보자. 요구사항은 다음과 같다.

✔ 상품 도메인 모델

: 상품 ID / 상품명 / 가격 / 수량

✔ 상품 관리 기능

: 상품 목록 / 상품 상세 / 상품 등록 / 상품 수정


서비스 제공 흐름

요구사항이 정리되고 디자이너, 웹 퍼블리셔, 백엔드 개발자가 업무를 나누어 진행한다.

  • 디자이너: 요구사항에 맞도록 디자인하고, 디자인 결과물을 웹 퍼블리셔에게 넘겨준다.
  • 웹 퍼블리셔: 다자이너에서 받은 디자인을 기반으로 HTML, CSS를 만들어 개발자에게 제공한다.
  • 백엔드 개발자: HTML 화면이 나오기 전까지 시스템을 설계하고, 핵심 비즈니스 모델을 개발한다. 이후 HTML이 나오면 이 HTML을 뷰 템플릿으로 변환해서 동적으로 화면을 그리고, 또 웹 화면의 흐름을 제어한다.

상품 도메인 개발

💡 상품 도메인 모델

: 상품 ID / 상품명 / 가격 / 수량

🔗 전체 코드 확인하기

테스트까지 확인 완료!


상품 서비스 HTML

부트스트랩

HTML 개발을 편리하게 하기 위해서 부트스트랩을 사용해보자!😃

부트스트랩에서 Compiled CSS and JS항목을 다운받은 뒤 bootstrap.min.css 파일을 resources/static/css 폴더에 추가해주자!

⚠ 주의

가끔 IntelliJ에 파일 그대로 옮기면 안될 때도 있어서,
http://localhost:8080/css/bootstrap.min.css에 접속했을 때 이렇게 잘 나오는지 확인하기!


HTML 만들기

이제 페이지를 만들어보자!

🔗 전체 코드 확인하기

실행 결과

  • items.html
  • item.html
  • addForm.html
  • editForm.html

상품 목록 - 타임리프

상품 목록 컨트롤러와 뷰 템플릿을 개발해보자!

BasicItemController

package hello.itemservice.web.basic;

import hello.itemservice.domain.item.Item;
import hello.itemservice.domain.item.ItemRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.PostConstruct;
import java.util.List;

@Controller
@RequestMapping("/basic/items")
@RequiredArgsConstructor
public class BasicItemController {

    private final ItemRepository itemRepository;

    @GetMapping
    public String items(Model model) {
        List<Item> items = itemRepository.findAll();
        model.addAttribute("items", items);
        return "basic/items";
    }

    @PostConstruct
    public void init() {
        itemRepository.save(new Item("testA", 1000, 10));
        itemRepository.save(new Item("testB", 2000, 20));
    }
}
  • 컨트롤러 로직
    : itemRepository에서 모든 상품 조회 → 모델에 저장 → 뷰 템플릿 호출
  • @RequiredArgsContructor: final이 붙은 멤버 변수만 사용해 생성자를 자동 생성
  • @PostConstructor
    • 컨트롤러만 구현하고 테스트하면 데이터가 초기화되기 때문에, 프로젝트 로드 시 해당 빈의 의존관계가 모두 주입된 후 초기화 용도로 호출.
    • init()을 수행해 2개의 아이템 미리 추가!

items.html

위에서 작성했던 items.html뷰 템플릿 영역으로 복사해주자.

🔗 코드 확인하기

실행 결과


타임리프(Thymeleaf) 간단히 알아보기

✔ 타임리프 사용 선언

<html xmlns:th="http://www.thymeleaf.org">

타임리프를 사용하려면 html 파일에 이렇게 적어야 한다.


✔ 속성 변경 - th:href

th:href="@{/css/bootstrap.min.css}"
  • 기존 hrefth:href로 변경해준다.
  • 타임리프 뷰 템플릿을 거치면 원래 값을 th:xxx로 변경한다. 만약 값이 없다면 새로 생성한다.
  • HTML을 그대로 볼 때는 href 속성이 사용되고, 뷰 템플릿을 거치면 th:href의 값이 href로 대체되면서 동적으로 변경할 수 있다.

✔ 타임리프 핵심

  • th:xxx 부분은 서버사이드에서 렌더링되고, 기존 속성을 대체한다. 만약 th:xxx이 없으면 기존 html의 xxx속성이 그대로 사용된다.
  • HTML 파일을 직접 열엇었을 때, th:xxx 속성을 웹 브라우저에서는 읽지 못하기 때문에 무시한다.
  • HTML을 파일 보기를 유지하면서 템플릿 기능도 할 수 있다!

URL링크 표현식 - @{...}

  • URL 링크를 사용하는 경우 @{...}를 사용하는데, 이를 URL링크 표현식이라 한다.
  • URL 링크 표현식을 사용하면 서블릿 컨텍스트를 자동으로 포함한다.

✔ 리터럴 대체 - |...|

th:onclick="|location.href='@{/basic/items/add}'|"
  • 타임리프에서 문자와 표현식 등은 분리되어 있어서, 합쳐서 쓰고 싶을 때 이것을 사용한다.

1. + + escape

<span th:text="'Welcome to our application, ' + ${user.name} + '!'">

2. |...| (리터럴 대체 문법)

<span th:text="|Welcome to our application, ${user.name}!|">
  • 기존에는 + 연산자와 escape 기호를 사용해 하나하나 작성해야 했지만, 리터럴 대체 문법을 사용하면 편리하게 사용할 수 있다!

✔ 반복 출력 - th:each

<tr th:each="item : ${items}">
  • 반복은 th:each를 사용한다.
  • 컬렉션 수만큼 <tr>..</tr> 이 하위 태그를 포함해서 생성된다.

✔ 변수 표현식 - ${...}

<td th:text="${item.price}">10000</td>
  • 모델에 포함된 값이나, 타임리프 변수로 선언한 값을 조회할 수 있다.
  • 프로퍼티 접근법을 사용한다. (item.getPrice())

✔ 내용 변경 - th:text

<td th:text="${item.price}">10000</td>
  • 내용의 값을 th:text의 값으로 변경한다.
  • 여기서는 10000${item.price}의 값으로 변경한다.

URL 링크 표현식2 - @{...}

th:href="@{/basic/items/{itemId}(itemId=${item.id})}"
  • URL 링크 표현식을 사용하면 경로를 템플릿처럼 편리하게 사용할 수 있다.
  • 경로 변수({itemId})뿐만 아니라 쿼리 파라미터도 생성할 수 있다.

✔ URL 링크 축약

th:href="@{|/basic/items/${item.id}|}"
  • 리터럴 대체 문법을 활용해서 간단히 사용할 수도 있다.

📌 네츄럴 템플릿 (natural templates)

타임리프는 순수 HTML 파일을 웹 브라우저에서 열어도 내용을 확인할 수 있고, 서버를 통해 뷰 템플릿을 거치면 동적으로 변경된 결과를 확인할 수 있다.
이렇게 순수 HTML을 유지하면서 뷰 템플릿도 사용할 수 있는 타임리프의 특징을 네츄럴 템플릿이라고 한다!

profile
🚧 https://coji.tistory.com/ 🏠
post-custom-banner

0개의 댓글