일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 스프링 mvc
- 스프링 데이터 JPA
- 컬렉션 조회 최적화
- 스프링
- 페이징
- 예제 도메인 모델
- jpa 활용
- 타임리프 문법
- API 개발 고급
- JPA
- JPQL
- JPA 활용 2
- 로그인
- QueryDSL
- 프로젝트 환경설정
- 김영한
- 검증 애노테이션
- 값 타입 컬렉션
- 불변 객체
- Spring Data JPA
- 실무활용
- 벌크 연산
- 기본문법
- 트위터
- 타임리프
- 일론머스크
- Bean Validation
- 임베디드 타입
- JPA 활용2
- 스프링MVC
- Today
- Total
RE-Heat 개발자 일지
스프링 MVC 2편 - [1] 타임리프 - 기본기능(상편) 본문
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/dashboard
인프런 김영한님의 스프링 MVC 2편 강의를 토대로 정리한 내용입니다.
[1] 프로젝트 생성
Gradle 세팅
롬복세팅
[2] 타임리프 소개
타임리프 특징
- 서버 사이드 HTML 렌더링(SSR) : 타임리프는 백엔드 서버에서 HTML을 동적으로 렌더링하는 용도로 사용된다.
- 내추럴 템플릿 :
- 순수 HTML을 최대한 유지하려는 특성이 있어 웹 브라우저에서 파일을 직접 열어도 내용을 확인할 수 있다. 아울러 서버를 통해 뷰 템플릿을 거치면 동적으로 변경된 결과도 확인할 수 있어 협업에 유리하다.
- 반면 JSP는 파일 자체를 웹브라우저에서 열면 정상적인 HTML 결과를 확인할 수 없다.
- 스프링 통합 지원 : 스프링과 자연스럽게 통합돼 스프링의 다양한 기능을 활용할 수 있다.
기본 표현식
• 간단한 표현:
◦ 변수 표현식: ${...}
◦ 선택 변수 표현식: *{...}
◦ 메시지 표현식: #{...}
◦ 링크 URL 표현식: @{...}
◦ 조각 표현식: ~{...}
• 리터럴
◦ 텍스트: 'one text', 'Another one!',…
◦ 숫자: 0, 34, 3.0, 12.3,…
◦ 불린: true, false
◦ 널: null
◦ 리터럴 토큰: one, sometext, main,…
• 문자 연산:
◦ 문자 합치기: +
◦ 리터럴 대체: |The name is ${name}|
• 산술 연산:
◦ Binary operators: +, -, *, /, %
◦ Minus sign (unary operator): -
• 불린 연산:
◦ Binary operators: and, or
◦ Boolean negation (unary operator): !, not
• 비교와 동등:
◦ 비교: >, <, >=, <= (gt, lt, ge, le)
◦ 동등 연산: ==, != (eq, ne)
• 조건 연산:
◦ If-then: (if) ? (then)
◦ If-then-else: (if) ? (then) : (else)
◦ Default: (value) ?: (defaultvalue)
• 특별한 토큰:
◦ No-Operation:
[3] 텍스트 - text, utext
① HTML 태그의 속성에 기능을 정의해 동작한다.
형식 th:text
예) <span th:text=${data}">
② HTML 컨텐츠 영역 안에 직접 데이터 출력
형식 [[...]]
예) [[${data}]]
HTML 엔티티
- 개념 : HTML엔 예약된 몇몇 문자가 있으며(HTML 예약어) 이를 HTML 코드에서 사용하면 웹 브라우저는 충돌을 방지하기 위해 평소와는 다른 의미로 해석한다. 이를 위해 별도로 만든 문자셋을 엔티티라 부른다.
- 대표적인 엔티티 예시
Escape vs UnEscape
웹브라우저는 <, > 등을 부등호가 아닌 HTML 태그의 시작으로 인식한다. 따라서 HTML에서 사용하는 특수문자를 HTML 엔티티(<, >)로 변경해야 하고 이를 이스케이프(Escape)라 한다. 타임리프가 제공하는 th:text, [[...]]은 이스케이프가 기본값이다.
물론 때때로 Escape를 원하지 않을 때가 있다. 예를 들어 <b>태그를 이용해 Spring! 을 만들고 싶으면 어떻게 할까?
이럴 땐 th:text 대신 th:utext, [[...]] 대신 [(...)]을 쓰면 된다.
BasicController : text-unescaped
@GetMapping("text-unescaped")
public String textUnescaped(Model model){
model.addAttribute("data", "Hello <b>Spring!</b>");
return "basic/text-unescaped";
}
실행화면
참고]
Escape가 Default값인 이유 : 유저들은 글을 작성할 때 온갖 특수문자를 사용하며 이 탓에 자칫 잘못하면 HTML이 정상 렌더링되지 않는 문제가 발생한다. 따라서 타임리프에선 Escape가 기본이며 개발자도 꼭 필요할 때만 UnEscape를 사용해야 한다.
[4] 변수 - SpringEL
타임리프에서 변수를 사용할 때는 변수 표현식 ${...}을 사용한다.
그리고 변수 표현식에는 스프링 EL이라는 스프링이 제공하는 표현식을 사용할 수 있다.
=>[2] 타임리프 소개 중 특징인 스프링 통합지원과 연관
BasicController: variable
@GetMapping("/variable")
public String variable(Model model){
User userA = new User("userA", 10);
User userB = new User("userB", 20);
List<User> list = new ArrayList<>();
list.add(userA);
list.add(userB);
Map<String, User> map = new HashMap<>();
map.put("userA", userA);
map.put("userB", userB);
model.addAttribute("user", userA);
model.addAttribute("users", list);
model.addAttribute("userMap", map);
return "basic/variable";
}
@Data
static class User{
private String username;
private int age;
public User(String username, int age) {
this.username = username;
this.age = age;
}
}
① variable() Object, List, Map 관련 SpringEL 다양한 표현식 접근 위해 세팅
② User class도 추가
SpringEL의 다양한 표현식
- Object
◦ user.username : user의 username을 프로퍼티접근 == user.getUsername()
◦ user['username'] : 위와 같음 user.getUsername()
◦ user.getUsername() : user의 getUsername()을직접호출 - List
◦ users[0].username : List에서 첫 번째 회원을 찾고 username 프로퍼티 접근 == list.get(0).getUsername()
◦ users[0]['username'] : 위와 같음
◦ users[0].getUsername() : List에서 첫 번째 회원을 찾고 메서드 직접 호출 - Map
◦ userMap['userA'].username : Map에서 userA를 찾고, username 프로퍼티 접근 == map.get("userA").getUsername()
◦ userMap['userA']['username'] : 위와 같음
◦ userMap['userA'].getUsername() : Map에서 userA를 찾고 메서드 직접호출
지역변수 선언
th:with를 사용하면 지역 변수를 선언해 사용할 수 있다. 당연히 지역 변수는 선언한 태그 안(지역 스코프)에서만 사용할 수 있다.
실행화면 + variable.html
[5] 기본 객체들
타임리프가 제공하는 기본 객체
${#locale} : locale 헤더 정보 (언어·지역 설정)
${sesson} : HttpSession 객체 (http 세션 - 사용자 식별, 로그인 유지)
=> 브라우저 종료 전까지 로그인 상태 유지
${param} : HttpServletRequest 객체 (http 요청 메세지)
BasicController : basic-objects
@GetMapping("/basic-objects")
public String basicObjects(HttpSession session){
session.setAttribute("sessionData", "Hello Session");
return "basic/basic-objects";
}
기본 객체
주의] 스프링부트 3.0 버전 이후 ${#request}, ${#response}, ${#session}, ${#ServletContext}는 지원하지 않는다. 위 html의 코드는 스프링부트 3.0 이하 버전
여러 객체를 지원하지 않아서 생긴 문제점은
HTTP 요청 파라미터 접근 ${param} , HTTP 세션 접근 ${session} , 스프링 빈 접근 @ 등 편의 객체를 제공해 해결.
BasicController : helloBean
@Component("helloBean")
static class HelloBean{
public String hello(String data){
return "Hello " + data;
}
}
편의 객체
① URL에 paramData를 넣어주면 ${param}으로 쉽게 꺼내쓸 수 있다.
실제 URL
② session은 session.setAttribute()로 저장한 값 가져 옴.
③ spring bean은 @Component를 달아 스프링 빈으로 등록한 HelloBean의 return값 가져옴.
=> hello('Spring!') => return "Hello " + data(Spring!) => Hello Spring!
[6] 유틸리티 객체와 날짜
타임리프는 문자·숫자·날짜·URI 등을 편리하게 다루는 다양한 유틸리티 객체도 제공한다.
(필요할 때 매뉴얼에서 찾아 사용하는 게 좋다)
■ 타임리프 유틸리티 객체
#message : 메시지, 국제화처리
#uris : URI 이스케이프 지원
#dates : java.util.Date 서식 지원
#calendars : java.util.Calendar 서식 지원
#temporals : 자바8 날짜 서식지원
#numbers : 숫자 서식지원
#strings : 문자 관련편의기능
#objects : 객체 관련기능제공
#bools : boolean 관련기능 제공
#arrays : 배열 관련 기능제공
#lists , #sets , #maps : 컬렉션 관련 기능제공
#ids : 아이디처리 관련 기능제공
타임리프 유틸리티 객체
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#expression-utility-objects
유틸리티 객체 예시
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#appendix-b-expressionutility-objects
LocalDataTime 사용 예시
BasicController : date
@GetMapping("/date")
public String date(Model model){
model.addAttribute("localDateTime", LocalDateTime.now());
return "basic/date";
}
실제결과 - date.html
[7] URL 링크
타임리프에서 URL을 생성할 땐 @{...} 문법을 사용한다.
BasicController : link
@GetMapping("/link")
public String link(Model model){
model.addAttribute("param1", "data1");
model.addAttribute("param2", "data2");
return "basic/link";
}
실행결과 - link.html
① 단순한 URL
@{/hello} => http://localhost:8081/hello
② 쿼리 파라미터 :
@{/hello(param1=${param1}, param2=${param2})} => http://localhost:8081/hello?param1=data1¶m2=data2
()안에 있는 부분은 쿼리 파라미터로 대체된다.
③ 경로 변수
@{/hello/{param1}/{param2}(param1=${param1}, param2=${param2})} => /hello/data1?param2=data2
URL 경로상에 변수({param1}, {param2}}가 있으면 ()부분은 경로 변수로 처리된다.
④ 경로 변수 + 쿼리 파라미터
@{/hello/{param1}(param1=${param1}, param2=${param2})} => /hello/data1?param2=data2
경로 변수로 처리{parma1}하고 남은 나머지는 자동으로 쿼리파라미터로 붙는다.
[8] 리터럴
리터럴은 소스 코드상에 고정된 값을 말하는 용어다.
String a = "hello" int a = 10 * 20 |
hello는 문자 리터럴, 10, 20은 숫자 리터럴
타임리프 리터럴 종류
- 문자: 'hello'
- 숫자: 10
- 불리언: true , false
- null: null
① 타임 리프에서 문자리터럴은 ''작은따옴표로 감싸야한다.
<span th:text="'hello'">
② 하지만 공백 없이 쭉 이어진다면 하나의 의미 있는 토큰으로 인식해 작은따옴표를 생략할 수 있다.
<span th:text="hello">
잘못된 예
<span th:text="hello world!"></span> : hello world사이에 공백이 있어 하나의 토큰으로 인식되지 않음
<span th:text="'hello world!'"></span>처럼 작은따옴표로 감싸면 정상 동작한다.
BasicController : literal
@GetMapping("/literal")
public String literal(Model model){
model.addAttribute("data", "Spring!");
return "basic/literal";
}
실제 결과 - literal.html
[9] 연산
타임리프 연산은 JAVA와 흡사하다. 단, HTML 안에서 사용하기 때문에 HTML 엔티티를 사용하는 부분은 주의해야 한다.
BasicController : operation
@GetMapping("/operation")
public String operation(Model model){
model.addAttribute("nullData", null);
model.addAttribute("data", "Spring!");
return "basic/operation";
}
실제 결과 - operation.html
- 비교연산 : HTML 엔티티를 사용해야 하는 부분을 주의하자
- ! (not), == (eq), != (neq, ne), > (gt), < (lt), >= (ge), <= (le)
- 조건식 : 자바의 조건식과 유사
- Elvis 연산자 : 조건식의 편의 버전
예시 ] <span th:text="${data}?: '데이터가 없습니다.'"></span>
data가 있으면 data값을 출력, 없으면 '데이터가 없습니다.' 출력
true일 때 출력:false일 때 출력으로만 이루어진 느낌
No-Operation : _ 마치 타임리프가 실행되지 않는 것처럼 동작
<span th:text="${nullData}?: _">데이터가 없습니다.</span>
HTML의 내용 그대로 활용 가능. 다시 말해 th:text가 무효화돼 HTML 기본값이 출력된다고 보면 된다.
'백엔드 > 스프링' 카테고리의 다른 글
스프링 MVC 2편 - [2] 스프링 통합과 폼 (0) | 2023.07.12 |
---|---|
스프링 MVC 2편 - [1] 타임리프 - 기본기능(하편) (0) | 2023.07.09 |
스프링 MVC 1편 - [7] 웹 페이지 만들기 [하편] (0) | 2023.07.06 |
스프링 MVC 1편 - [7] 웹 페이지 만들기 [상편] (0) | 2023.07.05 |
스프링 MVC 1편 - [6] 기본 기능(하편) (0) | 2023.07.02 |