◎ 컨트롤러의 메서드 생성 → HTML 뷰 생성 → 뷰 테스트 순서로 진행
※ 뷰 생성 시 주의 사항
- 서버에 있는 데이터를 가져올 때, 오타 주의 ( 오타 날 경우, 무조건 500 에러 발생 )
- 뷰 템플릿 페이지는 서버 쪽 모델 데이터가 중요
→ 우선적으로 데이터 값이 제대로 출력되는지 먼저 확인하여 500 에러가 발생할 확률을 줄이도록 하자!
1. 컨트롤러 메서드 작성하기
- 뷰 컨트롤러 메서드 : 뷰의 이름을 반환하고, 모델 객체에 값을 담음
1) 뷰에게 데이터를 전달하기 위한 객체 생성
▪︎ ArticleListViewResponse : 모든 게시글 목록을 요청 시, 필요한 DTO 클래스
▪︎ ArticleListViewResponse.java ( dto 패키지 )
package org.choongang.ewha.hithymeleaf.dto;
import lombok.Getter;
@Getter
public class ArticleListViewResponse {
// 변수 선언
private final Long id;
private final String title;
private final String content;
// 생성자
public ArticleListViewResponse(Article article) {
this.id = article.getId();
this.title = article.getTitle();
this.content = article.getContent();
}
}
2) 블로그 글 전체 리스트를 담은 뷰를 반환
▪︎ BlogViewController.java ( controller 패키지 )
- '/articles' GET 요청을 처리할 코드 작성
→ 블로그 글 전체 리스트를 담은 뷰를 반환
package org.choongang.ewha.hithymeleaf.controller;
import java.util.List;
import org.choongang.ewha.hithymeleaf.domain.Article;
import org.choongang.ewha.hithymeleaf.dto.ArticleListViewResponse;
import org.choongang.ewha.hithymeleaf.dto.ArticleViewResponse;
import org.choongang.ewha.hithymeleaf.service.BlogService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@RequiredArgsConstructor
@Controller
@Slf4j
public class BlogViewController {
// * 데이터베이스와 작업할 서비스 객체 선언
// : 의존성 주입으로 스프링 컨테이너에 의해 객체 생성
// * 의존성 주입을 요청하는 방법
// 1) @Autowired
// 2) @Resource
// 3) @Inject
// 4) @Lombok
// * Lombok의 필수 파라미터 생성자 자동생성 주석을 이용한 방법
// : @Autowired, @Lombok의 방법 이용
// lombok의 방법은 의존성 주입을 할 객체가 상수객체로 처리하려는 경우가 많음
// private final로 선언하고 @RequiredArgsConstructor 주석을 선언하는 방법
private final BlogService blogService;
@GetMapping("/articles")
// 반환타입 : String일 경우, 뷰 이름 지정 가능
// 반환타입 : void일 경우, 뷰 이름은 요청주소와 일치해야 함
public String getArticles(Model model) {
// * 컨트롤러 → 서비스 (요청 의뢰) : 데이터베이스와 작업하여 목록 레코드를 가져오도록 요청
// * 아래 필기 참고
List<ArticleListViewResponse> articles
= blogService.findAll().stream()
.map(ArticleListViewResponse::new)
.toList();
// * 블로그 글 리스트 저장
model.addAttribute("articles", articles);
return "articleList"; // articleList.html라는 뷰 조회
}
• 스트림 사용
❶ blogService.findAll() : blogService를 이용하여 모든 레코드를 가져옴 → 반환 타입 : List 형태
public List<Article> findAll(){
return blogRepository.findAll();
}
❷ 컬렉션의 최고 조상인 Collection에 stream()이 정의되어 있음
Stream<E> stream() // Collection 인터페이스의 메서드
- Collection의 자손인 List와 Set을 구현한 컬렉션 클래스들은 모두 이 메서드로 스트림 생성 가능
→ stream() : 해당 컬렉션을 소스로 하는 스트림을 반환
❸ 스트림의 중간연산인 map() 메서드를 이용한 데이터 처리
• map() 메서드 : 스트림의 요소에 저장된 값 중에서 원하는 필드만 뽑아내거나, 특정 형태로 변환해야 할 때 사용 ( 현재는 후자 )
• 생성자의 메서드 참조
- 헷갈릴 경우, 아래와 같이 메서드 참조를 람다식으로 바꿔 생각해보자
// 생성자의 메서드 참조
map(ArticleListViewResponse::new)
// 람다식으로 변경
map((Article article) -> new ArticleListViewResponse(article))
❹ 스트림의 최종 연산 : 스트림을 List 타입으로 반환
- toList() : 최종 결과를 모아 List 타입으로 반환
• 아래 코드와 동일
List<ArticleListViewResponse> articleListViewResponseList = new ArrayList<>();
for(Article article : articleList) {
articleListViewResponseList.add(new ArticleListViewResponse(article));
}
- ArticleListViewResponse : 모든 게시글 목록을 요청 시, 필요한 DTO 클래스
→ 이 클래스 목록을 응답 시, 반환하는 메서드 : List를 초기화한 후, 위의 리스트에 article 객체를 이용해 응답리스트를 추가함
• model.attribute( ) 메서드를 사용해 모델에 값을 저장
- "articles" key에 블로그 글들 즉, 글 리스트를 저장
2. HTML 뷰 만들고 테스트하기
1) 모델에 전달할 블로그 글 리스트 개수만큼 반복해 글 정보를 보여주는 뷰 생성
▪︎ articleList.html ( resource/templates )
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>블로그 글 목록</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
</head>
<body>
<!-- 헤더영역 : 제목표시 -->
<div class="p-5 mb-5 text-center</> bg-light">
<h1 class="mb-3">My Blog</h1>
<h4 class="mb-3">블로그에 오신 것을 환영합니다!</h4>
</div>
<!-- 컨테이너 영역 : 컨텐츠 -->
<div class="container">
<div class="row-6" th:each="item : ${articles}"><!-- article 개수만큼 반복 -->
<!-- 한 개의 블로그 article 내용 -->
<div class="card">
<!-- item의 id 출력 -->
<div class="card-header" th:text="${item.id}">
</div>
<div class="card-body">
<!-- item의 title 출력 -->
<h5 class="card-title" th:text="${item.title}"></h5>
<!-- item의 text 출력 -->
<p class="card-text" th:text="${item.content}"></p>
<a href="#" class="btn btn-primary">보러 가기</a>
</div>
</div>
<br />
</div>
</div>
<!-- 푸터 영역(꼬리말) -> 현재 없음 -->
<div>
</div>
</body>
</html>
• bootstrap ( 부트스트랩 )
- 반응형이며, 웹 프로젝트 개발을 위한 인기있는 HTML, CSS, JS 프레임 워크
① 구글에서 'bootstrapcdn' 검색 → 아래의 홈페이지 클릭

② v4.6.2 버전의 HTML 코드를 클릭하면 복사됨

③ 복사된 코드를 html 파일의 <titie> 태그 아래에 붙여넣으면 사용 준비 완료!
📍 현재 코드에서 나온 부트스트랩 내용 정리 ( 추후 부트스트랩에 대해 정리 )
p-5 | padding의 비율 설정 |
mb-3 | margin : border를 기준으로 박스의 여백을 지정 |
text-center | 가운데 정렬 |
text-center</> | 왼쪽 정렬 |
bg-light | background 밝게 설정 |
2) 'localhost/articles'로 접속해보면, 아래와 같이 뷰가 출력됨

'백엔드 > Spring Boot' 카테고리의 다른 글
7. 블로그 화면 구성하기 (3) - 블로그 글 구현하기 (0) | 2023.08.08 |
---|---|
외부 파일 import 방법 (0) | 2023.08.08 |
타임리프 (0) | 2023.08.04 |
Thymeleaf (0) | 2023.08.02 |
7. 블로그 화면 구성하기 (1) - 타임리프 (0) | 2023.08.02 |