JSP의 이해
📘 JSP (JavaServer Pages)란?
JSP는 HTML 코드 안에 Java 코드를 삽입해서 동적인 웹 페이지를 만들 수 있도록 해주는 기술
Java EE (Enterprise Edition)의 일부로, 서블릿보다 HTML과의 통합이 쉬워서 과거에 많이 사용
🔧 JSP 기본 구조 예:
1
2
3
4
5
6
7
8
9
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<body>
<%
String name = request.getParameter("name");
%>
<h1>Hello, <%= name %>!</h1>
</body>
</html>
위의 코드는 http://localhost:8080/hello.jsp?name=Rebecca 요청 시,
“Hello, Rebecca!“을 출력합니다.
🧠 JSP 작동 방식
JSP는 서버에서 실행될 때 서블릿으로 변환
즉, JSP → 서블릿 → 컴파일 → 실행되는 구조
개발자는 HTML 기반으로 쉽게 작성할 수 있지만, 내부적으로는 Java 서블릿임
✅ JSP의 장점
| 장점 | 설명 |
|---|---|
| HTML에 Java 코드를 직접 쓸 수 있음 | 웹 디자이너와 개발자가 협업하기 쉬움 |
| 빠르게 프로토타입 제작 가능 | 초기에 빠르게 동적 페이지 만들기 적합 |
| 서블릿보다 간단함 | 코드가 짧고 직관적임 |
❌ JSP의 단점
| 단점 | 설명 |
|---|---|
| 유지보수 어려움 | HTML + Java 혼합으로 가독성 나쁨 |
| 로직이 뷰에 있음 | MVC 패턴 위반, 비즈니스 로직이 섞임 |
| 코드 중복 많음 | 반복적인 코드, 분리 어려움 |
| 테스트 어려움 | Java 코드가 페이지에 섞여 있어 단위 테스트 힘듦 |
📉 요즘 트렌드 (2020년대 이후)
✅
JSP는 더 이상 트렌드가 아닙니다.
이유는 다음과 같습니다:
프론트엔드와 백엔드의 분리:
React, Vue.js, Angular 등 프론트엔드 프레임워크의 인기 증가
JSP처럼 서버에서 HTML을 만들어 보내는 방식은 덜 쓰임
Spring Boot + Thymeleaf, REST API 사용 증가:
백엔드는 REST API 제공 (Spring Boot)
프론트는 React 같은 SPA로 구성
서버 템플릿 필요할 때는 Thymeleaf 선호 (Spring과 통합이 좋음)
JSP는 보안, 유지보수, 확장성 면에서 불리
- 기업들도 JSP에서 다른 기술로 전환하는 추세
🔁 JSP는 언제 쓰일 수 있나?
기존 레거시 시스템 유지보수
학교/학원에서 Java 웹 기초 학습용
작은 내부 시스템에서 간단하게 구현할 때
🚀 요즘 대세 Java 웹 기술 스택
| 역할 | 기술 예시 |
|---|---|
| 프론트엔드 | React, Vue.js, Angular |
| 백엔드 (서버) | Spring Boot (Java) |
| 템플릿 (선택적) | Thymeleaf, FreeMarker |
| API 방식 | RESTful API, GraphQL |
| 데이터 저장 | MySQL, PostgreSQL, MongoDB |
| 인증/보안 | Spring Security, OAuth2 |
📌 결론
JSP는 과거에 많이 쓰였지만 현재는 거의 쓰이지 않는 기술입니다.
Spring Boot + Thymeleaf 또는 React + Spring REST API 조합이 현대적인 선택입니다.
하지만 JSP의 구조를 이해하면, 서블릿, MVC, 서버 렌더링의 개념을 배우는 데 도움이 됩니다.
제공된 다이어그램은 JSP(JavaServer Pages) 파일의 생명주기를 나타내며, JSP 파일이 처음 접근될 때부터 소멸될 때까지의 주요 단계와 관련된 파일들을 보여줍니다.
각 단계별 설명은 다음과 같습니다:
hello.jsp(JSP 파일 접근): 이 과정의 시작점입니다. 사용자가 JSP 파일(예:hello.jsp)을 요청하면, 웹 컨테이너(예: 톰캣)가 이 파일을 처리하기 시작합니다.- 클래스 변환 여부 확인 (Check if Class is Converted): 컨테이너는 먼저
hello.jsp파일이 이미 자바 서블릿 클래스로 변환되었는지 확인합니다.- 아니요 (No): 만약 변환되지 않았거나(또는 JSP 파일이 마지막 변환 이후 수정되었을 경우), 과정은 3단계로 넘어갑니다.
- 예 (Yes): 이미 변환되었고 변환된 클래스가 최신 상태라면, 메모리에 로드되었는지 여부를 직접 확인합니다.
hello_jsp.java(자바 소스로 변환): JSP가 변환될 필요가 있다면, 웹 컨테이너는hello.jsp파일을hello_jsp.java라는 자바 소스 파일로 변환합니다._jsp접미사는 생성된 서블릿 이름에 대한 일반적인 규칙입니다.그 다음, 이
hello_jsp.java파일은 자바 바이트코드 클래스 파일인hello_jsp.class로 컴파일됩니다 (자바 클래스로 컴파일).- 메모리에 실행 여부 확인 (Check if Loaded in Memory): 컴파일 후(또는 이미 변환된 클래스가 존재했을 경우), 컨테이너는
hello_jsp.class가 메모리에 로드되어 실행 준비가 완료되었는지 확인합니다.- 아니요 (No): 로드되지 않았다면,
jspInit()메서드가 호출됩니다.jspInit(): 이것은 JSP의 초기화 메서드입니다. JSP가 메모리에 처음 로드될 때 단 한 번만 호출됩니다. 여기에는 한 번만 실행되는 설정 작업을 위한 코드를 넣을 수 있습니다.- 4. 서블릿 실행 (Execute Servlet):
jspInit()호출 후, JSP는 요청을 처리할 “준비(Ready)” 상태가 됩니다.
- 예 (Yes): 클래스가 이미 로드되어 준비되었다면, 직접 “Ready” 상태로 진행됩니다.
- 아니요 (No): 로드되지 않았다면,
- Ready (사용자 요청 대기): 이 상태에서 JSP는 사용자 요청을 처리할 준비가 되어 있습니다.
_jspService(): 사용자 요청이 들어오면_jspService()메서드가 호출됩니다. 이 메서드는 각 요청을 처리하고 클라이언트에 응답을 생성하는 주요 메서드입니다. 이 메서드는 JSP에 대한 모든 후속 요청마다 반복적으로 호출됩니다.
- Destroy (컨테이너 종료): JSP 인스턴스는 웹 애플리케이션 또는 웹 컨테이너 자체가 종료될 때까지 메모리에 남아
_jspService()를 통해 요청을 처리합니다.- 웹 애플리케이션 컨테이너가 종료됨 (Web Application Container Terminates): 이 이벤트는 JSP의 소멸을 트리거합니다.
jspDestroy(): JSP 인스턴스가 메모리에서 제거되기 전에jspDestroy()메서드가 호출됩니다. 이 메서드 역시 단 한 번만 호출되며, 리소스 해제(예: 데이터베이스 연결 닫기)와 같은 정리 작업을 수행할 수 있도록 합니다.
요약하자면, 이 다이어그램은 JSP가 서블릿으로 처음 번역되고 컴파일되는 과정부터, 초기화, 요청 처리, 그리고 웹 애플리케이션이 종료될 때의 소멸에 이르기까지 JSP의 완전한 생명주기를 보여줍니다.
제공해주신 이미지의 내용을 바탕으로 서블릿(Servlet)과 JSP를 비교하는 표를 다음과 같이 정리할 수 있습니다.
서블릿과 JSP 비교
| 분류 | 서블릿 (Servlet) | JSP (JavaServer Pages) |
|---|---|---|
| 형식 | - Java 코드 내에 HTML 코드가 삽입된 형태 | - HTML 코드 내에 Java 코드가 삽입된 형태 |
| 특징 | - Java 코드 내에 HTML 코드가 삽입되는 형태입니다.<br>- 따라서 HTML을 작성하는 Java 코드가 복잡합니다. | - HTML 코드 내에 Java 코드가 삽입되는 형태입니다.<br>- 서블릿에 비해 HTML 코드를 쉽게 작성할 수 있습니다. |
| 목적 | - Java 코드를 이용한 Business Logic 처리에 적합합니다.<br>- 따라서 MVC 패턴의 Controller 역할로 사용됩니다. | - tag를 이용한 Presentation Logic 처리에 적합합니다.<br>- 따라서 MVC 패턴의 View 역할로 사용됩니다. |
JSP 스크립팅 요소는 JSP 페이지가 서블릿으로 변환될 때 JSP 엔진에 의해 처리되며, <% ... %> 형식을 가집니다.
다음은 각 스크립팅 요소에 대한 설명입니다:
- Comment tag (주석 태그)
- 형식:
<%-- 주석 --%> - 설명: JSP 파일 내에 주석을 작성할 때 사용합니다. 이 주석은 웹 브라우저로 전송되지 않으며, JSP 엔진이 서블릿 코드를 생성할 때 완전히 무시됩니다. 즉, 최종 생성된 HTML 소스 코드에는 나타나지 않습니다.
- 형식:
- Directive tag (지시어 태그)
- 형식:
<%@ 지시자 %> - 설명: JSP 페이지 전체에 대한 정보를 지정합니다. 예를 들어, 페이지의 언어 설정, 인코딩 방식, 필요한 클래스 임포트 등을 선언할 때 사용됩니다. 대표적인 지시어로는
page,include,taglib등이 있습니다.
- 형식:
- Declaration tag (선언 태그)
- 형식:
<%! 자바 선언문 %> - 설명: JSP 페이지에서 사용할 멤버 변수나 메서드를 선언할 때 사용합니다. 이 태그 안에 선언된 변수나 메서드는 JSP 페이지가 서블릿으로 변환될 때 서블릿 클래스의 멤버로 삽입됩니다. 따라서 한 번만 선언되고, 해당 JSP 페이지의 모든 요청에서 공유됩니다.
- 형식:
- Scriptlet tag (스크립트릿 태그)
- 형식:
<% 자바 코드 %> - 설명: JSP 페이지 내에서 Java 코드를 직접 작성할 때 사용합니다. 이 안에 작성된 Java 코드는 서블릿의
_jspService()메서드 내에 삽입되어, 클라이언트의 요청이 올 때마다 실행됩니다. 비즈니스 로직이나 조건문, 반복문 등을 구현하는 데 사용됩니다.
- 형식:
- Expression tag (표현식 태그)
- 형식:
<%= 자바 표현식 %> - 설명: Java 표현식의 결과를 HTML 문서에 출력할 때 사용합니다. 이 태그 안에 작성된 Java 표현식은 자동으로 문자열로 변환되어 웹 브라우저로 전송됩니다. 세미콜론(;)은 사용하지 않습니다.
- 형식:
이러한 스크립팅 요소들은 JSP 페이지가 동적인 웹 콘텐츠를 생성하고, HTML과 Java 코드를 효율적으로 혼합하여 사용할 수 있도록 해줍니다.
JSP page 지시어 속성
| 속성명 | 기본값 | 설명 | 예시 |
|---|---|---|---|
contentType | text/html | 웹 브라우저로 응답할 MIME 타입(페이지의 내용 유형)과 문자 인코딩을 지정합니다. 기본값은 text/html; charset=ISO-8859-1 이며, 주로 text/html; charset=UTF-8 등으로 설정하여 한글 깨짐을 방지합니다. | contentType="text/html; charset=UTF-8" 또는 <br> contentType="application/xml" |
import | 없음 | JSP 페이지에서 사용할 Java 패키지나 클래스를 임포트(import)합니다. 쉼표(,)로 여러 개의 패키지나 클래스를 구분하여 임포트할 수 있습니다. 자바의 import 문과 동일한 역할을 합니다. | import="java.util.*,java.io.File" 또는 <br> import="java.util.ArrayList" |
session | true | JSP 페이지에서 HTTP 세션(session) 객체를 사용할지 여부를 지정합니다. true로 설정하면 session 내장 객체를 사용할 수 있고, false로 설정하면 세션 객체가 생성되지 않습니다. | session="false" |
errorPage | 없음 | 현재 JSP 페이지에서 에러가 발생했을 때, 에러 처리를 위임할 에러 페이지의 URL을 지정합니다. 지정된 페이지로 제어가 이동하여 에러 정보를 처리할 수 있습니다. | errorPage="/error/error_404.jsp" |
isErrorPage | false | 현재 JSP 페이지가 다른 JSP 페이지에서 발생한 에러를 처리하는 에러 페이지인지 여부를 지정합니다. true로 설정하면 exception 내장 객체를 사용하여 에러 정보를 가져올 수 있습니다. | isErrorPage="true" |
language | java | JSP 페이지에서 스크립트릿(scriptlet)이나 표현식(expression) 등에 사용할 프로그래밍 언어를 지정합니다. 현재는 java만 지원됩니다. | language="java" |
extends | 없음 | JSP 페이지가 서블릿으로 변환될 때, 이 서블릿이 상속받을 상위 클래스(또는 인터페이스)를 지정합니다. 이 속성은 고급 사용자나 프레임워크에서 특정 기능을 통합할 때 사용될 수 있습니다. | extends="com.example.MyCustomServlet" |
buffer | 8kb | JSP 페이지의 출력 내용을 임시로 저장하는 버퍼의 크기를 지정합니다. 버퍼가 가득 차거나 페이지 처리가 완료되면 버퍼의 내용이 웹 브라우저로 전송됩니다. none으로 설정하면 버퍼링을 사용하지 않습니다. | buffer="16kb" 또는 <br> buffer="none" |
autoFlush | true | buffer 속성으로 지정된 출력 버퍼가 가득 찼을 때, 버퍼의 내용을 자동으로 웹 브라우저로 보낼지 여부를 지정합니다. true면 자동으로 전송하고, false면 버퍼 오버플로우 시 예외(IOException)를 발생시킵니다. | autoFlush="false" |
isThreadSafe | true | JSP 페이지가 여러 요청을 동시에 처리할 때 스레드로부터 안전한지 여부를 지정합니다. true면 동시에 여러 요청을 처리할 수 있으며, false면 한 번에 하나의 요청만 처리하도록 합니다(SingleThreadModel 인터페이스를 구현). false로 설정하는 것은 성능 저하를 가져올 수 있으므로 권장되지 않습니다. | isThreadSafe="false" |
info | 없음 | JSP 페이지에 대한 설명을 지정합니다. 이 정보는 서블릿 컨텍스트에서 접근할 수 있으며, 주로 개발자가 페이지에 대한 간단한 정보를 남길 때 사용합니다. | info="회원 정보 출력 페이지" |
pageEncoding | ISO-8859-1 | JSP 소스 파일 자체의 문자 인코딩을 지정합니다. 이 속성은 JSP 파일이 어떤 인코딩으로 저장되어 있는지를 JSP 엔진에 알려주어, JSP 파일의 문자들이 올바르게 해석되도록 합니다. contentType의 charset과는 다릅니다. | pageEncoding="EUC-KR" 또는 <br> pageEncoding="UTF-8" |
isELIgnored | false | JSP 페이지에서 EL(Expression Language) 표현식의 사용을 무시할지 여부를 지정합니다. true로 설정하면 ${...}와 같은 EL 표현식이 단순히 문자열로 처리되어 출력됩니다. | isELIgnored="true" |
네, JSP include 지시어에 대해 설명해 드릴게요.
JSP include 지시어
include 지시어는 JSP 페이지에 다른 HTML, JSP, 텍스트 파일 등의 내용을 삽입할 때 사용되는 지시어입니다. 주로 웹 페이지에서 공통적으로 사용되는 부분(예: 헤더, 푸터, 사이드 메뉴 등)을 여러 페이지에서 재사용할 목적으로 활용됩니다.
설명해주신 내용에 따라 자세히 풀어보면 다음과 같습니다:
- 현재 페이지에서 다른 HTML 및 JSP 페이지를 삽입할 수 있는 방법 제공:
include지시어는<%@ include file="삽입할_파일_경로" %>형식으로 사용됩니다.file속성에 삽입하고자 하는 파일의 상대 경로 또는 절대 경로를 지정합니다.- 이 지시어를 사용하면, 지정된 파일의 내용이 현재 JSP 페이지에 마치 한 파일인 것처럼 “합쳐져서” 처리됩니다.
- 각 페이지마다 공통적인 내용을 가지는 경우 매번 작성하지 않고 삽입 (footer, header, side 영역의 공통 내용 처리):
- 웹사이트를 만들 때, 대부분의 페이지에 동일한 헤더(상단 로고, 메뉴 바), 푸터(저작권 정보, 회사 정보), 또는 사이드 바(로그인 위젯, 공지사항)가 들어갑니다.
include지시어를 사용하면 이 공통적인 부분들을 별도의 파일(예:header.jsp,footer.jsp,sidebar.html)로 분리해두고, 필요한 모든 JSP 페이지에서 해당 파일을include지시어로 불러와 삽입할 수 있습니다.- 이렇게 하면 코드 중복을 줄이고, 나중에 공통 부분의 내용이 변경될 때 해당 파일 하나만 수정하면 되므로 유지보수가 매우 편리해집니다.
- 정적인 방법으로 삽입:
- 이것이
include지시어의 가장 중요한 특징 중 하나입니다.include지시어는 JSP 페이지가 서블릿으로 변환될 때 (즉, 컴파일 시점) 동작합니다. - 지시어로 지정된 파일의 내용이 물리적으로 현재 JSP 파일에 복사되어 하나의
.java파일로 합쳐지고, 그 후에 컴파일됩니다. - 따라서, 삽입되는 파일의 내용이 변경되면, 해당
include지시어를 사용하는 모든 JSP 파일이 다시 컴파일되어야 변경 내용이 반영됩니다. - 이는 동적으로 런타임에 포함되는
jsp:include액션 태그와 대비되는 개념입니다. (jsp:include는 요청 시점마다 별도의 서블릿을 실행하여 결과를 포함하는 방식)
- 이것이
간단한 예시:
header.jsp 파일 내용:
1
2
3
4
5
6
7
8
<header>
<h1>My Website</h1>
<nav>
<a href="/">Home</a>
<a href="/about.jsp">About</a>
<a href="/contact.jsp">Contact</a>
</nav>
</header>
main_page.jsp 파일 내용:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>메인 페이지</title>
</head>
<body>
<%@ include file="header.jsp" %>
<main>
<h2>환영합니다!</h2>
<p>이곳은 메인 페이지입니다.</p>
</main>
<footer>
<p>© 2025 My Website</p>
</footer>
</body>
</html>
위 예시에서 main_page.jsp는 header.jsp의 내용을 포함하여 최종적으로 하나의 HTML 페이지를 생성하게 됩니다. header.jsp 내용이 바뀌면, main_page.jsp는 다시 컴파일되어야 합니다.
다시 한 번 말씀드리겠습니다. Google Keep이나 다른 Google 소프트웨어를 사용하지 않고 Markdown 형식의 테이블로만 정리하겠습니다.
JSP 내장 객체
| 내장 객체 (내장 변수) | 설명 | |—|—| | request | HttpServletRequest 객체 참조. 클라이언트의 요청 정보(파라미터, 헤더 등)를 담고 있습니다. | | response | HttpServletResponse 객체 참조. 서버가 클라이언트에게 보낼 응답 정보(헤더, 리다이렉션 등)를 설정하는 데 사용됩니다. | | out | JspWriter 객체 참조. 웹 브라우저로 출력할 내용을 버퍼에 쓰는 데 사용됩니다. System.out.println()과 유사하게 동작합니다. | | session | HttpSession 객체 참조. 클라이언트의 세션 정보를 관리합니다. session="true" (기본값)인 경우에만 사용 가능합니다. | | application | ServletContext 객체 참조. 웹 애플리케이션 전체의 정보를 관리하며, 모든 사용자(세션)가 공유하는 데이터를 저장하는 데 사용됩니다. | | page | Object 타입으로, 현재 JSP 페이지를 서블릿으로 변환한 객체(현재 서블릿 인스턴스)를 참조합니다. 자바 클래스의 this 키워드와 동일한 역할을 합니다. | | config | ServletConfig 객체 참조. JSP 페이지(서블릿)의 초기화 매개변수(init-parameters)에 접근하는 데 사용됩니다. | | exception | Throwable 객체에 대한 참조. JSP 페이지에서 예외(에러)가 발생했을 때 해당 예외 객체를 참조합니다. isErrorPage="true"인 경우에만 사용 가능하며, 에러 처리 페이지에서 활용됩니다. | JSP 표준 액션 태그에 대한 표입니다.
| 표준 액션 태그 | 설명 |
|---|---|
<jsp:useBean /> | 자바빈 컴포넌트를 사용하기 위한 액션 태그 |
<jsp:setProperty /> | 자바빈 인스턴스에 데이터를 저장하기 위한 액션 태그 |
<jsp:getProperty /> | 자바빈 인스턴스에서 데이터를 얻기 위한 액션 태그 |
<jsp:include /> | 제공된 JSP 파일을 삽입하기 위한 액션 태그 |
<jsp:forward /> | 제공된 JSP 파일로 forward하기 위한 액션 태그 |
<jsp:param /> | include 및 forward할 때 요청 파라미터를 추가하기 위한 액션 태그 |