JSP 개요
JSP(Java Server Page)는?
- HTML 내에 자바 코드를 삽입하여, 웹 서버에서 동적으로 웹 페이지를 생성하여 웹 브라우저에 회신해주는 서버측 스크립트 언어이다.
- 웹 서비스를 위한 인터넷 프로그래밍 언어다.
- 원래, 서블릿(servlet)과 JSP는 Sun사의 Java 웹 서버 제품의 보조 기술로 등장하였다.
- 1998년 첫 번째 JSP API(Application Programming Interface) 스펙(specification) 발표하였다.
- 1999년 5월 JSP 1.0 스펙(Servlet 2.2)이 발표되면서 안정적인 개발 플랫폼의 면모를 갖추게 되었다.
- JSP 기능 역시 서블릿 기술을 사용하여 구현 되었기 때문에 기존의 서블릿 제품들의 장점을 그대로 충분히 흡수하였다.
- Apache Struts(MVC Framework)나 자카르타 프로젝트의 JSTL(JSP Standard Tag Library) 등의 JSP 태그 라이브러리를 사용하는 경우 자바 코딩 없이 태그만으로 간략히 기술이 가능하다.
JSP 특징
1. 플랫폼에 독립적이다.
- "Write Once, Run Anywhere"
- 개발되면, 다른 환경으로 큰 변경 작업 없이 이식 가능하다.
2. 소프트웨어의 재사용성이 증가된다.
- 미리 개발해 놓은 자원을 다른 곳에서도 새로운 개발 없이 사용 가능하다.
3. 안정적이며 수행 속도가 향상된다.
- JSP는 스크립트 소스코드가 JSP 컨테이너에 의해 컴파일되고, 서블릿 코드로 변환된다는 점에서 최초 응답 속도가 느릴 수 있으나, 이 과정이 처음 한 번만 일어나며, 컨테이너 스케줄러에 의해 미리 생성된 서블릿을 실행하기에 뛰어난 속도를 자랑한다.
- JSP는 하나의 요청마다 쓰레드를 생성하기 때문에 하나의 요청마다 프로세스를 생성하는 CGI보다 뛰어나다.
4. 디자인 부분과 프로그램 부분의 분리가 가능하다.
- JSP는 컴포넌트 중심적인 디자인이기 때문에 자바빈즈(JavaBeans)로 만들어진 서버측 객체의 기능을 사용할 수 있는 HTML과 비슷한 태그 시스템을 가진다.
5. Jakarta EE / Java EE(Java Enterprise Edition)의 진입로이다.
- 기업용 서버 플랫폼이다(1999년부터 현재까지 발전해왔다).
- 2017년 이클립스 재단으로 이관되면서 2020년 Java EE에서 Jakarta EE로 변경되었다.
- JSP를 필두로 서블릿(Servlet), XML, EJB(Enterprise JavaBean), JavaMail, JNDI(JavaNaming and Directory Interface), CORBA 등의 핵심 기술로 이루어져 있다.
- JSP는 웹상에서 Jakarta EE 핵심 기술들을 모두 연동 가능하다.
Jakarta EE
- 오라클에서 이클립스 재단으로 이관되면서, 자바EE의 공식 명칭이 자카르타EE, 프로젝트명은 EE4J(Eclipse Enterprise for Java)로 변경되었다.
- 자바 상표권은 여전히 오라클이 보유하고 있기 때문에 자바 네임스페이스 사용에 제약이 있다.
- 2020년 12월, 자카르타EE에서는 자바 네임스페이스가 Jakarta로, API 패키지명은 javax.* 에서 Jakarta.*로 변경(Tomcat 10 버전부터 적용 됨)
- Jakarta EE 추가 지원 사항
- 컨테이너와 마이크로서비스 환경을 위해 자바 런타임을 경량화된 모듈화 지원
- 자카르타 NoSQL 지원(대용량 데이터 처리, 비구조적 데이터 처리를 위한 분산 저장 시스템)
Context 디렉토리 구조
Publish할 때 Context 디렉토리 구성
1. *.html, *.jsp, *.jpg 등: root 디렉토리 중심으로 하위 디렉토리를 가지면서 위치함
2. /WEB-INF/web.xml: Web Application Deployment Descriptor
- XML로 구성된 일종의 환경 설정 파일
- 현재 웹 애플리케이션에 대한 각종 설정 사항을 갖고 있다.
3. /WEB-INF/classes/: 현재 웹 애플리케이션에서 사용할 자바 클래스 파일 위치
- Eclipse에서는 build/classes 폴더에 저장될 수도 있으나(사용자에 의한 변경 가능), 퍼블리싱 서비스 서버에서는 /WEB-INF/classes 디렉토리에 저장해야 한다.
- 서블릿과 기타 클래스도 위치할 수도 있다. 패키지 구조에 따라 디렉토리 구성 가능하다.
- jar 파일은 지원하지 않으므로 주의한다.
4. /WEB-INF/lib/: jar 파일이 위치한다(classes와 유사)
- 대부분 JDBC 드라이버와 같은 서브파티 클래스 혹은 현재 웹 어플리케이션이 배포되었을 때 여러 환경에서 다른 설정 없이도 실행 가능하도록 하는 다양한 클래스를 포함한다.
5. /META-INT/context.xml: WAR 파일 배포시, 동적으로 context 정보를 추가 적용하기 위한 파일이다.
WAR(Web Application aRchive)
- 웹 애플리케이션 디렉토리 구조를 가진 압축 파일(zip, jar 파일 호환)을 말한다.
- 웹 애플리케이션 배포를 위해 사용한다.
- WAR 파일의 배포 설치로 애플리케이션 서버(웹로직, 서블릿, J2EE) 간의 호환성 유지 가능하다.
JSP 동작 원리
JSP 생명주기
1. 클라이언트가 hello.jsp 요청을 보낸다.
2. 해당 JSP가 처음 요청이면:
- .java로 변환
- .class로 컴파일
3. 그 .class가 메모리에 로딩되면 jspInit() 실행 (한 번만)
4. 그 후 클라이언트 요청마다:
- _jspService() 실행! (여기서 버퍼를 사용함. JSP는 출력 내용을 출력 버퍼에 쌓아놓고, 그 버퍼가 가득차거나 JSP 처리가 끝나거나 명시적으로 flush() 될 때 그 때 한꺼번에 클라이언트로 전송한다)
5. 서버 종료시 jspDestory() 실행
생성 파일 확인
- jsp는 최초로 호출될 때 서블리승로 변경되어 컴파일된다.
- 모든 JSP 페이지는 파일 형태가 아닌 자바 클래스형태로 관리된다.
- 모든 JSP 페이지는 컨테이너에 의해 메모리에 적재된다.
JSP 문법
스크립틀릿(Scriptlet)
_jspService() 메소드에서 실행되는 java code 기술부이다.
문법은 다음과 같다.
<% statements of java code; %>
※ Example
다음과 같은 jsp 파일의 코드는 JSP 컨테이너에 의해 서블릿(java 파일)으로 변환된다.
<%@ page contentType="text/html;charset=UTF-8" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<% int total=0; for(int cnt=1; cnt <=10; cnt++) total +=cnt; out.print(total); %>
</body>
</html>
public void _jspService(final jakarta.servlet.http.HttpServletRequest request, final jakarta.servlet.http.HttpServletResponse response)
throws java.io.IOException, jakarta.servlet.ServletException {
if (!jakarta.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP들은 오직 GET, POST 또는 HEAD 메소드만을 허용합니다. Jasper는 OPTIONS 메소드 또한 허용합니다.");
return;
}
}
final jakarta.servlet.jsp.PageContext pageContext;
jakarta.servlet.http.HttpSession session = null;
final jakarta.servlet.ServletContext application;
final jakarta.servlet.ServletConfig config;
jakarta.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
jakarta.servlet.jsp.JspWriter _jspx_out = null;
jakarta.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\n");
out.write(" <!DOCTYPE html>\n");
out.write(" <html lang=\"en\">\n");
out.write("\n");
out.write(" <head>\n");
out.write(" <meta charset=\"UTF-8\">\n");
out.write(" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n");
out.write(" <title>Document</title>\n");
out.write(" </head>\n");
out.write("\n");
out.write(" <body>\n");
out.write(" ");
int total=0; for(int cnt=1; cnt <=10; cnt++) total +=cnt; out.print(total);
out.write("\n");
out.write(" </body>\n");
out.write("\n");
out.write(" </html>");
} catch (java.lang.Throwable t) {
if (!(t instanceof jakarta.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
표현식(Expression)
변수, 상수, 반환값을 가지는 메소드, 연산식의 결과를 문자열로 출력하는 구문이다.
statement를 지정하기 위한 세미콜론(;)을 사용할 수 없다.
동일한 역할을 수행하는 내장객체 메서드는 out.print()이다.
문법은 다음과 같다.
<%= variable or method %>
※ Example
다음 jsp 코드는 다음과 같은 서블릿으로 변환된다.
<body>
<% int total=0; for(int cnt=1; cnt <=10; cnt++) total +=cnt; out.print(total); %>
<%= total + 10 %>
</body>
out.print( total + 10 );
선언부(Declaration)
클래스의 멤버인 멤버 변수, 멤버 메서드, inner class를 선언한다.
접근 권한(public, private, protected) 지정 가능하다.
선언된 변수나 메소드는 다른 메소드나 스크립틀릿, 표현식에서도 사용 가능하다.
문법은 다음과 같다.
<%! variable or method; %>
※ Example
<%@ page contentType="text/html;charset=UTF-8" %>
<%! private int a; public int getA() { return a; } public void setA(int a) { this.a=a; } %>
<% setA(10); %>
<%= getA() %> <br>
<%= a %><br>
다음 서블릿 코드와 같이 ex1_jsp 클래스의 멤버로 선언된 것을 확인할 수 있다.
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/11.0.6
* Generated at: 2025-05-04 12:23:29 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.jsp.*;
public final class ex1_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports,
org.apache.jasper.runtime.JspSourceDirectives {
private int a; public int getA() { return a; } public void setA(int a) { this.a=a; }
private static final jakarta.servlet.jsp.JspFactory _jspxFactory =
jakarta.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages = new java.util.LinkedHashSet<>(4);
_jspx_imports_packages.add("jakarta.servlet");
_jspx_imports_packages.add("jakarta.servlet.http");
_jspx_imports_packages.add("jakarta.servlet.jsp");
_jspx_imports_classes = null;
}
private volatile jakarta.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public boolean getErrorOnELNotFound() {
return false;
}
public jakarta.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
public void _jspInit() {
}
public void _jspDestroy() {
}
public void _jspService(final jakarta.servlet.http.HttpServletRequest request, final jakarta.servlet.http.HttpServletResponse response)
throws java.io.IOException, jakarta.servlet.ServletException {
if (!jakarta.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP들은 오직 GET, POST 또는 HEAD 메소드만을 허용합니다. Jasper는 OPTIONS 메소드 또한 허용합니다.");
return;
}
}
final jakarta.servlet.jsp.PageContext pageContext;
jakarta.servlet.http.HttpSession session = null;
final jakarta.servlet.ServletContext application;
final jakarta.servlet.ServletConfig config;
jakarta.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
jakarta.servlet.jsp.JspWriter _jspx_out = null;
jakarta.servlet.jsp.PageContext _jspx_page_context = null;
try {
response.setContentType("text/html;charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\n");
out.write(" ");
out.write("\n");
out.write(" ");
setA(10);
out.write("\n");
out.write(" ");
out.print( getA() );
out.write(" <br>\n");
out.write(" ");
out.print( a );
out.write("<br>");
} catch (java.lang.Throwable t) {
if (!(t instanceof jakarta.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
주석(Comment)
JSP container에 의해 서버 측에서 주석으로 처리되어 클라이언트로 전송되지 않는다.
문법은 다음과 같다.
<%-- comments --%>
또한, 스크립틀릿, 표현식, 선언부에서의 주석은 JAVA 주석(// 또는 /* */)과 동일하다.
※ Example
<%@ page contentType="text/html;charset=UTF-8" %>
<%! public int i; %>
<% /* 여러 줄 주석 */ /* 안쪽에 주석 /* 중첩 여러 줄 주석은 문법 오류 */ */ /* // 여러 줄 주석 내에 한 줄 주석은 OK */ i=5; %><br>
<%=i //주석 문법 오류: 이후에 오는 스크립틀릿을 주석으로 처리해요 %> <br>
<%=i %>
<br>
<%=i /* 주석 문법 OK*/ %><br>
<%= /*주석*/ %> <br>
<%--[참고] expression 문법 오류: expression에는 반드시 값을 지정된 변수나 상수, 반환 값을 가지는 메소드가 위치해야한다. --%>
JSP 지시어(page)
page 지시어
- 현재 JSP 페이지를 컨테이너에서 처리하기 위한 각종 속성 지정. 즉, 해당 페이지가 어떤 속성을 갖고 어떤 식으로 요청을 처리해야 하는가를 JSP 컨테이너에게 알려주는 역할이다.
- 기본 문법
<%@ page 속성1="속성1" 속성2="속성2"... %>
- 사용 예시
<%@ page contextType="text/html;charsete=utf-8" import="javax.sql.*, java.util.*" errorPage="error.jsp" %>
<%@ page import="java.util.*" %>
- page 지시어
속성 | 설명 | 기본값 |
language | 스크립트 언어를 지정한다. | java |
import | jsp 파일 내에서 사용할 외부 자바 패키지나 클래스 지정 | 없음 |
session | 세션 생성 여부 지정 | true |
buffer | 버퍼 크기 지정 | 8kb |
autoFlash | 버퍼 내용 자동 비움 지정 | true |
isThreadSafe | 단일 쓰레드 모델을 사용하여 동시성 제어 여부 지정 | true |
info | JSP 페이지 설명 | 없음 |
errorPage | 에러 발생 시 호출 페이지 지정 | 없음 |
isErrorPage | 에러만 처리하는 페이지 지정 | false |
contentType | MIME 형식과 character set 설정 | text/html;charset=ISO-8859-1 |
▶ import 속성을 제외한 나머지 속성들은 어떤 경우라도 오로지 한 번만 사용할 수 있다.
language 속성
JSP 파일 내에서 사용할 스크립트 언어를 설정한다.
<%@ page language="java" %>
extends 속성
- JSP 컨테이너가 JSP 파일을 서블릿으로 변환할 때 상속하게 되는 부모 클래스를 지정한다.
- 기본 클래스: HttpJspBase
<%@ page extends="packageName.aa.bb.cc.MyJspPage %>
※ Example
public final class ex1_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports,
org.apache.jasper.runtime.JspSourceDirectives { }
import 속성
- JSP 페이지 내에서 사용할 클래스를 지정한다.
- 쉼표를 구분자로 여러 개의 클래스 파일을 지정 가능하다.
session 속성
- 기본적으로 HTTP는 클라이언트 요청에 대한 응답 후 커넥션을 끊는다.
- 사용 용도:
- 현재 요청을 시도한 클라이언트와 이전에 요청한 클라이언트 구별
- 클라이언트의 지속적인 정보 유지
session이 false면, session의 종료가 아닌 session 내장 객체를 사용하지 않겠다는 의미다.
<%@ page session="false" %>
session이 true면, session 내장 객체를 사용한다는 의미다.
<%@ page session="true" %>
buffer 속성
out 객체에 출력할 내용을 임시로 저장할 버퍼의 사용 여부를 지정한다.
buffer가 none이면, 버퍼에 쌓아두지 않고 즉시 전송한다.
<%@ page buffer="none" %>
buffer의 크기를 다음 예시와 같이 지정할 수 있다.
<%@ page buffer="10kb" %>
버퍼가 비어지는 시점은 클라이언트로 전송되는 시점과 같다.
- 버퍼가 다 찬 경우
- 해당 페이지의 서블릿 실행을 마쳤을 때(_jspService() 메서드 종료시)
사용 용도
- 나중에라도 헤더 정보를 수정할 필요가 있을 때(예를 들어 session 정보)
- 실행 중 예외 처리 발생시 stacktrace 정보 대신 완곡한 에러메시지를 클라이언트로 전송하고자 할 때
autoFlush 속성
<%@ page autoFlush="true" %>
- 지정한 buffer가 다 채워졌거나 응답 처리 서블릿 메서드가 종료되었을 때 클라이언트로 buffer의 내용이 전송되고 buffer가 비워진다.
<%@ page autoFlush="false" %>
- buffer가 다 채워졌을 때 예외가 발생한다.
- 발생 예외 클래스는 JSP 컨테이너에 따라 다르다.
- Tomcat: IOException과 ServletException 발생
- 예외 발생으로 특정 작업을 처리할 수 있다.
- buffer="none"인 경우, autoFlush="false"를 지정할 수 없다.
- buffer의 크기를 예측할 수 없는 경우, 일반적으로 true로 설정한다.
isThreadSafe 속성
JSP 컨테이너가 thread를 생성하여 _jspService() 메서드를 사용할지의 여부를 결정한다.
기본값은 true로 병렬로 처리하고, false로 설정하면 순차적으로 처리된다.
false이면:
- 한번에 하나의 thread만 처리가 가능하다. 즉, 동시에 여러 개의 요청이 동일한 페이지에 대하여 발생할 때는 나중에 요청한 클라이언트는 먼저 요청한 클라이언트의 요청이 처리될 때까지 기다려야 한다.
- 다중 요청이 들어 왔을 때, 서블릿으로 공유되는 데이터를 수정해야 하는 경우 사용한다.
info 속성
해당 페이지의 기능이나 특징에 대한 설명을 지정한다.
jakarta.servlet.Servlet 인터페이스에 선언된 getSer5vletInfo() 메서드로 정보를 불러올 수 있다.
※ Example
<% page contentType="text/html; charset=utf-8" info="info 속성 테스트 페이지 :: 홍길동" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>info 속성 테스트</title>
</head>
<body>
<% String servletInfo=getServletInfo(); %>
<pre>
<%=servletInfo%>
</pre>
</body>
</html>
errorPage 속성
- 서블릿이 요청을 처리할 때 발생하는 예외를 처리할 페이지를 지정할 수 있다.
- 예외가 발생하기 전까지의 응답 내용이 이미 클라이언트로 전송되면 해당 페이지에 대한 출력 제어권을 다른 페이지로 넘겨줄 수 없다.
- buffer="none" 사용 시 주의
isErrorPage 속성
다른 페이지에서 발생한 예외를 처리할 페이지임을 JSP 컨테이너에게 알려주는 속성이다.
※ HTTP 응답 상태 코드
응답코드 설명 200 요청이 정상적으로 처리됨 307 임시로 페이지가 redirect됨 400 클라이언트의 요청이 잘못된 구문으로 구성됨 404 지정한 URL을 처리하기 위한 자원이 존재하지 않음 405 요청된 메서드가 허용되지 않는다. 500 서버 내부 오류(JSP에서 예외가 발생하는 경우) 503 서버가 일시적으로 서비스를 제공할 수 없음(서버 과부하이거나 보수중인 경우)
contentType 속성
클라이언트로 전송할 MIME(Multipurpose Internet Mail Extension) type과 문자셋의 인코딩 방식을 지정하는 속성이다.
pageEncoding 속성
character set에 대한 encoding 방식을 지정하는 속성이다.
contentType과 같이 사용할 경우 contentType에서 선언한 인코딩 방식과 동일해야한다.
include 속성
현재 JSP 파일에 다른 JSP나 HTML 문서를 포함시킬 수 있다.
기본 문법은 다음과 같다.
<%@ include file="포함할 파일명" %>
주의사항은 다음과 같다:
- include되는 페이지의 문자셋이 현재 페이지의 문자셋과 동일해야 한다.
- 단, Tomcat 4.x에서는 contentType을 중복 선언하지 않는다.
※ Example
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>contentType속성</title>
</head>
<body>
<h2>include 지시어 테스트1</h2>
<hr>
<%@ include file="index.jsp" %>
</body>
</html>
그러면 현재 jsp 파일과 index.jsp 파일이 같이 실행되어 한 페이지로 실행될 것이다.
taglib 속성
현재 JSP 페이지에 사용할 커스텀 태그 라이브러리를 지정할 수 있다.
- url: TLD(Tag Library Descriptor) 파일이 존재하는 URL 지정
- prefix: 사용할 custom tag들의 namespace 지정
표준화된 커스텀 태그: JSTL(JSP Standard Tag Library)
JSP Spec 1.1 이상에서 구현 API가 추가되었다(jakarta.servlet.jsp.tagext)
JSP 페이지 내에 불필요한 자바 코드를 줄일 수 있다.
기본 문법은 다음과 같다.
<%@ taglib uri="/META-INF/mytag.tld" prefix="mytag" %>
JSP 액션
액션이란?
페이지 내에서 공통적으로 요구되는 기능을 XML 기반 태그로 구현한 것을 말한다.
페이지 내에서 요청을 처리하기 위해 스크립틀릿을 사용하지 않고도 동일한 기능을 지원하는 액션 태그 사용이 가능하다.
주요 기능은 다음과 같다:
- JSP 페이지 간 흐름 제어
- 자바 빈즈 컴포넌트와 상호작용 지원
- 자바 애플릿 지원
액션 태그 목록
액션 | 사용법 | 기능 |
include | <jsp:include page="xx.jsp" /> | 다른 페이지를 현재 페이지에 포함 |
forward | <jsp:forward page="xx.jsp" /> | 현재 페이지의 제어를 다른 페이지로 전달 |
beans | <jsp:useBean scope="page" id="cls" class="xx.myBean" /> | xx 패키지의 myBean 클래스를 cls로 page 범위에서 사용할 것을 선언 |
<jsp:setProperty name="cls" property="xxx"/> | useBean으로 선언된 빈즈 클래스의 setXxx() 메서드를 호출 | |
<jsp:getProperty name="cls" property="xxx"/> | useBean으로 선언된 빈즈 클래스의 getXxx() 메서드를 호출 |
include 액션
include 지시어와 유사하게 다른 페이지를 import한다.
include 지시어와의 차이점:
- include 지시어와 달리, include 되는 JSP 페이지가 수정되는 경우 원래 페이지가 수정되지 않더라도 include되는 JSP 페이지의 새로운 서블릿 코드를 생성한다.
- 즉, 실행 시점에 해당 파일을 호출하고 결과를 포함시킨다(단, 파일은 이미 컴파일 되어 있음).
- 파라미터를 전달할 수 있다.
동적 include라고도 한다.
forward 액션
현재 페이지의 제어권을 완전히 다른 페이지로 전달한다.
브라우저 URL에는 최종 전달된 파일명이 보이는 것이 아니라 최초 호출한 파일명이 보인다.
<jsp:param/>
- <jsp:forward/> 또는 <jsp:include/>를 사용하여 설정한 parameter 값을 지정한 uriPath로 넘겨준다.
- forward 또는 include 된 JSP 파일에서 request.getParameter("ParamName") 메소드로 값을 알아낼 수 있다.
JSP 내장객체
JSP 내장 객체 개요
- 지시어와 스크립트 요소 자체로는 JSP 페이지 서블릿의 유기적인 관계를 정의하고 해당 서블릿 인스턴스가 실행되는 런타임 환경 정보를 얻거나 기타 자바의 서블릿/JSP API가 제공하는 기능 활용이 불가능하다.
- JSP에서 선언하지 않고 사용할 수 있는 객체다.
- 컨테이너에 의해 미리 선언된 자바클래스의 참조 변수이다.
- 스크립틀릿이나 표현식에서 사용할 수 있다.
- jakarta.servlet 패키지에 8개, java.lang 패키지에 1개의 객체 참조변수가 정의된다.
주요 활용
- HTML 폼에서 입력한 값을 가져올 때
- 세션 관련 작업을 처리할 때
- 스크립트릿에서 브라우저 출력이 필요할 때
- 사용자 요청을 다른 페이지로 전달할 때
- 현재 JSP에 대한 각종 정보를 알고자 할 때
참조 변수명(내장 객체) | 자바 클래스와 주요 역할 |
request | jakarta.servlet.http.HTTPServletRequest HTML form 요소 선택 값과 같은 사용자 입력 정보를 읽어올 때 사용한다. |
response | jakarta.servlet.http.HTTPServletResponse 사용자 요청에 대한 응답을 처리할 때 사용한다. |
pageContext | jakarta.servlet.http.PageContext 현재 JSP 실행에 대한 context 정보를 참조하기 위해 사용한다. |
session | jakarta.servlet.http.HttpSession 클라이언트 세션 정보를 처리하기 위해 사용한다. |
application | jakarta.servlet.http.ServletContext 웹 서버의 애플리케이션 처리와 관련된 정보를 참조하기 위해 사용한다. |
out | jakarta.servlet.http.JspWriter 사용자에게 전달하기 위한 output 스트림 처리하기 위해 사용한다. |
config | jakarta.servlet.jsp.HttpConfig 현재 JSP에 대한 초기화 환경을 처리하기 위해 사용한다. |
page | jakarta.servlet.jsp.HttpJspPage 현재 JSP 페이지에 대한 클래스 정보를 처리하기 위해 사용한다. |
exception | java.lang.Throwable 예외 처리를 위해 사용한다. |
GET method
- 폼 데이터가 서버로 전송될 때, 요청 패킷의 헤더를 통해 전달하는 방식이다.
- 데이터 부분 대신 URL에 ? 문자를 붙이고 뒤이어 폼 데이터를 전송한다.
- 서버의 입력 버퍼 크기에 제한을 받는다.
- 폼 데이터가 전달될 때 명령 라인 argument를 통해 전달되므로 폼 데이터가 상당히 큰 경우 데이터 손실이 가능하다.
- 전송 데이터 크기가 작고 데이터 내용이 노출되어도 무관할 때 사용한다.
POST method
- 클라이언트가 웹 서버로 요청 패킷을 보낼 때, 요청 헤더가 아닌 데이터 부분에 폼 데이터를 전송하는 방식이다.
- 데이터 내용이 명령 표시줄(주소 표시줄)에 나타나지 않는다.
- 전송 데이터 크기가 크거나 URL에 데이터 내용을 감추고자 할 때 사용한다.
request 객체
- jakarta.servlet.http.HttpServletRequest
- 주요 기능:
- 사용자 요청(request)과 관련된 정보를 처리할 때 사용한다.
- 주로 HTML 폼을 통해 전달된 값을 가져올 때 사용한다.
메소드 | 설명 |
getParameterNames() | 현재 요청에 포함된 인수 이름을 enumeration 형태로 전달한다. |
getParameter(name) | 문자열 name과 같은 이름을 가진 인수 값을 가져온다. |
getParameterValues(name) | 문자열 name과 같은 이름을 가진 인수 값을 배열 형태로 가져온다. checkbox, multiple list 등에 주로 사용된다. |
getCookies() | 모든 쿠키 값을 jakarta.servlet.http.Cookie의 배열 형태로 가져온다. |
getMethod() | 현재 요청이 GET, POST인지 가져온다. |
getSession() | 현재 세션 객체를 가져온다. |
getRemoteAddr() | 클라이언트 IP 주소를 알려준다. |
getProtocol() | 현재 서버의 프로토콜을 문자열 형태로 알려준다. |
setCharacterEncoding() | 현재 jsp로 전달되는 내용을 지정한 character 셋으로 변환한다. html form에서 한글 입력 시 정상적으로 처리하려면 반드시 필요하다. |
response
- jakarta.servlet.http.HttpServletResponse
- 주요 기능:
- 사용자 요청에 대한 응답 처리, 페이지 전환
메소드 | 설명 |
setContentType(String type) | 문자열 형태의 MIME type으로 ContentType 설정 |
setHeader(String name, String value) | 문자열 name 이름으로 문자열 value값을 헤더로 설정 |
setDataHeader(String name, long data) | 문자열 name 이름으로 data에 설정된 밀리세컨드 시간 값을 헤더에 설정 |
sendError(int status, String msg) | 에러 코드를 세팅하고 메시지 보냄 |
sendRequest(String url) | 클라이언트 요청을 지정된 url 페이지로 보냄 |
addCookie(Cookie cookie) | 응답으로 지정된 쿠키를 추가한다. |
pageContext
- jakarta.servlet.PageContext
- 주요 기능:
- JSP 페이지와 관련된 프로그램 코드에서 다른 내장 객체를 얻거나 하나의 페이지에서 다른 페이지로 요청 처리 제어권을 임시, 혹은 영구적으로 넘겨주는데 사용한다.
- request, session, application과 같은 내장 객체의 속성(attribute) 관리
- <%@ page language=java...%>인 경우 크게 의미는 없음
session
- jakarta.servlet.http.HttpSession
- 주요 기능:
- 클라이언트와의 지속적인 연결 유지를 위한 세션 처리
- 세션은 하나의 애플리케이션 내에서만 유효함
- 두 개의 서로 다른 애플리케이션에서는 쿠키를 사용해야 한다.
메서드 | 설명 |
getId() | 각 접속에 대한 세션의 고유 ID를 문자열 형태로 반환 |
getCreatingTime() | 세션이 생성된 시간을 January 1, 1970 GMT.부터 long형 백분 초 값으로 반환 |
getLastAccessedTime() | 현재 세션으로 마지막 작업한 시간을 long형 백분초 값으로 반환 |
getMaxInactiveInterval() | 세션 유지 시간을 초로 반환 → 세션 유효 시간을 알 수 있다. |
setMaxInactiveInterval(t) | 세션 유효 시간을 t에 설정된 초 값으로 설정 |
invalidate() | 현재 세션을 종료한다. 세션과 관련한 값을 모두 지운다. |
getAttribute(attr) | 문자열 attr로 설정된 세션 값을 java.lang.Object 형태로 반환한다. |
setAttribute(name, attr) | 문자열 name으로 java.lang.Object attr을 설정한다. |
application
- jakarta.servlet.http.ServletContext
- 주요 기능:
- 특정 웹 애플리케이션에서 실행되는 실행 환경에 대한 정보를 담고 있는 객체
- 개발자를 위한 서버 정보, 서버의 각종 자원 정보, 로그 관련 정보, application scope의 속성 관련 정보
- 개발자를 위한 애플리케이션 실행 환경을 제공하는 서버 정보 관련 메소드
메소드 | 설명 |
getServerInfo() | JSP/서블릿 컨테이너 이름과 버전 반환 |
getMajorVersion() | 컨테이너가 지원하는 서블릿 API의 Major 버전 정보 반환 |
getMinorVersion() | 컨테이너가 지원하는 서블릿 API의 Minor 버전 정보 반환 |
getMimeType(filename) | 문자열 filename에 지정된 파일에 대한 MIME type을 반환 |
getResource(path) | 문자열 path에 지정된 자원을 URL 객체로 반환 |
getResourceAsStream(path) | 문자열 path에 지정된 자원을 InputStream 객체로 반환 |
getRealPath(path) | 문자열 path에 지정된 자원을 파일 시스템의 실제 경로로 반환 |
getContext(path) | 문자열 path에 지정된 자원의 컨텍스트 정보를 반환 |
getResourceDispatcher(path) | 문자열 path에 지정된 자원을 위한 request dispatcher를 생성 |
log(message) | 문자열 message 내용을 로그 파일에 기록 로그 파일 위치는 컨테이너에 따라 다름 |
log(message, exception) | 예외 상황과 관련한 정보를 포함하여 로그 파일에 기록 |
getAttribute(String name) | 문자열 name에 해당하는 속성값이 있다면 Object 형태로 가져옴. 반환 값에 대한 적절한 형 변환이 필요 |
getAttributeNames() | 현재 application 객체에 저장된 속성 이름을 Enumeration 형태로 가져옴 |
setAttribute(String name, Object value) | 문자열 name 이름으로 Object형 데이터를 저장. Object형이므로 자바 클래스 형태로도 저장 가능 |
removeAttribute(String name) | 문자열 name에 해당한느 속성을 삭제 |
out
- jakarta.servlet.jsp.JspWriter
- 주요 기능:
- 서블릿 요청을 처리하여 응답을 전송할 때 전송할 응답에 대한 출력 스트림 객체
- 스크립틀릿에서 브라우저 출력, 버퍼 컨트롤
메소드 | 설명 |
getBufferSize() | output buffer 크기를 바이트로 알려준다. |
getRemaining() | 남아 있는 버퍼 크기 중 사용 가능한 비율을 알려준다. |
clearBuffer() | 버퍼에 있는 컨텐츠를 모두 지운다. |
flush() | 버퍼를 비우고 output stream도 비운다. |
close() | output stream을 닫고 버퍼를 비운다. |
println(content) | content에 내용을 newline과 함께 출력한다. |
print(content) | content에 내용을 출력한다. |
config
- jakarta.servlet.ServletConfig
- 주요 기능:
- JSP 페이지에 대한 서블릿 인스턴스가 참조하게 될 초기 설정 데이터에 대한 정보를 담고 있는 객체
- 애플리케이션에서 공유할 수 있는 초기화 변수 접근
- web.xml에 초기화 파라미터가 설정되어야 함
- 애플리케이션의 ServletContext 객체를 가져옴
메소드 | 설명 |
public Enumeration getInitParameterNames() | 초기 파라미터 값의 설정 이름을 Enumeration 객체로 리턴 |
public String getInitParameter(name) | 문자열 name에 해당하는 초기화 파라미터 값을 리턴 |
public ServletContext getServletContext() | 현재 애플리케이션의 ServletContext 객체를 반환. 내장 객체인 application과 동일한 객체 참조 |
page
- javax.servlet.jsp.HttpJspPage
- 주요 기능:
- 해당 페이지 서블릿 인스턴스 자체를 나타내는 객체(Java의 this와 동일한 의미)
- JSP 파일에서 자기자신을 참조할 때 사용함
- 즉, 다른 스크립트 언어를 사용할 때, 내장 객체 page를 이용하여 페이지 서블릿 인스턴스 객체에 접근 가능하다.
- jakarta.servlet.jsp.HttpJspPage 인터페이스의 메소드 이용 가능
- <%@ page language=java...%>인 경우 크게 의미 없음
exception
- java.lang.Throwable
- 주요 기능:
- JSP 페이지 작성자가 페이지에서 발생한 예외를 처리할 페이지를 지정한 경우, 지정된 에러 페이지에 전달되는 예외 객체다.
- page 지시어에 isErrorPage="true"로 지정된 에러 페이지에서 사용한다.
- 현재 호출된 에러 정보를 제공한다.
메소드 | 설명 |
public String getMessage() | 문자열로 된 에러 메시지를 반환한다. |
public void printStackTrace() | 표준 출력 스트림으로 스택 추적 정보를 출력한다. |
public String toString() | 예외 클래스 이름과 함께 에러 메시지를 반환한다. |
영역(scope) 객체와 속성
영역
정의된 속성의 유효한 범위를 말한다.
영역(Scope) 객체
영역 내의 속성을 정의하거나 정의된 속성을 다시 얻어내기 위한 내장 객체를 말한다.
영역에 따른 내장 객체들의 유효 범위
영역 종류 | 속성 유효 범위 | 사용 영역 객체 |
page | 해당 페이지가 요청을 시도한 클라이언트에 서비스를 제공하는 동안 유효(서블릿 인스턴스의 _jspService() 메소드가 실행되는 동안 유효) | pageContext(request, session, application 정보도 얻을 수 있음) |
request | 클라이언트 요청이 처리되는 동안 유효 | request |
session | 세션이 유지되는 동안 유효 | session |
application | 해당 애플리케이션이 실행되는 동안 유효 | application |
영역 객체의 속성
다음은 pageContext, request, session, application 객체의 속성 관련 메소드이다.
메소드 | 기능 |
public Object getAttribute(String key) | key 값으로 등록된 속성을 Object형으로 리턴(key값으로 등록된 속성이 존재하지 않는 경우 null 리턴) |
public void setAttribute(String key, Object value) | 속성값을 key로 등록 |
public Enumeration getAttributeNames() | 해당 영역에 지정된 속성들의 이름을 Enumeration으로 리턴(지정된 속성이 없는 경우 empty Enumeration 리턴) |
public void removeAttribute(String key) | key값에 대응하는 해당 영역의 속성을 삭제 |
▶ key의 속성 값을 Object형으로 등록하기 때문에, Object를 반환하는 getAttribute() 메소드를 사용 시, 다운캐스팅하여 형변환 후 사용하도록 한다.
'대학 강의 > 인터넷 프로그래밍' 카테고리의 다른 글
JavaScript Overview (0) | 2025.04.02 |
---|---|
인터넷 프로그래밍 개요 (0) | 2025.03.24 |
CSS3 (0) | 2025.03.23 |
HTML5 기본 (0) | 2025.03.17 |