같은 JSP 파일을 참조하더라도 <%@ include file="..." %>를 사용하느냐, <jsp:include page="..." />를 사용하느냐에 따라 정적 포함(Static Include)인지 동적 포함(Dynamic Include)인지가 달라진다.
| 포함 방식 | 변환 시점 | 실행 방식 | JSP 변수 공유 | 변경 반영 |
|---|---|---|---|---|
<%@ include file="header.jsp" %> | 컴파일 시점 (JSP → 서블릿 변환 시) | JSP 코드 그대로 삽입 | ✅ 가능 (하나의 JSP 파일로 합쳐짐) | ❌ JSP가 수정되면 포함한 모든 JSP 다시 컴파일 필요 |
<jsp:include page="header.jsp" /> | 실행 시점 (사용자 요청 시) | 독립된 JSP 실행 후 결과 포함 | ❌ 불가능 (변수 공유 안 됨) | ✅ JSP가 수정되면 즉시 반영 |
"정적"이라고 하는 이유: 컴파일 타임(빌드 시점)에 포함되기 때문.
"동적"이라고 하는 이유: 서버에서 실행 결과가 바뀔 수 있기 때문.
✔ 정적 포함: 포함된 파일이 컴파일 시 결합됨.
✔ 동적 포함: 실행할 때마다 포함된 파일이 별도로 실행됨.
"서버에서 실행 결과가 바뀔 수 있다"는 말은, 서버 측에서 요청을 처리하는 과정에서 데이터를 동적으로 생성하거나 변경할 수 있다는 의미이다.
구체적으로 말하자면, 서버가 동적인 콘텐츠를 생성하거나 수정해서 클라이언트에게 보내주는 방식으로 예를 들어, 데이터베이스에서 값을 조회하거나 사용자의 요청에 따라 다르게 결과를 생성할 수 있다.
JSP는 서버에서 실행될 때마다 서버 측에서 HTML을 동적으로 생성하고, 그 결과를 클라이언트에게 전달.
예를 들어, 사용자가 페이지를 요청할 때마다 다른 데이터를 화면에 표시하려면, JSP 파일에서 요청 시마다 그에 맞는 데이터를 조회하고 출력해야 함.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<html>
<body>
<h1>오늘의 날짜는: <%= new java.util.Date() %></h1>
</body>
</html>
new java.util.Date()는 실행 시점에 현재 날짜와 시간이 다르게 반환되므로, 결과가 동적으로 달라짐.서버는 사용자 요청에 따라 데이터베이스에서 실시간으로 데이터를 조회하고, 그에 따라 페이지를 렌더링할 수 있다.
즉, 사용자가 요청할 때마다 데이터가 달라질 수 있기 때문에 실행 결과가 바뀌는 것.
<%@ page import="java.sql.*" %>
<%
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/mydb", "user", "password");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT name FROM users WHERE id=1");
if (rs.next()) {
String name = rs.getString("name");
%>
<h1>사용자 이름: <%= name %></h1>
<%
}
%>
<%@ include file="header.jsp" %> (정적 포함)header.jsp)의 내용이 그대로 현재 JSP(main.jsp)에 삽입됨.header.jsp를 수정하면, main.jsp도 다시 컴파일해야 반영됨.<!-- main.jsp -->
<%@ include file="header.jsp" %>
<body>
<h1>메인 페이지</h1>
<p>현재 시간: <%= currentTime %></p> <%-- header.jsp에서 선언한 변수 사용 가능 --%>
</body>
<!-- header.jsp -->
<%
String currentTime = new java.util.Date().toString();
%>
<h2>공통 헤더</h2>
header.jsp에서 선언한 currentTime 변수를 main.jsp에서 바로 사용할 수 있음.main.jsp가 서블릿으로 변환될 때 header.jsp 코드가 그대로 삽입되기 때문.<jsp:include page="header.jsp" /> (동적 포함)header.jsp가 별도로 실행되고, 그 출력 결과만 main.jsp에 포함됨.header.jsp)의 변수, 선언문 등을 현재 JSP(main.jsp)에서 직접 접근할 수 없음(독립적인 실행).header.jsp)이 수정되더라도, 기존 JSP 파일을 별도 컴파일할 필요 없이 즉시 변경 사항이 반영됨.<!-- main.jsp -->
<jsp:include page="header.jsp" />
<body>
<h1>메인 페이지</h1>
<p>현재 시간: <%= currentTime %></p> <%-- 오류 발생! 변수 공유 안 됨 --%>
</body>
<!-- header.jsp -->
<%
String currentTime = new java.util.Date().toString();
%>
<h2>공통 헤더</h2>
currentTime 변수를 main.jsp에서 직접 사용할 수 없음. <!-- header.jsp -->
<%
String currentTime = new java.util.Date().toString();
request.setAttribute("currentTime", currentTime);
%>
<h2>공통 헤더</h2>
<!-- main.jsp -->
<jsp:include page="header.jsp" />
<body>
<h1>메인 페이지</h1>
<p>현재 시간: <%= request.getAttribute("currentTime") %></p>
</body>
request.setAttribute()를 사용하면 변수를 main.jsp에서도 사용할 수 있음.header.jsp를 포함하더라도 방식에 따라 동작 방식이 다름! <%@ include %>는 서블릿 파일 자체가 변경됨, <jsp:include>는 독립적으로 실행됨 <%@ include file="..." %> → 정적 포함 (컴파일 시점에 JSP 코드 삽입, 변수 공유 가능)<jsp:include page="..." /> → 동적 포함 (실행 시점에 JSP 실행 결과 포함, 변수 공유 불가)✔️ 언제 어떤 걸 써야 할까?
include file="..." 사용 jsp:include page="..." 사용 jsp:include 추천 (별도로 관리 가능) 즉, 변수 공유가 필요하면 정적 포함, 변경 사항을 즉시 반영하고 싶다면 동적 포함! 🚀
<%@ page import="..." %> (Java import 문)import문과 동일하며, Java 클래스, 패키지를 현재 JSP에서 사용할 수 있도록 불러오는 역할을 합니다. <%@ page import="java.util.Date" %>import는 HTML 출력과 무관하며, JSP 코드 내에서만 영향을 줌 | 기능 | <%@ include file="..." %> | <jsp:include page="..." /> | <%@ page import="..." %> |
|---|---|---|---|
| 포함 방식 | 정적 포함 (Compile-time) | 동적 포함 (Runtime) | Java 패키지/클래스 가져오기 |
| 실행 방식 | 현재 JSP에 코드 삽입 | 별도의 JSP를 실행하여 출력 포함 | Java 코드에서 패키지 사용 가능 |
| 포함된 파일의 영향 | 하나의 서블릿으로 컴파일됨 | 별도의 서블릿으로 실행됨 | JSP 코드에서만 영향 |
| 변수 공유 | 포함된 파일의 변수, 메서드를 그대로 사용 가능 | 직접 변수 사용 불가 (request 전달 필요) | Java 클래스 사용 가능 |
include는 HTML/코드를 삽입하는 용도 jsp:include는 실행 결과를 삽입하는 용도 import는 Java 클래스를 가져오는 용도 JSP 파일이 서블릿(Servlet) 파일로 컴파일된다는 것은, JSP 코드가 실제로는 자바 코드로 변환되어 실행된다는 의미야.
.class(바이트코드) 생성 즉, 내부적으로 서블릿으로 변환된 후 자바 코드로 실행
📌 예제
hello.jsp)<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head><title>Hello JSP</title></head>
<body>
<h1>현재 시간: <%= new java.util.Date() %></h1>
</body>
</html>
이 코드를 웹 브라우저에서 실행하면, JSP 컨테이너(예: Tomcat)가 내부적으로 다음과 같은 서블릿 코드로 변환.
hello_jsp.java)public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase {
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
response.setContentType("text/html; charset=UTF-8");
JspWriter out = response.getWriter();
out.write("<html><head><title>Hello JSP</title></head><body>");
out.write("<h1>현재 시간: " + new java.util.Date() + "</h1>");
out.write("</body></html>");
}
}
위 코드처럼 JSP가 실제로는 HttpServlet 클래스를 상속받는 서블릿 클래스로 변환.