앞에서 살펴본 JSP의 구조적 문제를 해결하기 위해 커스텀 태그를 기반으로 하는 JSTL/EL이 도입되었다.
<table>
<% for(type variable : variables)> { %>
<tr>
<td><%= variable.attribute1></td>
<td><%= variable.attribute2></td>
</tr>
<% } %>
</table>
이 코드는 아래와 같이 개선할 수 있다.
<table>
<c:forEach var="variable" items="${variables}">
<tr>
<td>${variable.attribute1}</td>
<td>${variable.attribute2}</td>
</tr>
</c:forEach>
</table>
<c:forEach> 태그는 반복문을 제공하는 JSTL 커스텀 태그이다.
${...}의 형태는 표현 언어로 Java 객체의 멤버 출력이 가능하다.
JSP보다 훨씬 구조적이고 가독성도 높아진 것을 확인할 수 있다. 이와 같은 프로그램 구조는 MVC 패턴과 함께 Servlet과 결합되어 오랫동안 Java 웹 개발의 정석으로 자리 잡아왔다.
단점은 화면 구조를 서버에서 빌드하는 구조이기 때문에 모든 실행이 서블릿 컨테이너를 통해야 한다는 점이다. 예시로 <c:forEach> 태그나 ${...}, <% %> 같은 JSP 구문은 클라이언트에서 해석할 수 없으므로 사소한 변경도 서버를 통해 실행되어야 한다.
이는 개발 생산성과 디자이너와의 협업 등에서 큰 문제가 된다.
JSP의 주된 대체 솔루션인 스프링 프레임워크와 Vue.js에서 사용하는 형식을 간단하게 살펴본다.
스프링 프레임워크의 기본 템플릿 엔진인 타임리프를 사용하는 경우 다음과 같다.
<table>
<tr data-th-each="variable : ${variables}">
<td data-th-text="${variable.attribute1}">attribute</td>
<td data-th-text="${variable.attribute2}">attribute</td>
</tr>
</table>
JSP와 EL 부분은 동일하지만 JSTL 대신 HTML 태그에 data-*-
속성을 사용하는 형태라 서버 실행 없이도 디자인 확인이 가능한 구조다. 변수로 출력되는 데이터 이외 기본값 출력이 가능하다.
만일 Vue.js를 이용해 프론트엔트 개발 방식으로 클라이언트 사이드 랜더링을 사용한다면 다음과 같다.
<table>
<tr v-for="variable in variables">
<td>{{variable.attribute1}}</td>
<td>{{variable.attribute2}}</td>
</tr>
</table>
타임리프와 유사하게 v-*
형태의 속성을 사용하고 있으며 프론트앤드 방식이기 때문에 해당 속성은 자바스크립트로 동작하는 Vue.js에서 처리하게 된다.
로직을 처리하기 위한 방법과 데이터 핸들링하는 방법 등에서 차이가 있으나 HTML과 데이터 그리고 로직을 조합하는 방식이 모두 유사한 것을 확인할 수 있다.