백엔드/Spring Boot

7. 블로그 화면 구성하기 (2) - 블로그 글 목록 뷰 구현하기

두개의 문 2023. 8. 4. 17:05

◎ 컨트롤러의 메서드 생성 → 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