JSP?
먼 옛날. 서블릿 위에 html태그를 써서 화면으로 전달하던 시절. 디자이너와 개발자는 서로 얼굴 붉힐 일이 많았을 것이다. 이런 일이 있었다. 디자이너는 오늘 일찍 퇴근해서 애인과 종로에서 가장 오래된 레스토랑인 아지오에 갈 생각이다. 그런데 개발자라는 작자가 작업을 끝내지 못해서 오전 내 작업을 못하고 있다. 오후 세시께야 파일을 받았다. 디자이너는 세 시간 안에 작업을 끝내겠다는 생각으로 열의를 불태운다. 흠. 너무 과했던 모양이다. 실수로 자바 코드 몇 개를 건드렸는데...controll + z도 안 먹는다... 그렇게 디자이너와 개발자 사이는 비포장도로처럼 위태로워졌을 것이며 어쩌면 타이어에 펑크가 났을지도 모르는 일이다.
이런 배경에서 누군가. 그러니까 평화를 지향하던 인간 하나가 JSP를 들고 나타났다. JSP가 Java Server Pages가 약자가 아니라 Java Server Peace😇의 약자라는 전설이 그래서 도는 것이다. 물론 이건 내가 지어낸 얘기일 뿐이다.
그랬거나
말거나.
정리하자면,
JSP란, 화면과 비즈니스 로직을 분리해서 개발하려는 목적으로 고안된 것이다. 이렇게 하면 협업도 쉽고, 당연히 유지보수도 쉽다.
JSP는 서버사이드 스크립트 언어다. 확장자는 .jsp이며 HTML의 외향을 두르고 있지만 컴파일 되면서 서블릿 컨테이너에 의해 서블릿으로 바뀐다. 말하자면 결국 자바 클래스라는 것이다.
JSP의 구성 요소
- HTML , CSS , JS
- JSP 기본 태그
- JSP 액션 태그
- 사용자 정의 태그 또는 프레임워크가 제공하는 커스텀 태그
JSP가 동작하는 방식
자바스크립트는 브라우저가 해석할 수 있는, 클라이언트 사이드 스크립트 언어다. 반면 위에서 설명했듯이 jsp는 서버사이드 스크립트 언어다. 브라우저는 JSP를 해석할 수 없다. 따라서 실행 시에 서블릿(톰캣) 컨테이너가 .jsp파일을 자바코드로 컴파일 하는 과정을 거친다.
-
변환- 컨테이너는 JSP파일을 자바 파일로 변환한다.
-
컴파일 - 컨테이너는 변환한 .java파일을 클래스 파일로 컴파일 한다.
-
실행 - 컨테이너는 .class파일을 실행하여 그 결과html,css,js를 브라우저로 전송한다.
서블릿 컨테이너에 의해 .jsp에서 .java변환된 클래스 파일은 이클립스의 경우 '\eclipse-workspace.metadata.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\ROOT\org\apache\jsp\test' 이 경로에서 볼 수 있다.
구성 요소
JSP에서 HTML 태그와 같이 사용하는 여러 요소다.
- 디렉티브 태그
- 스크립트 요소 : 주석문, 스크립트릿scriptlet, 표현식, 선언식
- 표현 언어Expression Language
- 내장 객체
- 액션 태그
- 커스텀 태그
디렉티브 태그Directive Tag
디렉티브 태그는 전반적인 설정 정보를 저장할 때 사용한다.
몇 가지 종류가 있다.
- 페이지 디렉티브 태그 - 전반적인 정보를 설정할 때 사용
- 인클루드 디렉티브 태그 - 공통으로 사용하는 jsp페이지를 다른 jsp페이지에 추가할 때 사용
- 태그라이브 디렉티브 태그 - 개발자나 프레임워크에서 제공하는 태그를 쓸 때 사용
페이지 디렉티브 태그Page Directive Tag
형식은 <%page %> 이렇게 쓴다.
jsp파일을 만들면 맨 첫 줄에 나오는 태그가 페이지 디렉티브 태그다.
<%@page language="java" contentType="text/html;charset=UTF-8"
pageEncoding="UTF-8"%>
간단한 예제.
명시적으로 지정했지만, 아래 나온 값은 몇 가지를 제외한 대부분 기본값이므로 따로 지정하지 않아도 된다.
<%@page contentType="text/html;charset=utf-8;" //출력 형식
import="java.util.*" //다른 패키지의 클래스를 임포트할 때 지정해야 함
language="java" //jsp에서 사용할 언어
session="true" //HttpSession객체 사용 여부
buffer="8kb" //버퍼 크기
autoFlush="true" //출력되기 전 버퍼가 다 채워질 경우 동작을 지정
info="(Shoppingmall.........)" //페이지 설명
isErrorPage="false" //현재 페이지가 예외 처리 담당 jsp인지 지정
errorPage=""%>
인클루드 디렉티브 태그Include Directive Tag
한 웹에서 페이지 이동을 할 때, 윗부분header과 아랫부분footer은 동일하고 가운데 부분만 달라질 때가 많다. 인클루드 태그를 이용해서 헤더와 푸터를 공통적으로 중복을 제거하고 하나의 코드를 여러 jsp가 공유해서 재사용할 수 있다. 관리도 편하다.
<!-- 공통되는 부분은 include로 -->
<%include file="../header.jsp" %>
<!-- 각 페이지 고유한 부분 -->
<%include file="../footer.jsp" %>
스크립트 요소
JSP는 컴파일 되면서 자바 코드로 바뀐다고 했다. 이 말은 조건이나 상황에 맞게 html태그를 선택할 수 있다. 따라서 동적인 화면 구성을 할 수 있다.
스크립트 요소란, <% %>안에 자바 코드를 구현하는 것을 말한다. <% %>기호를 스크립트릿scriptlet이라고 부른다.
스크립트릿의 종류 세 가지
- 선언문 : 변수나 메서드를 선언할 때 사용
- 스크립트릿 : 자바 코드를 작성할 때 사용
- 표현식 : 변수 값을 출력할 때 사용
선언문
형식은 <%! .... %>이다.
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%!
private String name = "코코";
public String getName() {
return this.name;
}
%>
...
...
<h2>안녕하세요 <%=getName()%>님~</h2>
</body>
</html>
스크립트릿
초기 JSP에서 자바코드를 이용해 동적인 화면을 구성했다. 현재는 잘 쓰지 않는다.
<% 코드 %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%! /* 선언문 */
private String name = "뽀로로";
public String getName() {
return this.name;
}
%>
<% /* 스크립트릿 */
String age = request.getParameter("age");
%>
...
...
<h1>이름 <%=getName()%>, 나이 <%=age%></h1>
</body>
</html>
표현식
위 예제에서 변수 값을 가져올 때 썼던 <%= ...%>다.
<h1>이름 <%=getName()%>, 나이 <%=age%></h1>
<%=Integer.parseInt(age)+10 %>
표현식은 당연히 연산도 가능하다.
tip. JSP 프리컴파일
컴파일 시 JSP는 서블릿으로 변환된다. 때문에 처음 접속 시 속도가 느릴 수 있다. 이 시간을 단축하기 위해 톰캣 컨테이너는 JSP Precomile을 제공한다. 이것을 이용하면 미리 JSP파일을 컴파일해둘 수 있다. load-on-startup과 유사하다.
내장객체
서블릿으로 컴파일된 JSP의 일부다.
package org.apache.jsp.test;
import ...
public final class emtpy_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
....
...
//JSP페이지에 대한 정보를 저장한다.
final javax.servlet.jsp.PageContext pageContext;
//세션 정보를 저장한다.
javax.servlet.http.HttpSession session = null;
//컨텍스트 정보를 저장한다.
final javax.servlet.ServletContext application;
//JSP페이지에 대한 설정 정보를 저장한다.
final javax.servlet.ServletConfig config;
//JSP페이지에서 결과를 출력한다.
javax.servlet.jsp.JspWriter out = null;
//JSP페이지의 서블릿 인스턴스를 저장한다.
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
....
...
..
}
위에 선언되어 있는 것이 JSP의 내장객체다. 이외에도 HttpServletRequest나 HttpServletResponse 등이 있다. 이렇게 내장객체가 있기 때문에 HttpServletRequest 또는 HttpSession을 별도의 생성 없이 사용할 수 있는 것이다. 내장하지 않은 객체를 사용하고 싶다면 그냥 import하고 쓰면 된다.
내장 객체의 스코프
내장 객체 | 서블릿 | scope |
---|---|---|
page | this | 한 번의 요청에 대해 하나의 JSP페이지를 공유한다 |
request | HttpServletRequest | 한번의 요청에 대해 같은 요청을 공유하는 JSP를 공유한다 |
session | HttpSession | 같은 브라우저에서 공유한다. |
application | ServletContext | 같은 애플리케이션에서 공유한다. |
서블릿 스코프와 별반 다르지 않다.
'Servlet-JSP' 카테고리의 다른 글
표현언어(EL, Expression Language) (0) | 2020.09.11 |
---|---|
액션 태그 (0) | 2020.09.11 |
서블릿 리스너 (0) | 2020.09.11 |
Servlet Filter (0) | 2020.09.11 |
서블릿 스코프 (0) | 2020.09.11 |