์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

[JPA] Mustache ๋ž€ ๋ญ˜๊นŒ?

๋ฏธ๋กœ910 2024. 10. 4. 10:01
๐Ÿ’ก
1. Mustache์— ๋Œ€ํ•ด ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.
2. Mustache ๊ธฐ๋ณธ ๋ฌธ๋ฒ•์„ ํ™•์ธํ•ด ๋ณด์ž.

Mustache๋Š” ๊ฑฐ์˜ ๋กœ์ง์ด ์—†๋Š” ํ…œํ”Œ๋ฆฟ ์—”์ง„์œผ๋กœ, ๋‹ค์–‘ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ฐ„๋‹จํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•œ ํ…œํ”Œ๋ฆฟ์„ ๋งŒ๋“œ๋Š” ๋ฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. Spring Boot์™€ Mustache๋ฅผ ๊ฒฐํ•ฉํ•จ์œผ๋กœ์จ ๊ฐœ๋ฐœ์ž๋Š” ๋ฐฑ์—”๋“œ ๋กœ์ง๊ณผ ํ”„๋ก ํŠธ์—”๋“œ ํ‘œํ˜„์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๋” ํšจ์œจ์ ์ด๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฌ์šด ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Mustache์˜ ์ฃผ์š” ํŠน์ง•

  • ๋กœ์ง์„ ์ตœ์†Œํ™”ํ•œ ํ…œํ”Œ๋ฆฟ(Logic-less templates): Mustache ํ…œํ”Œ๋ฆฟ์€ ๋ณต์žกํ•œ ๋กœ์ง์„ ์ตœ์†Œํ™”ํ•˜์—ฌ, ํ…œํ”Œ๋ฆฟ ๋‚ด์—์„œ ๊ฐ„๋‹จํ•œ ์กฐ๊ฑด๋ฌธ๊ณผ ๋ฐ˜๋ณต๋ฌธ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฐ์— ์ง‘์ค‘ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

{{#users}}...{{/users}}๋Š” users ๋ชฉ๋ก์— ๋Œ€ํ•œ ๋ฐ˜๋ณต์„, {{^users}}...{{/users}}๋Š” users๊ฐ€ ๋น„์–ด ์žˆ์„ ๋•Œ์˜ ์ฒ˜๋ฆฌ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

if๋ฌธ ์‚ฌ์šฉX

  • ์–ธ์–ด ๋…๋ฆฝ์„ฑ(Language agnostic): Mustache๋Š” JavaScript, Java, Python ๋“ฑ ๋‹ค์–‘ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ฐ„๋‹จํ•จ(Simplicity): ํ…œํ”Œ๋ฆฟ์˜ ๊ตฌ์กฐ๊ฐ€ ๋‹จ์ˆœํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

 

Spring Boot์™€ Mustache ์˜ ์‚ฌ์šฉ

Spring Boot์—์„œ Mustache๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด, ๋จผ์ € spring-boot-starter-mustache ์˜์กด์„ฑ์„ ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์Šคํƒ€ํ„ฐ๋Š” Mustache ํ…œํ”Œ๋ฆฟ ์—”์ง„๊ณผ ๊ด€๋ จ๋œ ๋ชจ๋“  ํ•„์š”ํ•œ ์˜์กด์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ํ›„, src/main/resources/templates ๋””๋ ‰ํ† ๋ฆฌ์— Mustache ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ์„ ์œ„์น˜์‹œํ‚ค๊ณ , Spring MVC ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ†ตํ•ด ๋ชจ๋ธ ๋ฐ์ดํ„ฐ๋ฅผ ํ…œํ”Œ๋ฆฟ์— ์ „๋‹ฌํ•˜์—ฌ ๋™์ ์ธ ์›น ํŽ˜์ด์ง€๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

application-dev.yml  ์ถ”๊ฐ€
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-mustache'
    // ...
}

 

SampleController
package com.example.demo._domain.blog.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;


@Controller
public class SampleController {
	
	// ์ฃผ์†Œ ์„ค๊ณ„ : http://localhost:8080/	(GET) ์š”์ฒญ
	@GetMapping("/")
	public String home(Model model) {
		
		// ๋ทฐ ๋ฆฌ์กธ๋ธŒ ๋™์ž‘
		// hello --> src/main/resources/templates/hello.mustache
		model.addAttribute("name", "ํ•œ๊ธ€ ์„ค์ •");
		return "hello";
	}

}

 

hello.mustache ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ์€ src/main/resources/templates ๋””๋ ‰ํ† ๋ฆฌ์— ์œ„์น˜ํ•ด์•ผ ํ•˜๋ฉฐ, ์ด ํŒŒ์ผ์€ Mustache ํ…œํ”Œ๋ฆฟ ์–ธ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ "Hello, World!" ์˜ˆ์ œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ hello.mustache ํŒŒ์ผ์˜ ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค

hello.mustache
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>Hello, {{name}}</h1>
</body>
</html>

(.html  -> .mustache)

์‹คํ–‰ ํ™”๋ฉด______



Model ๋ง๊ณ  ์“ธ ์ˆ˜ ์žˆ๋Š” ๊ฒŒ ์—†์„๊นŒ?

package com.example.demo._domain.blog.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import jakarta.servlet.http.HttpServletRequest;


@Controller
public class SampleController {
	
	// ์ฃผ์†Œ ์„ค๊ณ„ : http://localhost:8080/	(GET) ์š”์ฒญ
	@GetMapping("/")
	public String home(HttpServletRequest request) {
		
		// ๋ทฐ ๋ฆฌ์กธ๋ธŒ ๋™์ž‘
		request.setAttribute("name", "๋ฐ˜๊ฐ€์›Œ");
		// hello --> src/main/resources/templates/hello.mustache
		// model.addAttribute("name", "ํ•œ๊ธ€ ์„ค์ •");
		return "hello";
	}

}

โžก๏ธ request๋กœ ํ•  ์ˆ˜ ์žˆ๋‹ค.

spring:
  mustache:
    servlet:
      expose-session-attributes: true  # Mustache ํ…œํ”Œ๋ฆฟ์—์„œ ์„ธ์…˜ ์†์„ฑ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉ
      expose-request-attributes: true  # Mustache ํ…œํ”Œ๋ฆฟ์—์„œ ์š”์ฒญ ์†์„ฑ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉ

 

์‹คํ–‰ ํ™”๋ฉด____