Spring Boot (+ RESTful)

Spring Boot - # Project 03 - 웹 버튼 클릭 /

wy-family 2024. 12. 18. 12:58

자, 이제 View Details 버튼을 누르면 작동되도록 해보자.

 

home.html 을 확인해보자.

1. HTML 기본 구조

HTML은 HyperText Markup Language의 약자로, 웹페이지의 구조를 만들 때 사용되는 언어입니다.
HTML은 태그로 구성되며, 각 태그는 여는 태그 <태그>와 닫는 태그 </태그>로 나눠집니다.

<div>내용</div>

여기서 <div>는 **"division"**의 약자이며, 컨테이너(묶음) 역할을 합니다. 즉, <div>는 다른 요소들을 그룹화하기 위해 사용됩니다.


2. class 속성

  • class는 CSS나 JavaScript에서 특정 요소를 선택하거나 스타일을 적용하기 위해 사용되는 속성입니다.
  • 하나의 클래스 이름에 여러 요소를 부여할 수 있고, 하나의 요소에 여러 클래스 이름을 붙일 수도 있습니다.

예시:

<div class="container my-5"></div>

여기서 class="container my-5"는 이 요소에 container와 my-5라는 두 개의 클래스가 적용되었음을 의미합니다.
container와 my-5는 CSS 프레임워크(Bootstrap)의 미리 정의된 클래스 이름입니다.


3. container 클래스

container 클래스는 Bootstrap의 클래스입니다.
Bootstrap은 웹 개발에 자주 사용되는 CSS 프레임워크로, 간편하게 웹페이지 디자인을 할 수 있게 도와줍니다.

  • container는 페이지의 내용을 중앙에 정렬하고, 좌우 여백을 만들어줍니다.
    즉, **페이지의 내용을 "중심 정렬"**하고 내용이 너무 화면 끝으로 붙지 않도록 여백을 만듭니다.

4. my 클래스와 my-5

my는 여백(margin)을 추가하는 Bootstrap의 약어입니다.

  • m: margin (바깥 여백)
  • y: 수직 여백 (위, 아래)
  • 5: 여백의 크기 (0부터 5까지 숫자가 있고, 5는 큰 여백을 의미합니다.)

즉, my-5는 위쪽(margin-top)과 아래쪽(margin-bottom)에 큰 여백을 추가합니다.

예시:

<div class="my-5"></div>
  • 이 코드의 <div> 요소는 위와 아래에 동일하게 큰 여백이 추가됩니다.

5. Bootstrap Grid System (row와 col-md-4)

Bootstrap에는 그리드 시스템이 있어서, 화면을 여러 개의 열(column)로 나눌 수 있습니다.

  • row: 줄(row)을 의미합니다. <div class="row">는 하나의 줄을 만들겠다는 의미입니다.
  • col-md-4: 열(column)을 의미하며, 화면 크기가 중간(md) 이상일 때 화면의 12등분 중 4등분을 차지하겠다는 의미입니다.

Grid System의 개념:

  • 화면은 기본적으로 **12개의 열(column)**로 나뉩니다.
  • col-md-4는 12개의 열 중 4개를 차지하므로, 한 줄에 3개의 열이 배치됩니다.

예시:

<div class="row">
    <div class="col-md-4"></div>
    <div class="col-md-4"></div>
    <div class="col-md-4"></div>
</div>

위 코드의 경우 한 줄(row)에 3개의 열이 배치됩니다.


6. card 클래스

card는 Bootstrap에서 제공하는 카드형 디자인을 위한 클래스입니다. 카드에는 제목, 이미지, 본문 등이 깔끔하게 포함될 수 있습니다.

shadow-sm:

  • 작은 그림자 효과를 부여합니다.
  • **shadow**는 그림자 효과를 의미하며, -sm은 작은(small) 그림자를 뜻합니다.

7. card-body

card-body는 카드 내부의 내용을 감싸는 컨테이너입니다. 여기에는 텍스트, 제목, 버튼 등을 넣습니다.


8. h5와 h6 태그

<h1>부터 <h6>까지는 HTML에서 제목(heading)을 나타내는 태그입니다.

  • <h1>: 가장 큰 제목
  • <h6>: 가장 작은 제목

여기서 th:text는 Thymeleaf 문법입니다. Thymeleaf는 Java의 Spring Boot에서 사용되는 템플릿 엔진입니다.
th:text="${book.subject}"는 Java 객체 book의 subject 값을 HTML에 출력하는 코드입니다.


9. p 태그와 <span>

  • <p>: 문단(paragraph)을 나타내는 태그입니다. 텍스트를 감쌀 때 사용합니다.
  • <span>: 인라인 요소로, 텍스트의 특정 부분에 스타일을 적용하거나 데이터를 표시할 때 사용됩니다.

10. btn 클래스와 btn-primary

btn은 버튼 스타일을 적용하는 Bootstrap 클래스입니다.

  • btn-primary: 주요 버튼(파란색 버튼) 스타일을 적용합니다.

정리된 코드 이해

  1. 전체 구조:
    <div class="container">는 웹페이지 내용을 중앙에 정렬하고 여백을 줍니다.
  2. 줄과 열:
    <div class="row"> 안에서 <div class="col-md-4">는 12칸 중 4칸을 차지하는 열을 3개 배치합니다.
  3. 카드 디자인:
    <div class="card">는 각 책 정보를 카드형 디자인으로 표현합니다.
  4. Thymeleaf 문법:
    th:text는 Java 객체에서 값을 불러와 화면에 출력합니다.
  5. 여백과 스타일:
    my-5와 shadow-sm은 여백과 그림자 효과를 추가합니다.

1. th:text="${book.subject}">Book Subject

  • th:text: Thymeleaf의 속성입니다.
    • th:text="${book.subject}"는 Java 객체 book의 subject 속성 값을 출력하라는 의미입니다.
  • >Book Subject:
    • > 기호는 여는 태그와 내용 사이를 구분하는 구문입니다.
    • Book Subject는 백업 텍스트(기본 텍스트)로, Thymeleaf가 작동하지 않는 경우 화면에 보입니다.
    • 예를 들어, Thymeleaf를 사용하지 않고 단순히 HTML만 실행하면 화면에 "Book Subject"라는 값이 나타납니다.

2. text-muted 클래스

text-muted는 Bootstrap 클래스입니다.

  • 이 클래스는 텍스트 색상을 회색처럼 흐리게 만들어 부수적인 정보임을 강조할 때 사용합니다.
  • 예를 들어, 저자 이름이나 추가 정보를 표시할 때 text-muted를 쓰면 디자인적으로 더 깔끔해집니다.

예시:

<h6 class="card-subtitle mb-2 text-muted">Author Name</h6>

결과: "Author Name"이 흐릿한 회색 텍스트로 보입니다.


3. <span> 태그와 $<span

<span> 태그

  • <span>: 인라인 요소입니다. 텍스트의 일부를 감싸서 스타일을 적용하거나 특정 데이터를 표시할 때 사용합니다.
    • <span> 안에 있는 내용은 한 줄로 표시됩니다.
    • 블록 요소(줄바꿈을 하는 태그)와는 다릅니다.

$<span와 <span의 차이

  • $는 Thymeleaf 문법의 일부입니다.
  • th:text="${book.price}" 같은 형태로 객체의 값을 화면에 출력하려고 할 때 사용합니다.
  • $는 Thymeleaf 표현식(EL)을 의미합니다.

예시:

Price: $<span th:text="${book.price}">10</span>
  • th:text="${book.price}"는 book.price 값이 15라면 화면에는 15가 출력됩니다.
  • Thymeleaf가 작동하지 않는 경우 기본 값인 10이 보입니다.

4. <br> 태그

  • **<br>**는 **줄바꿈(break)**을 의미하는 태그입니다.
  • <br>를 사용하면 텍스트 다음에 줄바꿈이 일어나 다음 줄로 이동합니다.

예시:

Price: $10<br>
Pages: 200

출력 결과:

Price: $10
Pages: 200

5. <a> 태그

  • <a> 태그는 **"anchor(앵커)"**를 의미하며, 하이퍼링크를 만들 때 사용됩니다.
  • 링크를 클릭하면 다른 페이지로 이동하거나 특정 작업이 실행됩니다.

기본 문법:

<a href="URL">링크 텍스트</a>
  • href: hyperlink reference의 약자입니다.
    • 링크를 클릭했을 때 이동할 주소(URL)를 지정합니다.

6. href="#"

  • href="#"는 임시 링크를 의미합니다.
  • #은 현재 페이지를 가리키는 빈 링크입니다.
  • 나중에 링크 주소를 넣기 전까지 임시로 사용됩니다.

정리된 예시 코드

<a href="#" class="btn btn-primary">View Details</a>
  • <a>: 하이퍼링크를 의미합니다.
  • href="#": 임시 링크입니다.
  • class="btn btn-primary": Bootstrap 클래스입니다.
    • btn: 버튼 스타일을 적용합니다.
    • btn-primary: 주요 버튼(파란색 버튼) 스타일을 적용합니다.
  • View Details: 버튼에 표시되는 텍스트입니다.

이제, View Details 버튼을 누르면 페이지가 넘어가도록 해보자.

경로를 연결해줄 것. 그리고 버튼의 크기는 조금 작게.

 

<a th:href="@{/detail/{id}(id=${book.id})}" class="btn btn-primary btn-sm">View Details</a>

 

th:href와 href 차이점

  • href: 정적인 URL을 그대로 사용합니다. 서버에서 변환 없이 그대로 브라우저로 전달됩니다.
<a href="/detail/1">View Details</a>
  • th:href: Thymeleaf의 속성입니다. 동적인 URL을 생성합니다.
    • 변수나 경로 매핑을 통해 서버에서 데이터에 맞는 URL로 변환됩니다.
    • 예를 들어 {id} 부분이 Spring Controller에서 전달받은 데이터로 동적으로 바뀝니다.

예시

<a th:href="@{/detail/{id}(id=${book.id})}">View Details</a>
  • ${book.id}: book 객체의 id 값을 가져옵니다.
  • @{/detail/{id}(id=${book.id})}:
    • /detail/{id}에서 {id}는 경로 변수입니다.
    • (id=${book.id}) 부분에서 {id}를 실제 값으로 대체합니다.
    • book.id가 1이라면 결과적으로 /detail/1로 변환됩니다.

3. @ 기호의 의미

@ 기호는 Thymeleaf의 URL 표현식입니다.

  • **@{}**를 사용하면 컨텍스트 경로(Context Path)를 자동으로 포함한 URL을 생성합니다.
  • 컨텍스트 경로란 웹 애플리케이션의 기본 경로입니다. (예: http://localhost:8080/)
  • 만약 애플리케이션의 경로가 /myapp이라면, @{/detail/1}은 자동으로 /myapp/detail/1로 변환됩니다.

예시

  1. 정적 URL:
    • 브라우저에 그대로 전달되며, 컨텍스트 경로를 고려하지 않습니다.
<a href="/detail/1">View Details</a>
  1. 동적 URL (Thymeleaf):
    • Thymeleaf가 서버에서 데이터를 채워 넣어 /detail/1로 변환됩니다.
    • 컨텍스트 경로를 자동으로 포함합니다.
<a th:href="@{/detail/{id}(id=${book.id})}">View Details</a>

4. 정리

  • href: 정적인 URL만 사용. 서버에서 데이터와 상관없이 URL이 고정됩니다.
  • th:href: Thymeleaf에서 사용되며, 동적으로 URL을 생성하고 데이터를 대체합니다.
  • @: Thymeleaf의 URL 표현식으로, 경로 변수와 컨텍스트 경로를 포함한 동적 URL을 만들 때 사용합니다.
지금은 경로 변수가 id 1개 인데, 경로 변수가 2개 이상 일수도 있어?
경로 변수가 2개 이상일 수도 있습니다. ThymeleafSpring Boot를 사용할 때, 경로 변수 여러 개를 사용할 수 있고 이런 경우에도 동적으로 값을 전달할 수 있습니다.

경로 변수가 2개 이상인 경우

예를 들어, 두 개의 경로 변수 category와 id를 사용한다고 가정해 봅시다.

1. Thymeleaf 문법

경로 변수 여러 개를 사용하는 예시:

<a th:href="@{/detail/{category}/{id}(category=${book.category}, id=${book.id})}" 
   class="btn btn-primary btn-sm">
   View Details
</a>

설명:

  • /detail/{category}/{id}: 경로에 두 개의 변수를 선언합니다.
  • (category=${book.category}, id=${book.id}):
    • {category}에 book.category 값을 넣습니다.
    • {id}에 book.id 값을 넣습니다.
  • Thymeleaf가 서버에서 이 값을 동적으로 바꿔줍니다.

2. 컨트롤러에서의 설정

Spring Boot 컨트롤러에서 경로 변수 2개를 처리하는 코드 예시:

@GetMapping("/detail/{category}/{id}")
public String getDetails(@PathVariable String category, @PathVariable Long id, Model model) {
    // category와 id 값이 경로에서 전달됨
    model.addAttribute("category", category);
    model.addAttribute("id", id);
    // 필요한 로직 수행
    return "details";
}

3. 정리

  • 경로 변수는 여러 개를 사용할 수 있습니다.
  • Thymeleaf에서는 @{/path/{var1}/{var2}(var1=${value1}, var2=${value2})} 문법으로 여러 경로 변수를 처리합니다.
  • Spring Boot 컨트롤러에서는 @PathVariable을 여러 개 선언하여 값을 받을 수 있습니다.

 


아직 컨트롤러에서의 설정은 작성하지 않았지만,

run 을 해서 버튼 클릭하면 페이지가 넘어가는지만 확인해보자.

/detail/1

이라고 뜨는 걸 확인했다.

이제 mapping 을 해줘야 할 것.

어쨌든, 버튼을 클릭한다는 건, 클라이언트의 요청이 발생한다는 것이다.

클라이언트는 /detail/{id} 이라는 요청을 한 것이 된다.

클라이언트의 요청을 가장 먼저 받아서 처리하는 건, Controller, 그러니까 BookController로 가보자.

@GetMapping("/detail/{id}")

  • 역할: 이 메서드가 HTTP GET 요청을 처리하도록 지정하는 어노테이션입니다.
  • 경로: "/detail/{id}" 경로를 요청했을 때 이 메서드가 실행됩니다.
  • 중괄호 {}:
    • **{id}**는 경로 변수로, 요청 URL에서 동적으로 값을 받겠다는 의미입니다.
    • 예를 들어 /detail/1로 요청하면, {id}에는 1이 들어갑니다.

@PathVariable Long id

  • @PathVariable: URL 경로의 {id} 값을 메서드 파라미터인 id에 전달하는 어노테이션입니다.
    • 예: /detail/10 → id 변수에는 10이 들어갑니다.
  • Long: id의 자료형입니다. 책의 식별자가 Long 타입임을 의미합니다.

Model model

  • Model 객체:
    • Spring MVC에서 View와 데이터를 연결하는 객체입니다.
    • model.addAttribute("key", value)를 사용해서 데이터를 View에 전달합니다.

model.addAttribute("book", book);

  • 역할: 데이터를 View에 전달합니다.
  • "book":
    • Key입니다. View에서 이 Key로 데이터를 참조할 수 있습니다.
  • book:
    • Value입니다. Book 객체를 전달합니다.

View에서 데이터 참조 예시

View 파일 (detail.html)에서 데이터를 표시할 때:

<p>Book Title: <span th:text="${book.title}"></span></p>
  • ${book}: model.addAttribute에서 전달된 Book 객체입니다.

else { return "redirect:/"; }

redirect:/

  • redirect:: 다른 URL로 리다이렉트하도록 지시하는 키워드입니다.
  • /: 애플리케이션의 루트 경로입니다.
  • 만약 책이 존재하지 않는다면 메인 페이지로 이동하게 됩니다.

최종 흐름 요약

  1. HTTP GET 요청이 /detail/{id}로 들어옵니다.
  2. id 값을 @PathVariable을 통해 메서드에 전달합니다.
  3. bookService.getById(id)를 통해 책 정보를 조회합니다.
  4. 조회된 결과가 존재하면:
    • Book 객체를 model에 추가 (addAttribute).
    • detail View로 이동 (렌더링).
  5. 조회된 결과가 없으면:
    • 메인 페이지 (/)로 리다이렉트합니다.

요약

이 코드는 Spring Boot의 MVC 패턴에서:

  1. GET 요청을 처리하고,
  2. Service에서 데이터를 조회하며,
  3. Model을 통해 데이터를 View에 전달하거나,
  4. 필요 시 리다이렉트하는 역할을 수행합니다.

이제 detail.html 을 만들어야 한다.

여기서 부터는 다음 게시물에서.