JSTL 이란?
JSTL (JavaServer Pages Standard Tag Library)는 JSP에서 자주 사용하는 기능들을 쉽게 사용할 수 있도록 미리 정의된 태그 라이브러리이다. JSTL은 표현 언어(EL), 조건 처리, 반복 처리, 포맷팅, XML 처리 등을 위한 태그를 제공한다. 이를 통해 JSP 코드의 가독성을 높이고, 비즈니스 로직을 JSP에서 분리할 수 있다.
JSTL 라이브러리 종류
Core Tags
JSTL의 Core 태그 라이브러리는 가장 기본적인 조건문, 반복문, 변수 지원 등을 포함한다. 주로 데이터 조작 및 제어 흐름을 처리하는 데 사용된다.
- <c:if> : 조건문을 처리하는 태그이다.
- <c:choose>, <c:when>, <c:otherwise> : 다중 조건문을 처리하는 태그이다.
- <c:forEach> : 반복문을 처리하는 태그이다.
- <c:set> : 변수 값을 설정하는 태그이다.
- <c:remove> : 변수를 제거하는 태그이다.
- <c:catch> : 예외를 처리하는 태그이다.
Formatting Tags
Formatting 태그 라이브러리는 날짜, 숫자 등을 포맷팅하는 데 사용됩니다. 국제화를 지원하는 포맷팅 기능을 제공합니다.
- fmt:formatDate : 날짜를 포맷팅하는 태그이다.
- fmt:formatNumber : 숫자를 포맷팅하는 태그이다.
- fmt:parseNumber : 문자열을 숫자로 파싱하는 태그이다.
- fmt:parseDate : 문자열을 날짜로 파싱하는 태그이다.
- fmt:bundle : 리소스 번들을 설정하는 태그이다.
- fmt:message : 리소스 번들에서 메시지를 가져오는 태그이다.
SQL Tags
sql:query : 데이터베이스에 쿼리를 실행하는 태그이다.
sql:update : 데이터베이스에 업데이트를 수행하는 태그이다.
sql:param : 쿼리에 매개변수를 설정하는 태그이다.
sql:setDataSource : 데이터베이스 연결을 설정하는 태그이다.
SQL 태그 라이브러리는 JSP에서 직접 데이터베이스 작업을 수행할 수 있도록 도와준다.
XML Tags
XML 태그 라이브러리는 XML 문서를 처리하는 데 사용된다. XPath를 사용하여 XML 데이터를 탐색하고 조작할 수 있다.
- <x:parse>: XML 문서를 파싱하는 태그이다.
- <x:out>: XML 문서의 값을 출력하는 태그이다.
- <x:forEach>: XML 문서의 각 노드를 반복하는 태그이다.
- <x:set>: XPath 표현식을 설정하는 태그이다.
라이브러리 설정 방법 (톰캣 10.x.x 환경)
- 라이브러리 파일 다운로드: 위에서 제공한 링크에서 JAR 파일을 다운로드한다.
- jakarta.servlet.jsp.jstl-api-3.0.0.jar
- jakarta.servlet.jsp.jstl-3.0.0.jar
- JAR 파일 추가:
- 프로젝트의 WEB-INF/lib 디렉터리에 다운로드한 두 JAR 파일을 복사한다.
- 프로젝트 빌드 패스에 추가:
- STS(Eclipse)에서 프로젝트를 마우스 오른쪽 버튼으로 클릭하고, Build Path -> Configure Build Path를 선택한다.
- Libraries 탭을 선택하고, Add JARs... 버튼을 클릭한다.
- 프로젝트의 WEB-INF/lib 디렉터리에서 두 JAR 파일을 선택하여 추가한다.
https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api/3.0.0
https://mvnrepository.com/artifact/org.glassfish.web/jakarta.servlet.jsp.jstl/3.0.0
https://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/overview-summary.html
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSTL 예제</title>
</head>
<body>
<h1>JSTL 예제</h1>
<% // 스크립트 릿 대신에 <c:set....> 태그를 사용할 수 있다. %>
<c:set var="message" value="JSTL ~~~ "/>
<p>메시지 : </p><c:out value="${message}" />
<!-- IF -->
<c:if test="${message != null}">
<p>메시지 값이 null 아닙니다</p>
</c:if>
<!-- foreach -->
<c:forEach var="i" begin="1" end="10" >
<p>Number : ${i}</p>
</c:forEach>
<h2>JSTL Formatting Example</h2>
<c:set var="now" value="<%=new Date() %>"/>
<fmt:formatDate var="formattedDate" value="${now}" pattern="yyyy-MM-dd HH:mm:ss" />
<p>현재 시간 : ${formattedDate} </p>
<c:set var="price" value="12345.678"/>
<fmt:formatNumber value="${price}" type="currency" var="formatPrice" />
<p>Format Price : ${formatPrice} </p>
</body>
</html>
User 클래스 생성(DTO)
package com.tenco.mdels;
import lombok.Data;
@Data
public class User {
private int id;
private String username;
private String password;
private String email;
}
UserDAOImpl 생성
package com.tenco.repository;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.mysql.cj.protocol.Resultset;
import com.tenco.mdels.User;
/**
* 인터페이스 설계 생략..
*/
public class UserDAOImpl {
private static final String URL = "jdbc:mysql://localhost:3306/demo3?serverTimezone=Asia/Seoul";
private static final String USER = "root";
private static final String PASSWORD = "asd123";
public UserDAOImpl() {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USER, PASSWORD);
}
public List<User> getAUsers() {
List<User> list = new ArrayList<>();
String sql = " SELECT * FROM users " ;
try(Connection conn = getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
User user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setEmail(rs.getString("email"));
list.add(user);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
}
UserDAOImpl 클래스가 인터페이스 설계를 포함하지 않은 경우, SOLID 원칙 중 다음 원칙들이 위배될 사항들은 뭐가 있을까?
1. 단일 책임 원칙 (Single Responsibility Principle, SRP)
UserDAOImpl 클래스가 인터페이스를 포함하지 않으면, 이 클래스는 데이터베이스와 직접적으로 연결되고, 데이터를 조작하는 역할을 모두 수행 함. 이는 데이터 접근 로직과 비즈니스 로직이 혼합될 가능성이 높아, 클래스가 여러 가지 책임을 지게 됨.
2. 인터페이스 분리 원칙 (Interface Segregation Principle, ISP)
ISP는 클라이언트가 자신이 사용하지 않는 메서드에 의존하지 않도록 인터페이스를 분리하도록 설계 해야 한다. UserDAO가 인터페이스를 사용하지 않으면, 모든 클라이언트는 필요하지 않은 메서드를 사용할 수밖에 없게 되어 인터페이스가 분리되지 않은 상태가 됨.
3. 의존성 역전 원칙 (Dependency Inversion Principle, DIP)
DIP는 고수준 모듈이 저수준 모듈에 의존해서는 안 되며, 둘 다 추상화에 의존해야 한다. 이 클래스는 구체적인 구현에 의존하게 되어 DIP를 위배하게 됨.
package com.tenco.controller;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import com.tenco.mdels.User;
import com.tenco.repository.UserDAOImpl;
@WebServlet("/user/*")
public class UserController extends HttpServlet {
private static final long serialVersionUID = 1L;
private UserDAOImpl userDAOImpl;
public UserController() {
userDAOImpl = new UserDAOImpl();
}
// http://localhost:8080/jstl/user/list?id=123&name=길동
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 전체 URL 를 문자를 반환 할려면
String fullURL = request.getRequestURL().toString();
System.out.println("fullURL : " + fullURL);
// URL의 쿼리 문자열을 반환 합니다.(쿼리 문자열이 없으면 null 을 반환)
String queryString = request.getQueryString();
System.out.println("queryString : " + queryString);
// 컨텍스트 루트 경로를 반환 받고 싶다면
String contextPath = request.getContextPath();
System.out.println("contextPath : " + contextPath);
// URL 마지막 경로(엔드포인트)를 반환 받고 싶다면
String pathInfo = request.getPathInfo();
System.out.println("pathInfo : " + pathInfo);
switch (pathInfo) {
case "/list":
userListPage(request, response);
break;
default:
break;
}
}
private void userListPage(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<User> userList = userDAOImpl.getAUsers();
request.setAttribute("userList", userList);
request.getRequestDispatcher("/WEB-INF/user/userList.jsp").forward(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
<%@page import="java.util.List"%>
<%@page import="com.tenco.mdels.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>USERLIST PAGE</h1>
<%
List<User> userList = (List<User>)request.getAttribute("userList");
%>
<table border="1">
<tr>
<th>ID</th>
<th>이름</th>
<th>이메일</th>
</tr>
<%
for(User user : userList) { %>
<td><%=user.getId()%></td>
<td><%=user.getUsername()%></td>
<td><%=user.getPassword()%></td>
<%} %>
</table>
</body>
</html>
<%@page import="java.util.List"%>
<%@page import="com.tenco.mdels.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>USERLIST PAGE</h1>
<c:choose>
<c:when test="${not empty userList}">
<table border="1">
<tr>
<th>ID</th>
<th>이름</th>
<th>이메일</th>
</tr>
<c:forEach var="user" items="${userList}" >
<tr>
<td><c:out value="${user.id}"/> </td>
<td><c:out value="${user.username}"/> </td>
<td><c:out value="${user.email}"/> </td>
</tr>
</c:forEach>
</table>
</c:when>
<c:otherwise>
<p>등록된 사용자가 없습니다.</p>
</c:otherwise>
</c:choose>
</body>
</html>
'JSP' 카테고리의 다른 글
JSP와 MVC 패턴 Todo 프로젝트 (0) | 2024.07.09 |
---|---|
Dynamic Web Project 를 활용한 기본적인 CRUD JSP 게시판 제작 (0) | 2024.07.09 |
서블릿과 JSP의 개념과 차이점 (1) | 2024.07.05 |
쿠키와 세션 관리 (0) | 2024.07.04 |
폼 처리와 요청 방식 (0) | 2024.07.04 |