보통 api 응답으로는 json 형식을 리턴하는것이 일반적이고 바람직한 방식이라고 생각한다. 그러나 가끔 html을 이용해야 할 때가 있다. (예 : 가입환영 이메일, 비밀번호 확인 이메일 등)
특정 API로 해당 요청을 받음 -> DB 에서 해당 내역 조회 -> 템플릿으로 DB 내용을 담아 전달 의 프로세스가 필요할 때가 있다. 참고로 오브젝트를 리턴하면 Json으로 변환하여 리턴하게 된다
템플릿을 이용하기 위해 보통 타임리프 라이브러리를 사용한다. 다음의 순서로 동작한다
***코틀린을 이용하여 VSCode 에서 구동시 ./gradlew bootrun 으로 실행해야 한다.
- build.gradle 설치
- resource 폴더 -> templates 폴더 -> html 파일 추가
- Controller 클래스 함수에서 url 매핑
- 매핑된 함수에서 Model 클래스를 이용하여 전달할 내용 담아주기
- 매핑된 함수에서 추가한 html 파일을 응답으로 리턴
- 설치
- build.gradle 에 다음을 추가한다.
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
- 템플릿 추가
- resource 폴더 -> templates 폴더에 원하는이름을 입력하여 html 파일을 추가한다.
- resource 폴더 -> templates 폴더에 원하는이름을 입력하여 html 파일을 추가한다.
- 템플릿 상속 (Fragment)
- 여러 템플릿 html 파일이 있을경우, 사실상 body를 제외하곤 중복되는 부분이 많다. HTML 기본구조가 같기 때문이다. 하나의 html에 중복되는 부분을 구현해 두고, 다른 템플릿에서는 이를 상속받아 body 부분만 변경 할 수 있다.
- resource 폴더 -> templates -> 부모가 될 html 을 추가한다.
- body 부분에 <th:block layout:fragment="childcontent"></th:block> 을 작성한다.
- 이 부분에 각 내용들이 삽입된다.
- childcontent 는 다른 문자열로 대체해도 된다. 단, 자식 html에서도 이름이 같아야 한다.
- 자식 템플릿 작성
- html 태그에 layout:decorate="~{부모html이름(확장자제외)}" 를 추가
- 부모 html에서 layout:fragment 설정한 부분이 될 태그의 어트리뷰트로 layout:fragment="childcontent" 를 입력
**부모 html
.....
<body>
...
<th:block layout:fragment="원하는명칭"></th:block>
...
</body>
**자식 html
<html layout:decorate="~{부모html이름(확장자제외)}">
<태그명 layout:fragment="원하는명칭" >
...
</태그명>
</html>
- 템플릿 치환
- 부모 템플릿을 상속 받는것과는 조금 다르게, 각 템플릿의 일부 태그를 타 템플릿의 내용으로 치환한다.
- 위에서 눈치 챘겠지만, Fragment 를 선언하고, 필요한 곳에서 해당 Fragment를 가져다 쓰는 방식이다.
- Fragment 작성 및 치환 예
**프레그먼트 설정
...
<태그명 th:fragment="원하는 이름" >
...
**프레그먼트 대치하는 쪽
...
<태그명 th:replace="~{대치할html이름(확장자제외)::위의fragment에서_설정한_이름}" >
...
- Model
- 스프링에서 자동으로 생성자를 생성해주는 클래스로, 다양한 값들을 담을 수 있다.
- addAttribute("이름", 입력할 값) 함수를 이용해 값을 넣는다.
- @ResponseBody 어노테이션을 삭제한다
-
import org.springframework.ui.Model 로 추가해야 한다.아래는 코틀린 예제이다.
package com.example.test1.test1
import org.springframework.ui.Model
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.ResponseBody
@Controller
public class test()
{
@GetMapping("/서브url주소")
fun Hello(model : Model) : String
{
var a = 10
//키값 명칭은 자유롭게 추가. html 에서 해당 명칭으로 값을 가져옴
model.addAttribute("키값명칭",a)
//templates 에 hello.html을 추가 했을경우 hello 리턴
return "hello"
}
}
- HTML 에서 Model 에 넣은 인자값 사용
- 어트리뷰트로 접근하여 사용 (텍스트인 경우)
-
th:text="${키값명칭}"또는 [[${키값명칭}]]
-
- 어트리뷰트로 접근하여 사용 (텍스트인 경우)
<h2 th:text="${test}"></h2>
//또는
<h2>[[${test}]]</h2>
- 타임리프 분기문
- th:if="${키값명칭 != null}"
<div th:if="${test != null}">
<p th:text="${test}">
</div>
- 타임리프 반복문
- foreach를 생각하면 된다
- th:each="item : ${키값명}"
<div th:each="item : ${test}">
<p th:text="${item}">
</div>
- 타임리프 반복문 2
- loop 를 추가 하여 index, count 등 값을 추출 할 수 있다.
- loop.index
- loop.count
- loop.size
- loop.current
- loop.odd
- loop.even 등등
- th:each="item, loop : ${키값명}"
- loop 를 추가 하여 index, count 등 값을 추출 할 수 있다.
- 타임리프 href
- @{ } 사이에 주소값을 넣는다.
- th:href=@"{/url주소/}"
- 만일 변수값과 같이 조합을 할 경우에는 || 로 감싸줘야 한다
- th:href=@"{|/url주소/${키값명}|}"
- @{ } 사이에 주소값을 넣는다.
'Backend > SpringBoot' 카테고리의 다른 글
Paging (0) | 2024.10.24 |
---|---|
[기본구조4] 서비스 (0) | 2024.10.23 |
의존성 주입 (0) | 2024.10.23 |
[기본구조3] Repository with JPA (DB CRUD동작,Interface, findby) (0) | 2024.10.23 |
[기본구조2] JPA 초기 설정 (DB 관리) 및 Entity 예제(validation 포함) (0) | 2024.10.22 |