<< Back
blog 스프링프레임워크

스프링프레임워크 :: 4.스프링부트 웹프로그래밍 Part2




타임리프(Thymeleaf)

타임리프(Thymeleaf) 자체가 생소 할 수 있습니다만 뷰 템플릿의 구성이 데이터를 표현하기 위한 EL(Expression Language)과 조건체크, 반복 등의 작업을 수행하기 위한 태그라이브러리 혹은 이에 준하는 다른 구성요소로 이루어진다는 구조적 특징만 이해 한다면 배우는 것은 크게 어렵지 않습니다. 특히 스프링 프레임워크와 연동이 수월환 장점이 있어 많은 스프링 프레임워크 기반 프로젝트에서 타임리프를 사용하고 있습니다. 타임리프와 관련한 자세한 정보는 https://www.thymeleaf.org 에서 살펴볼 수 있습니다.

시작하기

Part-1 에서는 스프링 프레임워크를 이용해 Rest Controller 를 구현해 보았으며 Part-2 에서는 MVC 패턴을 가지는 일반적인 웹 어플리케이션 개발을 살펴보게 됩니다.

예전에는 주로 JSP를 뷰 템플릿으로 많이 사용 하였으나 JSP 의 커스텀 태그나 이를 이용한 JSTL, JSP 액션태그 등을 사용함으로써 웹페이지 자체의 독리적인 개발이나 테스트등이 어려워지는 문제가 있었습니다.

또한 최근에는 서버사이드 렌더링이 아닌 클라이언트 렌더링 중심의 프론트엔드 기반 개발도 확대되고 있으며 REST 기반 개발이 보편화 되면서 JSP 의 사용이 예전만큼 필수적인 요소가 되지 못하고 있습니다.

스프링 프레임워크의 경우에는 자바 기반 프레임워크 이지만 JSP에 대한 종속은 없으며 Thymeleaf, JSP, FreeMarker, Velocity 등 다양한 템플릿 엔진과의 연동을 지원하고 있습니다. JSP 사용은 별도의 설정이 필요하며 Thymeleaf 의 경우 pom.xml 에만 추가하면 별도의 설정 없이 사용할 수 있습니다.

DemoWebController 작성

MVC 웹 컨트롤러로 사용할 DemoWebController 클래스를 생성합니다. DemoRestController 와 마찬가지로 별도의 클래스 상속이나 인터페이스 구현 없는 일반 자바 클래스로 만들면 됩니다.

@Controller 애너테이션 추가

클래스 생성후 선언부 위에 다음과 같이 애너테이션을 추가 합니다.

@Controller
@RequestMapping("/web")
public class DemoWebController {	
}

테스트 메서드 등록

/web/hello GET 요청에 동작하는 메서드를 만들어 컨트롤러와 뷰 페이지의 연계 과정을 살펴 보도록 합니다.

@GetMapping("/hello")
public String hello(Model model) {
	model.addAttribute("msg", "Hello World");
	return "hello";
}

htllo.html 작성

resources/templates/ 폴더에 hello.html 파일을 만듭니다. 파일의 일반적인 html5 구조를 가지고 있습니다. 타임리프의 제어문이나 조건등을 지정하는 속성은 th:XXX 형식으로 사용하는데 이는 html5 표준 규격이 아니므로 다음과 같이 xmlns를 추가해 주어야 합니다.

여기서는 th 대신 data-th-XXX 와 같이 html5 표준 규격을 사용하므로 <html xmlns:th="http://www.thymeleaf.org"> 를 추가할 필요가 없다.

html 문서는 다음과 같이 작성 합니다.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>Hello Spring Boot Project</h2>
<hr>
MSG : <span data-th-text="${msg}">hello</span>
</body>
</html>

타임리프에서 사용하는 Expression 표기는 다음과 같은 종류가 있습니다.

Variable Expressions: ${...}
Selection Variable Expressions: *{...}
Message Expressions: #{...}
Link URL Expressions: @{...}
Fragment Expressions: ~{...}

실행 및 테스트

스프링 부트 앱을 실행하고 브라우저에서 http://localhost/web/hello 를 입력하도록 합니다.

get request

상품관리 웹 어플리케이션

DemoWebController 확장

이제 Part-1 에서 만들었던 Product 와 ProductManager 를 이용해 웹 어플리케이션을 작성해 봅니다. DemoWebController 에 다음과 같이 등록과 목록을 보여주기 위한 메서드를 추가 합니다.

@Autowired
ProductManager pm;

@GetMapping("/productlist")
public String getProducts(Model model) {
	model.addAttribute("products", pm.getDatas());
	return "product_list";
}

@PostMapping("/productadd")
public String addProduct(Product p) {
	pm.addProduct(p);
	return "redirect:/web/productlist";
}

product_list.html

상품목록을 보여주기 위한 html로 타임리프 html 이므로 /resources/templates 폴더에 있어야 합니다. 물론 서브폴더를 만들어도 됩니다.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>product_list.html</title>
</head>
<body>
<h2>Product List</h2>
<hr>
<a href="/product_form.html">New Product</a>

<table border=1>
<tr>
	<th>ID</th>
	<th>Product Name</th>
	<th>Price</th>
</tr>
<tr data-th-each="p : ${products}">
	<td data-th-text="${p.id}">1</td>
	<td data-th-text="${p.name}">Apple Iphone Xs</td>
	<td data-th-text="${p.price}">130000</td>
</tr>
</table>
</body>
</html>

product_form.html

상품을 등록하기 위한 html 로 별도의 데이터를 표현하지 않는 일반 html 입니다. 이경우 templates 폴더가 아닌 static 폴더에 둘 수 있습니다. 만일 하나의 양식으로 등록과 수정을 모두 처리하는 경우에는 당연히 templates 폴더에 두어야 한다. 이와 관련해서는 추후 다른 강좌에서 다시 다루도록 합니다.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>product_form.html</title>
</head>
<body>
<h2>New Product</h2>
<hr>
<form action="/web/productadd" method="post">
Name: <input type="text" name="name">
Price: <input type="text" name="price">
<button type="submit">Submit</button>
</form>
</body>
</html>

실행 및 결과 확인

먼저 목록을 확인합니다.

http://localhost:8080/web/productlist

get request

Add Product 링크를 클릭하면 다음과 같이 양식이 나옵니다. 입력양식에 내용을 작성하고 submit 버튼을 누르면 새로운 항목이 추가되고 다시 목록으로 이동해 추가된 내용을 함께 보여줍니다.

get request

get request

이것으로 기본적인 스프링 부트를 이용한 웹 어플리케이션 개발을 모두 살펴 보았습니다. 실제 프로젝트를 수행하기 위해서는 예제와 달리 다양한 요구사항을 처리해야 하기 때문에 웹 개발에 대한 풍부한 경험과 자료 수집 능력이 요구 됩니다. 강좌에서는 여러분들이 스프링프레임워크를 시작할 수 있도록 안내하는 것일뿐 스프링프레임워크를 제대로 사용하는 것은 쉽지 않은 일임을 명심하고 꾸준히 학습하기 바랍니다.
<< Back