EL에 대하여 알아보자
06_Web-workspace2 에 Action-Project 동적 웹 프로젝트 생성
![](https://blog.kakaocdn.net/dn/bOu2ye/btrQI7Psars/KHo5SZcNdlosuqpxTwkzF0/img.png)
![](https://blog.kakaocdn.net/dn/nkBUN/btrQK1fWt9l/zYYMWJXixIuPEL3IKU65lk/img.png)
![](https://blog.kakaocdn.net/dn/bx7I5e/btrQJpB5KLW/HWMeA1vUXkqOLw66tNFUk1/img.png)
index.jsp 생성 후 서버에 올리기
![](https://blog.kakaocdn.net/dn/bdBBXx/btrQJcbY0BN/rMkbNHvKPLUUdSOUr3BjC0/img.png)
![](https://blog.kakaocdn.net/dn/bx9XVZ/btrQK7UL47H/ojXiB5cik1H0HbzuuxzIvK/img.png)
WebContent 폴더 내에 views 폴더와 1~3까지의 폴더 생성
![](https://blog.kakaocdn.net/dn/x1OjG/btrQJPN7rO3/3k5CAt1C5HZTekoqBVlWZk/img.png)
EL (Expression Language) 표현 언어
✔️ 기존에 사용했던 표현식(출력식) <%= name %> 과 같이
JSP 상에서 표현하고자 하는 값을 ${ name } 의 형식으로 표현해서 작성하는 것
✔️EL은 기본적으로 getXXX을 통해 값을 빼 올 필요 없이 키값만 제시하면 바로 값에 접근 가능
내부적으로 해당 Scope 영역에 해당 키값의 밸류값을 가지고 올 수 있음
기본적으로 EL은 JSP의 내장객체를 구분하지 않고 자동적으로 모든 내장 객체에 키값을 검색해서 존재하는 경우 값을 가지고 옴
✔️ 단, 공유 범위가 작은 객체부터 찾아내기 시작함
✔️ 만약 찾는 값이 없다면 오류를 발생시키지 않고 출력을 안 함
데이터들을 담을 수 있는 JSP 내장 객체 종류(Servlet Scope 내장 객체 - 타입 기준 정의)
✔️ ServletContext (applicationScope)
한 애플리케이션당 단 1개 존재하는 객체
이 영역에 데이터를 담으면 애플리케이션 전역에서 사용 가능
👉🏻공유 범위가 가장 큼
✔️ HttpSession (sessionScope)
한 브라우저당 단 1개 존재하는 객체
이 영역에 데이터를 담으면 애플리케이션 전역에서 사용 가능
단, 값이 한 번 담기면 서버가 멈추거나, 브라우저가 종료되거나, 세션에 든 값이 직접 지워지기 "전"까지만 사용 가능
👉🏻 공유 범위가 다소 제한적임
✔️ HttpServletRequest (requestScope)
요청 및 응답 시 매번 생성되는 객체
이 영역에 데이터를 담으면 해당 request 객체를 포워딩받는 응답 jsp에서만 사용 가능(1회성)
👉🏻공유 범위가 해당 요청에 대한 응답 jsp 단 하나뿐임!
✔️ PageContext (pageScope)
현재 그 jsp 페이지에서만 사용 가능
👉🏻 공유 범위가 가장 작음 (현재 그 페이지에서 값을 담을 수 있고 그 페이지에서만 값을 꺼낼 수 있음)
👉🏻 위의 객체들의 값을 담을 때는 .setAttribute("키", 담고자하는데이터);
👉🏻 값을 꺼낼 때는 .getAttribute("키"); => Object 타입의 밸류값 리턴 (다형성 적용)
👉🏻 값을 지울 때는 .removeAttribute("키");
💻 index.jsp (메인 페이지에서 EL 관련 공부 페이지로 이동하기 위해 이동 경로 지정)
<a href="/action/el.do">01_EL</a>
EL 기본 구문
ELServlet 서블릿 생성
url mapping: /el.do
![](https://blog.kakaocdn.net/dn/Ha8B4/btrQMw7QfLe/K8kikDkN29F1RkmGOq9tLK/img.png)
01_el.jsp 생성
![](https://blog.kakaocdn.net/dn/cEbjUZ/btrQJbD7ODp/AAXxut20rcazlZYgU39yiK/img.png)
Person 클래스 정의
![](https://blog.kakaocdn.net/dn/K3sAZ/btrQISZqMix/FNWNLjnjGubiXGkk6mMhxK/img.png)
💻 공통 ELServlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// requestScope에 객체 담기 - 별도 정의 없이 바로 사용 가능
request.setAttribute("classRoom", "D강의장");
request.setAttribute("student", new Person("홍길동", 15, "남자"));
// sessionScope에 데이터 담기
HttpSession session = request.getSession(); // 세션 객체를 얻어낸 후 사용 가능
session.setAttribute("academy", "컴터학원");
session.setAttribute("teacher", new Person("김티처", 20, "여자"));
// requestScope와 sessionScope에 동일한 키값으로 데이터를 담기
// 원래 동일한 키값을 넣으면 덮어씌워지지만 이 경우 request, session으로써 하나씩 정의했으므로 중복 아님!
request.setAttribute("scope", "request");
session.setAttribute("scope", "session");
// applicationScope에 데이터 담기
// ServletContext application = request.getSession().getServletContext(); // 세션으로부터 객체를 얻어내는 첫 번째 방법
ServletContext application = request.getServletContext(); // request 객체로부터 얻어내는 두 번째 방법
application.setAttribute("scope", "application"); // 객체의 타입이 다르므로 이 키값 역시 중복 아님!
// jsp 페이지로 포워딩
request.getRequestDispatcher("views/1_EL/01_el.jsp").forward(request, response);
}
💻 1. 기존 방식의 01_el.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.kh.model.vo.Person" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>EL 기본 구문</h1>
<h3>1. 기존 방식대로 스크립틀릿과 표현식을 이용해서 각 영역에 담겨 있는 값을 뽑아서 화면에 출력</h3>
<%
// requestScope에 담긴 데이터 뽑기
String classRoom = (String)request.getAttribute("classRoom");
Person student = (Person)request.getAttribute("student");
// sessionScope에 담긴 데이터 뽑기
String academy = (String)session.getAttribute("academy");
Person teacher = (Person)session.getAttribute("teacher");
%>
<p>
학원명: <%= academy %> <br>
강의장: <%= classRoom %> <br>
강사 정보: <%= teacher.getName() %>, <%= teacher.getAge() %>, <%= teacher.getGender() %> <br>
수강생 정보 <br>
<ul>
<li>이름: <%= student.getName() %></li>
<li>나이: <%= student.getAge() %></li>
<li>성별: <%= student.getGender() %></li>
</ul>
</p>
</body>
</html>
💻 2. EL 방식을 적용한 01_el.jsp
EL을 사용하면 스크립틀릿을 이용해 데이터를 뽑는 과정을 생략할 수 있음
<hr>
<h3>2. EL을 이용해서 보다 쉽게 해당 Scope에 저장된 데이터들을 출력하기</h3>
<p>
학원명 : ${ academy } <br>
강의장 : ${ classRoom } <br>
강사 정보 : ${ teacher.name }, ${ teacher.age }, ${ teacher.gender } <br>
<%--
teacher라는 키값에 딸린 밸류값은 Person 객체임
해당 Person 객체의 각 필드에 담긴 값을 EL 표기법으로 출력하고자 한다면 .필드명으로 접근하면 됨
=> 내부적으로 해당 객체에 대한 해당 필드의 getter 메소드를 알아서 찾아 실행하는 구조
(즉, VO 클래스 생성 시 getter 메소드는 항상 만들어야 함)
--%>
수강생 정보 <br>
<ul>
<li>이름: ${ student.name }</li>
<li>나이: ${ student.age }</li>
<li>성별: ${ student.gender }</li>
</ul>
</p>
💻 3. EL 사용 시 내장 객체들에 저장된 키값이 동일할 경우
👉🏻 EL은 공유 범위가 제일 작은 Scope에서부터 해당 키값을 검색함
<h3>3. 단, EL 사용 시 내장 객체들에 저장된 키값이 동일할 경우</h3>
scope 값: ${ scope } <br> <!-- request가 출력됨 -->
EL 객체 우선 순위
pageScope => requestScope => sessionScope => application 순으로 속성을 찾음
만약 모든 영역에서 해당 키값을 못 찾는 경우?
✔️아무것도 출력되지 않음 (오류 발생하지 않음) => EL은 없으면 아무것도 출력되지 않으나 기본 방식은 키값 틀리면 500 오류 남!
💻 4. 직접 Scope 영역을 지정해서 접근하기
👉🏻 Scope 객체를 지정했을 때, 해당 키값을 정의한 Scope 객체를 제대로 지정하지 않으면?
✔️ 오류가 뜨는 게 아니라 아예 출력되지 않음!
<h3>4. 직접 Scope 영역을 지정해서 접근하기</h3>
<%
// pageScope에 데이터 담기
pageContext.setAttribute("scope", "page");
%>
pageScope에 담긴 값: ${ scope } 또는 ${ pageScope.scope } <br>
requestScope에 담긴 값: ${ requestScope.scope } <br>
sessionScope에 담긴 값 : ${ sessionScope.scope } <br>
applicationScope에 담긴 값: ${ applicationScope.scope } <br><br>
잘못된 접근 예시(session으로부터 classRoom 키값 찾기) : ${ sessionScope.classRoom } <br>
<!-- request 객체에 담은 classRoom 객체를 session에서 찾고자 하니 오류가 발생하는 것이 아니라 출력이 안 됨! -->
EL 구문 내에서 키값만 제시한다기보다는 스코프객체.키값으로 표현하는 걸 더 권장함
👉🏻 이유 1. 가독성 (도 맞지만)
👉🏻 이유 2. 필요한 값을 찾기 위해 pageScope부터 순차적으로 탐색이 모두 일어나기 때문에 성능상의 문제를 방지하기 위함