Day73 Java프로그래밍 기초(JSP/EL)
JSP
1. JSP의 구조
- JSP Engine을 이용하여 Servlet 구현체를 만드는 과정이다.
- JSP의 구조는 다음과 같다.
2. JSP의 구동원리
- JSP는 아래 순서와 같이 구동한다.
- 웹브라우저가 서블릿 컨테이너를 호출한다.
- 서블릿 컨테이너가 JSP의 서블릿 객체를 찾는다. 1) 서블릿 객체가 있으면 service() -> _jspService() 를 호출한다. 2) 서블릿 객체가 없으면, JSP파일로 .class 파일을 컴파일 후 호출한다.
- 웹브라우저에 결과를 리턴한다.
- JSP 파일은 Python이나 PHP 처럼 직접 그 스크립트가 인터프리팅이 아니다.
- JSP 파일을 분석해서 JSP Engine이 class파일을 생성하는 template 기술이다.
- JSP 파일로 Servlet을 구현하기위해서는 HttpJspPage를 구현해야한다.
3. JSP의 구성요소
1) Template Data
- JSP 파일에 작성된 텍스트는 자바 출력 코드를 생성한다.
JSP 코드
1
<h1>템플릿 데이터(template data)</h1>
Java.class
1
out.write("템플릿 데이터(template data)")
2) Scriptlet
3) Expression element
- 표현식은 할당된 값을 리턴하는 문장을 말한다.
- 결과 값을 출력하기위해서 사용되는 요소이다.
- 문장 끝에 ; 을 사용하지 않는다.
주로 객체의 값을 웹에 출력하거나 연산결과를 HTML에 삽입할 때 사용된다.
JSP 코드
1 2 3 4 5
<% String name="집에가고싶다" %> <%=name%>
Java.class
1 2
String name = "집에가고싶다" out.write(name);
4) Declaration element
- 선언부는 클래스에 멤버를 추가할 때 사용한다.
- jspInit()나 jspDestroy()와 같은 메서드를 오버라이딩 할 때도 사용할 수 있다.
선언되는 위치에 상관없이 _jspService()전에 삽입된다.
JSP 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
<%! // 다음과 같이 상속 받은 메서드를 오버라이딩 할 수 있다. public void jspInit() { System.out.println("ex06.jsp의 jspInit()"); } %> <body> <h1>선언부(declaration element)</h1> 100,000,000 입금 = <%=calculate(100000000)%> </body> <%! double interest = 0.025; // 인스턴스 변수 private String calculate(long money) { // 인스턴스 메서드 return String.format("%.2f", money + (money * interest)); } %> <%! { // 인스턴스 블록 System.out.println("ex06 인스턴스 생성!"); } %>
Java.class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
{ // 인스턴스 블록 System.out.println("ex06 인스턴스 생성!"); } public void jspInit() { System.out.println("ex06.jsp의 jspInit()"); } private String calculate(long money) { // 인스턴스 메서드 return String.format("%.2f", money + (money * interest)); } double interest = 0.025; // 인스턴스 변수 protected void _jspService(){ out.write("<body>"); out.write("<h1>선언부(declaration element)</h1>"); out.write("100,000,000 입금 = "+ calculate(100000000)"); out.write("</body>"); }
5) Page(Directive element)
- 서블릿 실행과 관련하여 특정 기능을 설정한다.
- language: JSP에서 사용할 언어를 지정 (기본값은
java
). - contentType: 클라이언트로 전송될 응답의 MIME 타입과 문자 인코딩을 설정 (
text/html; charset=UTF-8
). - pageEncoding: JSP 파일 자체의 인코딩 방식 설정 (예:
UTF-8
). - import: JSP에서 사용할 자바 클래스를 임포트 (여러 클래스를 쉼표로 구분하여 한 번에 임포트 가능).
- trimDirectiveWhitespaces: JSP 페이지에서 불필요한 공백을 제거할지 여부 설정 (
true
로 설정 시 공백 제거). - buffer: 클라이언트로 전송할 데이터를 임시로 저장할 버퍼 크기 설정 (예:
8kb
). autoFlush: 버퍼가 가득 찼을 때 자동으로 클라이언트로 데이터를 전송할지 여부 설정 (
false
로 설정 시 자동 전송 안 함).1 2 3 4 5 6 7 8 9 10 11
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.net.Socket" import="java.net.ServerSocket" import="java.util.List,java.util.Map,java.util.Set" trimDirectiveWhitespaces="true" buffer="8kb" autoFlush="false" %>
6) Include(Directive element)
- 지정한 파일을 JSP로 포함시킨 후에 자바 서블릿 클래스를 생성한다.
- 일반 텍스트 파일이면 된다. JSP 파일일 필요가 없다.
RequestDispatcher의 include()와 다르다.
1
<%@ include file="./ex08_header.txt"%>
7) Tablib(Directive element)
- 외부에 따로 정의된 JSP 확장 태그를 가져올 때 사용한다.
- JSP 명세에 추가로 정의된 태그는 JSTL이라 한다.
8) action tage(Directive element)
- JSP에서 기본으로 제공하는 JSP 전용 태그이다.
jsp:useBean
- JSP에서 사용할 객체를 생성할 때 사용할 수 있다.
- 보관소(ServletContext, HttpSession, ServletRequest, PageContext)에 저장된 객체를 꺼낼 때도 사용한다.
-
- scope : 객체를 꺼내거나 생성된 객체를 저장할 보관소 이름, 기본이 page이다.
- id : 객체를 꺼내거나 저장 할 때 사용할 이름이다.
- class : 보관소에서 객체를 찾을 수 없을 때 생성할 객체의 클래스명이다.
- type : 보관소에서 꺼낸 객체의 타입을 지정할 때 사용한다.
jsp:setProperty
-
- name:
jsp:useBean
에서 정의된 빈 객체의 id를 지정합니다. 이 빈 객체에 대해 속성을 설정한다. - property: 빈 객체의 속성 이름을 지정합니다. 이 속성에 값을 설정한다.
- 특별한 값으로
*
를 사용할 수 있는데, 이 경우 요청의 모든 매개변수를 자바빈의 동일한 이름을 가진 속성에 자동으로 매핑한다. - value: 속성에 설정할 값을 직접 지정합니다. 이 값은 속성에 할당된다.
jsp:include
jsp:forward
- 다른 페이지로 실행을 위임할 때 사용한다.
- 제어권이 넘어가면 되돌아 오지 않는다.
- page 속성에 지정하는 URL은 서블릿/JSP 이어야 한다.
9) errorPage
- JSP를 실행하는 중에 오류가 발생했을 때 실행할 JSP를 지정할 수 있다.
- <%@ page errorPage=”URL”%>
Expression Language 표기법
1. 용어정의
1) EL(Expression Language)
- EL(Expression Language)은 콤마(.)와 대괄호([]) 등을 사용하여 객체의 프로퍼티나, 리스트, 셋, 맵 객체의 값을 꺼내고 설정하는 문법이다.
- 단순화된 표현: JavaBean, Map, List, 배열 등의 데이터를 간단한 표현식으로 접근 가능하다.
- 점 표기법(Dot Notation): 객체의 속성에 접근할 때 점(.)을 사용한다.
- 대괄호 표기법(Bracket Notation): 배열이나 컬렉션의 특정 요소에 접근할 때 대괄호(
[]
) 사용한다. - 기본 변수 접근:
request
,session
,application
등의 범위 내에서 설정된 데이터에 간편하게 접근한다.
2) OGNL(Object Graph Navigation Language)의 정의
- Java 언어에서 객체 그래프를 탐색하고 조작하기 위한 표현 언어다.
- 객체의 프로퍼티 값을 가리킬 때 사용하는 문법이다.
- 파일의 경로처럼 객체에 포함된 객체를 탐색하여 값을 쉽게 조회할 수 있다.
3) 객체 그래프(Object Graph)
- 객체들 간에 관계를 나타내는 그래프 구조다.
- 객체 그래프는 복잡한 데이터 구조를 표현하고 탐색하는 데 유용하며, 객체 간의 다양한 관계를 표현할 수 있다.
- 객체 그래프를 사용하면 데이터를 계층적으로 구조화하고 관리할 수 있으며, 객체 간의 연결성을 효율적으로 관리할 수 있다.
EL 기본기능
1) 문법
1
2
${ 객체명.프로퍼티명.프로퍼티명.프로퍼티명 }
${ 객체명["프로퍼티명"]["프로퍼티명"]["프로퍼티명"] }
2) EL에서 사용할 수 있는 빌트인 객체
- pageContext : JSP의 PageContext 객체
- servletContext : ${ pageContext.servletContext.프로퍼티명 } => 자바코드 => pageContext.getServletContext().get프로퍼티()
- session : ${ pageContext.session.프로퍼티명 } => pageContext.getSession().get프로퍼티명();
- request: ${ pageContext.request.프로퍼티명 }
- response : ${ pageContext.response.프로퍼티명 }
- param : ${ param.파라미터명 } => request.getParameter(“파라미터명”);
- paramValues : ${ paramValues.파라미터명 } => request.getParameterValues(“파라미터명”);
- header : ${ header.헤더명 } => request.getHeader(“헤더명”);
- headerValues : ${ headerValues.헤더명 } => request.getHeaders(“헤더명”);
- cookie
- ${ cookie.쿠키명 }
- ${ cookie.쿠키명.name }
- ${ cookie.쿠키명.value }
- initParam : ${ initParam.파라미터명 }
보관소에서 값 꺼내기
- 보관소명.프로퍼티명을 사용하여 보관소에서 값을 꺼낸다.
- 보관소의 이름을 지정하지 않으면 다음 순서로 값을 찾는다.
- pageScope ==> requestScope ==> sessionScope ==> applicationScope
보관소에 저장된 값을 찾지 못하면 빈 문자열을 리턴한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
<h1>EL - 보관소에 값 꺼내기</h1> <% pageContext.setAttribute("name", "홍길동"); request.setAttribute("name", "임꺽정"); session.setAttribute("name", "유관순"); application.setAttribute("name", "안중근"); %> PageContext 보관소 : ${pageScope.name}<br> PageContext 보관소 : <%=pageContext.getAttribute("name")%><br> ServletRequest 보관소 : ${requestScope.name}<br> ServletRequest 보관소 : <%=request.getAttribute("name")%><br> HttpSession 보관소 : ${sessionScope.name}<br> HttpSession 보관소 : <%=session.getAttribute("name")%><br> ServletContext 보관소 : ${applicationScope.name}<br> ServletContext 보관소 : <%=application.getAttribute("name")%><br>
EL은 로컨 변수를 사용할 수 없다. 아래의 배열에서는 값을 꺼낼 수 없다.
1
String[] names = new String[]{"홍길동","임꺽정","유관순"};
EL은 오직 보관소에 저장된 값을 꺼낼 수 있다.
1 2 3 4 5 6 7 8
<% pageContext.setAttribute("names", new String[]{"홍길동","임꺽정","유관순"}); %> ${names[0]}<br> ${names[1]}<br> ${names[2]}<br> ${names[3]}<br>
EL 연산자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<h1>EL - 연산자</h1>
<h2>산술연산자</h2>
100 + 200 = ${100 + 200}<br>
100 - 200 = ${100 - 200}<br>
100 * 200 = ${100 * 200}<br>
100 / 200 = ${100 / 200}<br>
100 div 200 = ${100 div 200}<br>
100 % 200 = ${100 % 200}<br>
100 mod 200 = ${100 mod 200}<br>
<h2>논리연산자</h2>
true && false = ${true && false}<br>
true and false = ${true and false}<br>
true || false = ${true || false}<br>
true or false = ${true or false}<br>
!true = ${!true}<br>
not true = ${not true}<br>
<h2>관계 연산자</h2>
100 == 200 = ${100 == 200}<br>
100 eq 200 = ${100 eq 200}<br>
100 != 200 = ${100 != 200}<br>
100 ne 200 = ${100 ne 200}<br>
100 > 200 = ${100 > 200}<br>
100 gt 200 = ${100 gt 200}<br>
100 >= 200 = ${100 >= 200}<br>
100 ge 200 = ${100 ge 200}<br>
100 < 200 = ${100 < 200}<br>
100 lt 200 = ${100 lt 200}<br>
100 <= 200 = ${100 <= 200}<br>
100 le 200 = ${100 le 200}<br>
<h2>empty</h2>
<p>보관소에 해당 객체가 없는지 검사한다. 없으면 true, 있으면 false.</p>
<%
pageContext.setAttribute("name", new String("홍길동"));
%>
name 값이 없는가? ${empty name}<br>
name2 값이 없는가? ${empty name2}<br>
<h2>조건 연산자 - 조건 ? 식1 : 식2 </h2>
name == "홍길동" : ${name == "홍길동" ? "맞다!" : "아니다!"}<br>
<%
String a = "홍길동";
String b = new String("홍길동");
if (a == b) { // 인스턴스의 주소를 비교!
out.println("== : 같다!<br>");
} else {
out.println("== : 다르다!<br>");
}
if (a.equals(b)) { // 인스턴스의 값을 비교!
out.println("equals() : 같다!<br>");
} else {
out.println("equals() : 다르다!<br>");
}
%>
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.