jsp

[jsp] 24. EL(Expression Language)의 개념

jeri 2024. 7. 15. 10:01
반응형

01. EL(Expression Language)의 개념

1) EL의 개념

  • (표현식 언어) - 출력전용언어
  • jsp1에서 사용한 언어와는 다른 언어임
// => 앞에 코드는 자바코드를 추가하기 위해 사용한 언어라면, 앞으로 배울 언어는 JSP에서 출력할 때 사용할 언어들임
// => 따라서 EL언어의 내장객체 와 JSP1에서 사용한 내장객체는 다름!!
// => 단 EL의 pageContext내장객체는 JSP의 pageContext내장객체와 동일함

//JSP1
<% %>
<%= %>
  • EL을 제공해주는 곳 : apache Tomcat의 라이브러리 중 el-api.jar 파일 있어서 EL 사용 가능한 것

2) EL(Expression Language)

EL의 개념

  • "스코프 (Scope)가 제공하는 속성값"으로 저장된 객체를 제공받아 클라이언트에게 전달하여 출력하기 위한 언어

EL의 특징

  • 특정 Scope에 명시된 속성(Attribute)에 property나 property를 좀 더 쉽게 표현하고 나온 것

EL 사용 시 주의

  • 변수값을 출력하는 것이 아닌, session 이나 request scope에 저장된 속성값을 출력할 때 이용하는 것!!!
<%
	int no = 1;
%>
<p><%=no%></p> 	//ok
<p>${no}</p> 	//no

 

EL의 표현식

 

 

 

 

02. Page Scope 이용

1) Scope 속성값으로 문자열(값)을 저장해서 EL 태그 사용하기

🖤basic_string.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%
	//pageContext.setAttribute(String attribute, Object attributeValue):
	//=> pageContext 내장객체에 속성명(문자열)과 속성값(객체)을 전달받아 저장하는 메소드 - Page Scope
	// Page Scope : 스코프 속성값을 저장한 웹프로그램에서만 객체를 반환받아 사용 가능
	pageContext.setAttribute("name", "홍길동");
%>

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
</head>
<body>

 

	<h2>EL 미사용</h2>
	<%
		//pageContext.getAttribute(String attribute) : pageContext 내장객체에 저장된 속성값을
		//속성명을 이용하여 객체로 반환하는 메소드
		// => Object 타입의 객체로 반환하므로 반드시 명시적 객체 형변환하여 사용
		String name = (String)pageContext.getAttribute("name");

		//전달받은 속성명에 대한 속성값이 없는 경우 null 반환
		String pageName = (String)pageContext.getAttribute("pageName");
	%>

	<p>이름(name) = <%=name %></p>
	//<%-- JSP 표현식에서는 출력값이 [null]인 경우 "null" 문자열로 변환되어 출 --%>
	<p>이름(pageName) = <%=pageName %></p>
	//<%-- if 명령을 사용하여 JSP 표현식의 값이 [null]이 아닌 경우에만 출력되도록 설정필요 --%>
	<p>이름(pageName) = <%if(pageName!=null){%> <%=pageName %> <%} %></p>
	<h2>EL 사용</h2>
	//<%-- ${속성명} : EL 표현식으로 스코프의 속성명을 사용하면 속성값을 제공받아 사용 가능 --%>
	//<%-- getAttribute()메소드를 호출하지 않아도 스코프의 속성값을 제공받아 사용 가능 --%>
	<p>이름(name) = ${name}</p>
	//<%--스코프 속성명으로 저장된 속성값이 없는 경우 EL 미실행 - 속성값 미출력 --%>
	<p>이름(pageName) = ${pageName}</p>

</body>
</html>

 



2) Scope 속성값으로 자바빈 객체를 저장해서 EL 태그 사용하기

🖤Car.java
package xyz.itwill.el;
public class Car {
	private String modelName;
	private String carColor;
	public Car() {	}
	public Car(String modelName, String carColor) { super(); this.modelName = modelName; this.carColor = carColor;}
	public String getModelName() { return modelName;}
	public void setModelName(String modelName) { this.modelName = modelName;}
	public String getCarColor() { return carColor;}
	public void setCarColor(String carColor) { this.carColor = carColor;}
}
🖤basic_car.jsp
<%@page import="xyz.itwill.el.Car"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%
	//pageContext 내장객체에 Car 객체를 속성값으로 저장
	pageContext.setAttribute("car", new Car("산타페","하얀색"));
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
</head>
<body>

 

	<h2>EL 미사용</h2>
    <%
		//pageContext 내장객체에 저장된 속성값을 Car 객체로 반환받아 저장
		Car car = (Car)pageContext.getAttribute("car");

		//전달받은 속성명에 대한 속성값이 없는 경우 null 반환
		//=> 참조변수에 [null]이 저장된 상태에서 메소드를 호출하면 NullPointerException 발생
		//Car car = (Car)pageContext.getAttribute("pageCar");

		//객체의 필드값을 반환받아 저장
		String modelName = car.getModelName();
		String carColor = car.getCarColor();
	%>
    <p>자동차(car) = <%=car %></p>
	<p>자동차모델명(modelName) = <%=modelName %></p>
	<p>자동차색상(carColor) = <%=carColor %></p>
	<h2>EL 사용</h2>
	<p>자동차(car) = ${car}</p>
	//<%-- EL 표현식으로 제공받은 객체의 메소드 호출 가능 - 비권장 --%>
	//<%-- <p>자동차모델명(modelName) = ${car.getModelName()}</p> --%>
	//<%-- 스코프 속성값이 객체인 경우 ${속성명.필드명} 형식의 표현식을 사용하여 객체의 필드값을 제공받아 출력 가능 --%>
	//<%-- => EL 표현식으로 필드명을 사용하면 Getter 메소드 자동 호출 --%>
	//<%-- => Getter 메소드 작성 규칙에 맞지 않게 선언된 경우 또는 Getter 메소드가 없는 경우 에러 발생 --%>
	<p>자동차모델명(modelName) = ${car.modelName}</p>
	<p>자동차색상(carColor) = ${car.carColor}</p>

	//<%-- EL 표현식의 속성명으로 제공되는 속성값이 없는 경우 EL 미실행
    //- NullPointerException 미발생 --%>
	<p>자동차모델명(modelName) = ${pageCar.modelName}</p>

</body>
</html>

 

 

 

 

3) Scope 속성값으로 Map객체를 저장해서 EL 태그 사용하기

  • 따로 Car클래스 만들 필요없음 값만을 저장할 목적의 VO클래스를 만드는 대신 Map을 이용해 사용
  • 그래서 어떤 개발자들은 VO클래스 절대 안만들고, 대신 Map 객체 이용함
🖤basic_map.jsp
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%
	//HashMap 객체(Map 객체)를 생성하여 저장
	Map<String, String> carMap = new HashMap<String, String>();

	//HashMap 객체(Map 객체)에 엔트리(Entry: 이름과 값을 하나의 묶음으로 표현한 요소)를 추가하여 저장
	carMap.put("modelName", "싼타페");
	carMap.put("carColor", "하얀색");

	pageContext.setAttribute("carMap", carMap);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
</head>
<body>

 

	<h2>EL 미사용</h2>
	<%
		//pageContext 내장객체에 저장된 속성값을 객체로 반환받아 저장
		//@SuppressWarnings : 프로그램 소스코드에서 발생되는 경고를 제거하는 어노테이션
		//=> value 속성값으로 경고의 종료를 설정 - 다른 속성이 없는 경우 속성값만 설정 가능
		@SuppressWarnings("unchecked")
		Map<String, String> car = (Map<String, String>)pageContext.getAttribute("carMap");
	%>

	<p>자동차 = <%=car%></p>
	//<%-- Map 객체에 저장된 엔트리(Entry)에서 맵키(Key)를 이용하여 맵값(Value)을 반환받아 출력 --%>
	<p>자동차의 모델명 = <%=car.get("modelName")%></p>
	<p>자동차의 색상 = <%=car.get("carColor")%></p>
	<h2>EL 사용</h2>
	<p>자동차 = ${carMap}</p>
	//<%-- 스코프 속성값이 Map 객체인 경우 ${속성명.맵키} 형식의 표현식을 사용하여 Map 객체에 저장된 엔트리의 맵값을 제공받아 출력 --%>
	//<%-- => EL 표현식에서 맵키를 사용하면 Map 객체의 get()메소드가 자동 호출되어 맵값 반환 --%>
	<p>자동차의 모델명 = ${carMap.modelName }</p>
	<p>자동차의 색상 = ${carMap.carColor }</p>

</body>
</html>

 

 

 

 

 

03. 반드시 [ ]연산자 사용하는 경우

  1. 리스트나 배열의 요소에 접근할 때 - Array객체 , List객체
  2. Map에서 표현 불가능한 문자가 맵키로 있을 때
  3. SCOPE 객체의 속성값을 Map키로 제공 받았을 때
  • 배열의 요소값을 표현할 경우 .연산자 사용 못하므로 [ ]연산자 이용
<li>${nameArray["0"] }</li> //error
<li>${nameArray[0] }</li> //ok

 

 

1) Request Scope에 [문자열(값) - Array객체] 저장해 사용

🖤 string_array.jsp - 요청페이지
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	String[] nameArray = {"홍길동","임꺽정","전우치","일지매","장길산"};
	request.setAttribute("nameArray", nameArray);
	request.getRequestDispatcher("string_array_el.jsp").forward(request, response);
%>
🖤 string_array_el.jsp - 응답페이지
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
</head>
<body>
	<h1>EL -Array</h1>
	<hr />

<ul>
		//<%-- 스코프 속성값이 배열인 경우 배열 요소값을 표현하기 위해 EL 표현식에서 . 연산자로
		//첨자(Index)를 표현한 경우 ELException 발생 - . 연산자 사용 불가능 --%>
		//<%-- <li>${nameArray.0 }</li> --%>
		//<%-- 스코프 속성값이 배열인 경우 배열 요소값을 표현하기 위해 EL 표현식에서 [] 연산자로
		//첨자(Index)를 표현하여 요소값을 제공받아 출력 --%>
		//<%-- <li>${nameArray["0"] }</li>--%> <%--첨자는 "" 기호 생략 가능 --%>
		//<%-- for문을 사용하려면 스크립틀릿을 사용해야하므로 우선 그냥 작성 --%>
		<li>${nameArray[0] }</li>
		<li>${nameArray[1] }</li>
		<li>${nameArray[2] }</li>
		<li>${nameArray[3] }</li>
		<li>${nameArray[4] }</li>
		//<%--EL로 표현식에서 첨자가 배열 요소의 범위를 벗어난 경우 EL 미실행 - 미출력될 뿐 에러나지 않음 --%>
		<li>${nameArray[5] }</li>
	</ul>
</body>
</html>

2) Request Scope에 [자바빈객체 Student클래스 - List객체 ] 저장해 사용

  • List자료구조의 요소값을 표현할 경우 .연산자 사용 못하므로 [ ]연산자 이용
<p>학번 = ${studentList.0.num }, 이름 = ${studentList.0.name }</p>   //error
<p>학번 = ${studentList[0].num }, 이름 = ${studentList[0].name }</p> //ok
🖤 Student.java - VO클래스
package xyz.itiwll.el;
public class Student {
	private int num;
	private String name;
	public Student() {	}
	public Student(int num, String name) { super(); this.num = num; this.name = name; }
	public int getNum() { return num; }
	public void setNum(int num) { this.num = num; }
	public String getName() { return name; }
	public void setName(String name) { this.name = name; }
}
🖤 student_list.jsp - 요청페이지
<%@page import="java.util.ArrayList"%>
<%@page import="xyz.itwill.el.Student"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<%
	List<Student> studentList = new ArrayList<Student>();

	studentList.add(new Student(1000,"홍길동"));
	studentList.add(new Student(2000,"임꺽정"));
	studentList.add(new Student(3000,"전우치"));
	studentList.add(new Student(4000,"일지매"));
	studentList.add(new Student(5000,"장길산"));

	request.setAttribute("studentList", studentList);
	request.getRequestDispatcher("student_list_el.jsp").forward(request, response);
%>
🖤 student_list_el.jsp - 응답페이지
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
</head>
<body>

<h1>EL - List</h1>
	<hr />
	//<%-- EL 표현식에 . 연산자로 첨자를 표현하면 ELException 발생 --%>
	//<%-- <p>학번 = ${studentList.0.num }, 이름 = ${studentList.0.name }</p>--%>
	//<%-- <p>학번 = ${studentList[0]["num"] }, 이름 = ${studentList[0]["name"] }</p> --%>
	<p>학번 = ${studentList[0].num }, 이름 = ${studentList[0].name }</p>
	<p>학번 = ${studentList[1].num }, 이름 = ${studentList[1].name }</p>
	<p>학번 = ${studentList[2].num }, 이름 = ${studentList[2].name }</p>
	<p>학번 = ${studentList[3].num }, 이름 = ${studentList[3].name }</p>
	<p>학번 = ${studentList[4].num }, 이름 = ${studentList[4].name }</p>
</body>
</html>

3) Request Scope에 [Map객체 ] 저장해 사용

  • Map에서 표현 불가능한 문자가 맵키로 있을 때
<p>이름 = ${hewonMap.first.name } ${hewonMap.second.name }</p> //error
<p>이름 = ${hewonMap["first.name"] } ${hewonMap["second.name"] }</p> //ok
🖤 hewon_map.jsp - 요청페이지
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	Map<String, String> hewonMap = new HashMap<String, String>();

	hewonMap.put("first.name", "홍");
	hewonMap.put("second.name", "길동");

	request.setAttribute("hewonMap", hewonMap);
	request.getRequestDispatcher("hewon_map_el.jsp").forward(request, response);
%>
🖤 hewon_map_el.jsp - 응답페이지
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
</head>
<body>
	<h1>EL - Map</h1>
	<hr />
	//<%-- 스코프 속성값으로 Map 객체가 저장된 경우 맵키가 EL 표현식으로 사용하기 부적절한
	//문자가 존재할 경우 . 연산자로 맵값을 제공받아 출력 불가능 --%>
	//<%-- <p>이름 = ${hewonMap.first.name } ${hewonMap.second.name }</p>--%>

	//<%-- 스코프 속성값으로 Map 객체가 저장된 경우 맵키가 EL 표현식으로 사용하기 부적절한
	//문자가 존재할 경우 [] 연산자로 맵키를 표현하여 맵값을 제공받아 출력 --%>
	<p>이름 = ${hewonMap["first.name"] } ${hewonMap{"second.name"] }</p>
</body>
</html>

4) Request Scope에 [Map객체 ] 저장해 사용

  • SCOPE 객체의 속성값을 Map키로 제공 받았을 때
<p>좋아하는 과일 = ${fruitsMap.choice }</p> //error
<p>좋아하는 과일 = ${fruitsMap[choice] }</p> //ok
🖤fruits_map.jsp - 요청페이지 (다른 속성값을 Map키로 제공받았을 때)
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	Map<String, String> fruitsMap = new HashMap<String, String>();

	fruitsMap.put("one", "딸기");
	fruitsMap.put("two", "복숭아");
	fruitsMap.put("three", "사과");

	request.setAttribute("fruitsMap", fruitsMap);
	request.setAttribute("choice", "two");

	request.getRequestDispatcher("fruits_map_el.jsp").forward(request, response);
%>
🖤 fruits_map_el.jsp - 응답페이지
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
</head>
<body>
	<h2>EL - Map</h2>
	<hr />

	<p>과일-1 = ${fruitsMap.one }</p>
	<p>과일-1 = ${fruitsMap.two }</p>
	<p>과일-1 = ${fruitsMap.three }</p>

	<p>좋아하는 과일 = ${fruitsMap.two }</p>
	<p>좋아하는 과일 = ${fruitsMap["two"] }</p>
	//<%-- 스코프 속성값이 Map 객체인 경우 맵키를 이용하여 맵값을 제공받아 출력 가능 --%>
	//<%-- => 맵키에 해당하는 맵값이 없는 경우 EL 미실행 --%>
	//<%-- <p>좋아하는 과일 = ${fruitsMap.choice }</p>--%>
	//<%-- EL 표현식에서 [] 연산자를 이용하여 다른 스코프 속성값을 제공받아 맵키로 표현하여 맵값 출력 가능 --%>
	//<%-- two를 맵키로 제공받음 , 단 ""사용 안함  --%>
	<p>좋아하는 과일 = ${fruitsMap[choice] }</p>

</body>
</html>

04. Request Scope 이용

1) requestScope이용할 것임

  • 반드시 요청페이지 실행해야 응답페이지에서 실행결과를 알려줌

2) Member.java - VO클래스

package xyz.itwill.el;
public class Member {
	private String name;
	private Car car;
	public Member() {	}
	public Member(String name, Car car) { super(); this.name = name; this.car = car;}
	public String getName() {return name;}
	public void setName(String name) {this.name = name;}
	public Car getCar() {return car;}
	public void setCar(Car car) {this.car = car;}
}

3) member.jsp - 요청페이지

<%@page import="xyz.itwill.el.Member"%>
<%@page import="xyz.itwill.el.Car"%>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

//<%--Member 객체를 생성하여 Request Scope 속성값으로 저장하고 다른 웹프로그램(JSP)로
//포워드 이동하는 JSP 문서 - 요청을 처리하는 웹프로그램(Model의 역할)--%>

<%
	Member member =new Member("홍길동", new Car("싼타페","하얀색"));

	//request 내장객체에 Member 객체를 속성값으로 저장 - Request Scope
	//Request Scope : 스코프 속성값을 저장한 웹프로그램과 스레드가 이동된 웹프로그램에서만
	//속성값을 객체로 반환받아 사용 가능
	request.setAttribute("member", member);

	//포워드 이동 : 현재 웹프로그램의 명령을 실행하는 스레드를 다른 웹프로그램으로 이동시켜
	//명령을 실행하도록 제공하는 기능
	//=> 스레드가 이동되는 웹프로그램에서는 현재 웹프로그램의 request 객체와 response 객체를 전달받아 사용
	request.getRequestDispatcher("member_non_el.jsp").forward(request, response);
	//request.getRequestDispatcher("member_el.jsp").forward(request, response);
%>

4) member_non_el.jsp - 응답페이지

<%@page import="xyz.itwill.el.Member"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

//<%-- 요청 페이지(member.jsp)의 Request Scope 속성값을 객체로 반환받아 클라이언트에게 전달하는 JSP 문서--%>
//<%-- => 요청페이지(member.jsp)에 대한 실행 결과를 제공받아 응답 처리하는 웹프로그램 (View의 역할) --%>
//<%-- => 응답페이지(member_non_el.jsp)를 요청한 경우 Request Scope 속성값이 없으므로  NullPointerException 발생 --%>

<%
	//Request Scope 속성값을 객체로 반환받아 저장
	Member member = (Member)request.getAttribute("member");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
</head>
<body>
	<h2>EL 미사용</h2>

	<p>회원 = <%=member %></p>
	<p>회원의 이름 = <%=member.getName() %></p>
	<p>회원의 자동차 = <%=member.getCar() %></p>
	<p>회원의 자동차의 모델명 = <%=member.getCar().getModelName() %></p>
	<p>회원의 자동차의 색상 = <%=member.getCar().getCarColor() %></p>

</body>
</html>

5) member_el.jsp - 응답페이지

<%@page import="xyz.itwill.el.Member"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

//<%-- 요청 페이지(member.jsp)의 Request Scope 속성값을 객체로 반환받아 클라이언트에게 전달하는 JSP 문서--%>
//<%-- => 요청페이지(member.jsp)에 대한 실행 결과를 제공받아 응답 처리하는 웹프로그램 (View의 역할) --%>
//<%-- => 응답페이지(member_el.jsp)를 요청한 경우에도 EL이 미실행될 뿐 NullPointerException 미발생 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
</head>
<body>
	<h2>EL 사용</h2>

	<p>회원 = ${memeber }</p>
	<p>회원의 이름 = ${member.name}</p>
	<p>회원의 자동차 = ${member.car }</p>
	<p>회원의 자동차의 모델명 = ${member.car.modelName }</p>
	<p>회원의 자동차의 색상 = ${member.car.carColor }</p>
	<hr />
	//<%-- EL 표현식에서 . 연산자 대신 [] 연산자를 이용하여 필드명(맵키)으로 필드값(맵값)을 제공받아 출력 --%>
	//<%-- => []연산자에 필드명(맵키) 사용시 반드시 ""으로 표현 --%>
	<p>회원의 이름 = ${member["name"]}</p>
	<p>회원의 자동차의 모델명 = ${member["car"]["modelName"] }</p>
	<p>회원의 자동차의 색상 = ${member["car"]["carColor"] }</p>

</body>
</html>

 

반응형