0118 Spring boot / thymeleaf
Spring boot
dev tools
lombok
web
thymeleaf
jap[mybatis 대체]
validation
oracle
security
따로 톰캣 연결 안함
1.Spring boot 모듈 생성
2.주입할 의존을 키워드로 검색 해서 선택가능.
3.구조
static : js css images
templates : html
static..단어 그대로 정적이란 뜻이다. 정적파일인 js css image들을 여기다 두면 된다.
반대로 동적인 파일은 웹페이지 등이 있다.
그리고 모듈 생성 후 , 클릭해보면 백지 상태인 application.properties라는 파일이 있는데
여기에 xml에 기술했던 설정들을 작성하면 된다.
확장자 명은 yml 이나 yaml을 사용하자.
주의할 점은 들여쓰기.
server-port 속성이므로 들여쓰기를 해야한다 만약
server:
port: 8080
이런식으로 작성하면 작동하지 않는다.
하단의 logging관련 설정도, 기본은 info이지만 com.sh.app 패키지에 한정해 debug 레벨부터 시작한다는 뜻.
#들여쓰기 주의 탭은 두개
#context-path 생략가능
#tomcat (container)
server:
port: 8080
servlet:
context-path: /spring
#logback(logging)
logging:
level:
root: info
com.sh.app: debug
4.예제
package com.sh.app;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* getMapping에 아무것도 없을 때 = switch의 default = 문자열반환
* @return
*/
@Controller
@Slf4j
public class HomeController {
@GetMapping
@ResponseBody //반환객체를 http응답메시지에 작성하라..
public String home()
{
return "hello world!🎮🎨";
}
}

Thymeleaf
-view template(뷰 템플릿)
-controller가 전달하는 데이터를 이용해 동적으로 화면을 구성해주는 역할.
-백엔드 서버에서 HTML을 동적으로 렌더링하는 용도로 사용한다.
-.html로 view작업을 진행한다.
1.Thymeleaf 모듈 생성
2.Thymeleaf 설정
application.yml
server:
port: 8080
servlet:
context-path: /thymeleaf
2.Thymeleaf 예제
-model
-modelmap
-modelandview
controller->view로 값을 전달할 때
model의 addAttribute 속성을 사용하면 된다.
기본:request에 저장
model.addAttribute("flag",new Random().nextBoolean());
model.addAttribute("greeting","hello, thymeleaf!");
model.addAttribute("num",new Random().nextInt(10)+1);
model.addAttribute("today", LocalDate.now());
model.addAttribute("nongdamgom",
User.builder()
.id(777L)
.username("nongdamgom")
.password("pw1234")
.name("담곰이")
.enabled(true)
.createdAt(LocalDateTime.now())
.build());
index.html
<title th:text="|Hello World!|">여기는안나와</title>
th:text가 우선순위가 높기 때문에 여기는안나와 텍스트는 출력되지 않고 Hello World!가 나온다.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title th:text="|Hello World!|"></title>
</head>
<body>
<h1 th:text="|띄어쓰기 하고싶으면 양쪽에 파이프라인을 붙이시오|"></h1>
<ul>
<li><a th:href="@{/basics.do?mode=kr&opt=red&opt=blue}" th:text="여기가우선순위">후순위</a></li>
<li><a th:href="@{/inline.do}" th:text="inline작성"></a></li>
<li><a th:href="@{/utilityObject.do}" th:text="utility객체"></a></li>
<li><a th:href="@{/fragment.do}" th:text="fragment"></a></li>
<li><a th:href="@{/layout.do}" th:text="Layout"></a></li>
</ul>
</body>
</html>
1)사용자 입력값
<li th:text="${param.mode}"></li>
<li th:text="${param.opt}"></li>
<li th:text="${param.opt[0]}"></li>
<li th:text="${param.opt[1]}"></li>
2)속성가져오기
el과 유사하게 ${attributreName}을 사용하면 된다.
속성을 가져올 때엔 ${attributreName.필드값} 이렇게 가져오면 된다.
jsp랑 다르게 여긴 자동완성까지 된다 신기함.
그리고 속성 문자열을 표현하고싶으면 시작과 끝에 파이프라인(|)을 붙여주면 된다. 그렇지 않으면 오류 발생
+
한가지 드는 의문점
nongdamgom의 id,name등은 private값인데 어떻게 접근할 수 있지?
마치 필드같지만 getter를 사용해 호출하는것.
ex)
필드 변수명은 irm인데 getName,setName인 경우엔 user.irm이 아니라 user.name을 사용해야한다는것
private String irm;
public String getName(){}
public String setName(String irm(){}
property 접근방식 : 객체를따라가며 찾는거
OGNL property(Object Graph Navigation Lang)
-el
-mybatis
-bean:property
-thymeleaf
<li th:text="${greeting}"></li>
<li th:text="${num}"></li>
<li th:text="${today}"></li>
<li th:text="${nongdamgom}"></li>
<li>
속성 가져오기1
<ul>
<li th:text="${nongdamgom.id}"></li>
<li th:text="${nongdamgom.username}"></li>
<li th:text="${nongdamgom.password}"></li>
<li th:text="${nongdamgom.name}"></li>
<li th:text="${nongdamgom.enabled}"></li>
<li th:text="${nongdamgom.createdAt}"></li>
</ul>
</li>
<li>
속성 문자열 표현
<ul>
<li th:text="|안녕하세요 ${nongdamgom.name} 입니당|"></li>
</ul>
</li>
아스타로 값 가져오기
nongdamgom에 대한 id, username (앞에 * 기호 붙이기)
<li th:object="${nongdamgom}">
속성 가져오기2
<ul>
<li th:text="*{id}"></li>
<li th:text="*{username}"></li>
<li>
<input type="checkbox" th:checked="*{enabled}">
</li>
</ul>
</li>
3)분기처리
el과 다르게 eq ne가 없어서 !=로 처리했다.
<h2>분기처리</h2>
<p th:if="${flag}" th:text="|flag가 true 입니다.|"></p>
<p th:unless="${flag}" th:text="|flag가 false 입니다.|"></p>
<p th:if="${nongdamgom != null}" th:text="|nongdamgom 존재하는 아이디 입니다|"></p>
<!--switch-->
<div th:switch="${num}">
<p th:case="1" th:text="|1을 뽑았습니다..|"></p>
<p th:case="2" th:text="|2을 뽑았습니다..|"></p>
<p th:case="3" th:text="|3을 뽑았습니다..|"></p>
<p th:case="4" th:text="|4을 뽑았습니다..|"></p>
<p th:case="*" th:text="|꽝을 뽑았습니다..|"></p>
<!--기본값은 * -->
</div>
4)반복처리
<h2>반복처리</h2>
<table>
<tr>
<th>no</th>
<th>id</th>
<th>username</th>
<th>name</th>
</tr>
<!-- 꺼냈을때 사용할 각각의 변수 :반복객체 -->
<!--
status
-index : 0 based index
-count : 1 based index
-first : 첫번째 요소 여부
-last : 마지막 요소 여부
-odd : 홀수 여부
-even : 짝수 여부
-size :크기[전체수]
index,count는 숫자타입이고 나머지는 boolean
-->
<tr th:each="user , status : ${users}" th:style="${status.odd}?'background-color:pink'">
<td th:text="${status.count}"></td>
<td th:text="${user.id}"></td>
<td th:text="${user.username}"></td>
<td th:text="${user.name}"></td>
</tr>
</table>
4)Utility Object
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Thymeleaf | Utility Object</title>
</head>
<body>
<a href="https://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html">
Basic Object | Utility Obejct</a>
<h1>Utility Object</h1>
<h2>#strings</h2>
<ul>
<li th:text="${#strings.isEmpty(name)}"></li>
<li th:text="${#strings.contains('홍')}"></li>
<li th:text="${#strings.startsWith('홍')}"></li>
<li th:text="${#strings.replace('홍','고')}"></li>
</ul>
<h2>#lists</h2>
</body>
</html>
5)Layout
th의 fragment : 재사용
->th include
layout의 fragment : 각 페이지마다 변하는것
->layout fragment
jsp에서 header / index / footer 로 영역을 나눈 것처럼 spring에서도 나눌 수 있다.
오늘 처음 익힌 방식이라 조금 헷갈리긴한데 익숙해진다면 jsp보다 활용도가 높을 것 같다.
아래는 page.html의 전체 구조다
<!DOCTYPE html>
<html
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/default}">
<style layout:fragment="style">
*{font-size:100px;}
*{background-color: cornflowerblue}
</style>
<div layout:fragment="content">
🐧🐧🐧🐧🐧🐧🐧🐧🐧
</div>
<script layout:fragment="script">
console.log('👻👻👻👻👻👻👻👻👻👻👻👻👻');
</script>
<!-- layout:decorate="~{layout/default}" 페이지 뼈대-->
내부에 스타일태그를 작성해서 간단하게 폰트사이즈랑 배경색을 설정했다.
content엔 펭귄 아이콘을 출력, console.log는 유령을 출력한다.
html 속성에 decorate는 이 페이지의 뼈대를 의미한다. layout디렉토리의 default.html을 확인해보자.
layout-default.html
문서의 구조를 잡는 html이다.
헤더-section(content)-푸터
<!DOCTYPE html>
<html
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 각 페이지의 style 태그로 대체 -->
<style layout:fragment="style"></style>
</head>
<body>
<div id="container">
<header th:include="~{fragments/header::header}"></header>
<section>
<!-- 각 페이지의 content 페이지로 대체되는 구역 -->
<div layout:fragment="content"></div>
</section>
<footer th:include="~{fragments/footer::footer}"></footer>
</div>
<!-- 각 페이지의 script로 대체-->
<script layout:fragment="script"></script>
</body>
</html>
<!--
문서의 구조를 잡는 html
-->
header
<!DOCTYPE html>
<html
xmlns:th="httP://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<header th:fragment="header">
<h2>Header</h2>
</header>
footer
<!DOCTYPE html>
<html
xmlns:th="httP://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<footer th:fragment="footer">
<h3>Footer</h3>
</footer>