프로젝트 개요 : Jump to SpringBoot 클론코딩 - 회원제 QnA 게시판 웹
프로젝트 환경 : IntelliJ, SpringBoot, JPA, H2
프로젝트 코드 : https://github.com/smkim9202/sbb
URL과 타임리프 매핑하기
Controller 생성
매핑 할 URL : /question/list
@ResponseBody 사용하여 타임리프와 매핑하기 전까지 404오류를 방지한다.
파일명: QuestionController.java
package com.mysite.sbb.question;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class QuestionController {
@RequestMapping("/question/list")
@ResponseBody
public String list() {
return "question list";
}
}
템플릿 설정하기
템플릿이란?
자바 코드를 삽입할 수 있는 HTML 형식의 파일이다.
템플릿엔진을 사용하면 서버에서 HTML을 랜더링 하여 동적으로 바꿔준다. JSP, PHP등도 템플릿엔진이다.
스프링부트에서 사용 할 수 있는 엔진으로 Thymeleaf, Mustache, Groovy, Freemarker, Velocity 등이 있다.
그 중 스프링 진영에서 추천하는 Thymeleaf 템플릿 엔진을 사용해보겠다.
- 타임리프 - https://www.thymeleaf.org/
타임리프 설치
그레이들로 타임리프 사용하기 위한 라이브러리를 설치한다.
템플릿 엔진 적용하기 위해서는 라이브러리 설치 후 로컬서버 재시작이 필요하다.
파일명: build.gradle
dependencies {
(... 생략 ...)
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
}
템플릿 사용하기
타임리프 작성
파일명: 프로젝트명/src/main/resources/templates/quetion_list.html
<h2>Hello Template</h2>
Controller 매핑
파일명: QuestionController.java
package com.mysite.sbb.question;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class QuestionController {
@RequestMapping("/question/list")
//@ResponseBody //템플릿 사용하기 때문에 삭제
public String list() {
return "question_list"; //템플릿파일명 리턴
}
}
데이터 조회하여 템플릿에 전달하기
템플릿에 DB 저장된 데이터를 조회하여 전달하기.
파일명: QuestionController.java
package com.mysite.sbb.question;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor //questionRepository 속성을 포함하는 생성자를 생성한다 => 의존성 주입
@Controller
public class QuestionController {
private final QuestionRepository questionRepository;
@RequestMapping("/question/list")
public String list(Model model) {
//Model 클래스 사용하여 데이터 전달
//Model 객체는 따로 생성 할 필요 없이 메서드의 매개변수 지정하면 자동으로 객체 생성해줌
List<Question> questionList = this.questionRepository.findAll();
model.addAttribute("questionList", questionList);
//model에 "questionList"라는 이름으로 값을 저장해서 템플릿에서 그 값을 사용한다.
return "question_list";
}
}
스프링의 의존성 주입(Dependency Injection) 방식 3가지
@Autowired : @Controller, @Service 같이 스프링이 관리하는 객체에서만 동작한다. 빈으로 등록하지 않은 내가 직접 생성한 객체에서는 동작하지 않는다.
- 필드 주입 : 필드에 @Autowired 주입
- setter 주입 : setter메서드 작성 후 @Autowired 애너테이션 적용
- 생성자 주입 : 생성자를 작성하여 객체를 주입
=>의존관계 설정중에 동적으로 변하는 경우는 거의 없으므로 생성자주입 권장
템플릿에서 전달받은 데이터 사용하기
Model 객체에 저장 한 DB 조회한 데이터 값을 템플릿에서 사용하기.
파일명: 프로젝트명/src/main/resources/templates/quetion_list.html
<table>
<thead>
<tr>
<th>제목</th>
<th>작성일시</th>
</tr>
</thead>
<tbody>
<tr th:each="question : ${questionList}">
//th:each : <tr> 엘리먼트를 questionList갯수만큼 반복 출력 하는 역할
//for each문을 떠올리면 쉽게 이해 가능
<td th:text="${question.subject}"></td>
<td th:text="${question.createDate}"></td>
//th:text="${데이터}" : for문에서 얻은 데이터를 <td> 엘리먼트의 텍스트로 출력
</tr>
</tbody>
</table>
자주 사용하는 타임리프의 속성
1. 분기문 속성
th:if="${question != null}"
=> 객체가 null이 아닌 경우에만 해당 엘리먼트가 표시
2. 반복문 속성 : 반복횟수만큼 해당 엘리먼트를 반복 표시
th:each="question" : ${questionList}
=> for each문과 유사
th:each="question, loop : ${questionList}"
=> loop 객체를 이용하여 루프 내에서 다양한 속성을 사용
- loop.index - 반복 순서, 0부터 1씩 증가
- loop.count - 반복 순서, 1부터 1씩 증가
- loop.size - 반복 객체의 요소 갯수 (예: questionList의 요소 갯수)
- loop.first - 루프의 첫번째 순서인 경우 true
- loop.last - 루프의 마지막 순서인 경우 true
- loop.odd - 루프의 홀수번째 순서인 경우 true
- loop.even - 루프의 짝수번째 순서인 경우 true
- loop.current - 현재 대입된 객체 (예: 위의 경우 question과 동일)
3. 텍스트 속성
th:text="${값}"
=> 해당 엘리먼트의 텍스트 "값"을 출력
[[${값}]]
=> th:text= 부분을 대괄호로 바꿔서도 사용가능하다
ROOT URL 설정하기
루트 URL : 'http://localhost:8080'처럼 도메인명과 포트 뒤에 아무것도 붙이지 않는 URL
ROOT URL을 다른 URL로 넘기기
파일명: MainController.java
package com.mysite.sbb;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class MainController {
@RequestMapping("/") //루트 URL은 "/"으로 매핑
public String root() {
return "redirect:/question/list"; //루트URL과 연결할 템플릿 redirect
}
}
- redirect:<URL> : URL로 리다이렉트(완전히 새로운 URL로 요청)
- forward:<URL> : URL로 포워드(기존 요청 값들이 유지된 상태로 URL 전환)
'프로젝트 > clone coding' 카테고리의 다른 글
[Jump to SpringBoot : SBB] 스프링부트 windows cmd창으로 빌드하고 실행 (0) | 2022.04.21 |
---|---|
[Jump to SpringBoot : SBB] 서비스와 DTO (0) | 2022.04.20 |
[Jump to SpringBoot : SBB] JpaRepository 상속 받은 Repository 테스트해보기(+JUnit 프레임워크) (0) | 2022.04.19 |
[Jump to SpringBoot : SBB] SpringBoot 기본 요소(Controller, JPA, Entity, Repository) (0) | 2022.04.19 |
[Jump to SpringBoot : SBB] IntelliJ에서 SpringBoot 사용하기 (0) | 2022.04.18 |