카테고리 없음

#74. EL(Express Language)구문

열하나요 2023. 10. 23. 14:12

web.xml 만드는거 => 배포서술자

 

74-1. EL기본구문

${ 키값 }, ${ 키값.필드명 }

이렇게 불러오면 알아서 필드명을 get필드명으로 바꿔줌 => EL구문을 쓸 때 getter가 꼭 있어야 함

 

만약 request와 session과 application이 getAttribute로 보낸 키값이 같다면???

=> 공유범위가 작은 request값이 나온다. 없다면 session값...

없는 키값을 제시하면 아~~~~무것도 안나옴 (원래 스크립틀릿은 500에러 발생)

 

여기서 request에도 같은 키값이 있지만 session의 값을 뽑고 싶다면,

sessionScope.키값을 써주면 된다.

 

만약 getAttribute로 담고 지워도 흔적이 남아있음 => 꼭 remove로 지워야 사라진다

 

1. index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>안녕 나는 웰컴파일이야</title>
</head>
<body>

	<h1>* EL(Expression Language) 표현 언어</h1>
	
	<p>
		기존에 사용했던 표현식(출력식) &lt;= name %&gt; == <br>
		JSP상에 표현하고자 하는 값을 \${ name }의 형식으로 표현해서 작성하는 것
	</p>
	
	<h3>1. EL 기본 구문에 대해서 먼저 배워보자</h3>
	<a href="/action/el.do">01_EL</a>
	
	<br><br>
	
	<h3>2. EL의 연산자에 대해서 배워보자!</h3>
	<a href="/action/operation.do">02_EL의 연산자</a>
	
	<br><br>
	
	<hr>
	

</body>
</html>

 

2. Person.java (VO)

package com.kh.model.vo;

public class Person {
	
	private String name;
	private int age;
	private String gender;
	public Person() {
		super();
	}
	public Person(String name, int age, String gender) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
}

 

3. ELServlet (Controller)

a태그는 GET방식

package com.kh.controller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.kh.model.vo.Person;

/**
 * Servlet implementation class ELServlet
 */
@WebServlet("/el.do")
public class ELServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ELServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		// 그동안 응답 데이터가 존재한다면 request, session, application, page에 담았음
		// 						 Scope객체 / JSP내장객체
		
		/*
		 * 1. ServletContext (application scope)
		 *    한 어플리케이션 당 단 1개 존재하는 객체
		 *    이 영역에 데이터를 담으면 어플리케이션 전역에서 사용 가능
		 *    => 공유범위가 가장 큼
		 *    
		 * 2. HttpSession (session scope)
		 *    한 브라우저 당 1개 존재하는 객체
		 *    이 영역에 데이터를 담으면 JSP/Servlet단에서 사용가능
		 *    값이 한 번 담기면 서버가 멈추거나, 브라우저가 닫히기 전까지 사용 가능
		 *    => 공유범위가 다소 제한적
		 * 
		 * 3. HttpServletRequest (request scope)
		 *    요청 및 응답 시 매 번 생성되는 객체
		 *    이 영역에 데이터를 담으면 해당 request객체를
		 *    포워딩 받는 응답 JSP에서만 사용가능(1회성)
		 *    => 공유범위가 해당 요청에 대한 응답 JSP 단 하나뿐
		 * 
		 * 4. PageContext (page scope)
		 *    현재 JSP페이지에서만 사용 가능
		 *    => 공유범위가 가장 작음(해당 페이지에서만 사용 가능)
		 * 
		 * => 위 객체들에 값을 담을 때는 .setAttribute("키", "밸류");
		 * 			    값을 뽑을 때는 .getAttribute("키"); (Object형태로)
		 * 			    값을 지우고자 할때는 .removeAttribute("키");
		 * 
		 */
		
		
		// requestScope에 담기
		request.setAttribute("classRoom", "C강의장");
		request.setAttribute("student", new Person("홍길동", 15, "남자"));
		
		// sessionScope에 담기
		HttpSession session = request.getSession();
		session.setAttribute("academy", "KH정보교육원");
		session.setAttribute("lecture", new Person("이땡철", 20, "남자"));
		
		// requestScope와 sessionScope에 동일한 키값으로 데이터 담아보기
		request.setAttribute("scope", "reqeust");
		session.setAttribute("scope", "session");
		request.getServletContext().setAttribute("scope", "application");
		
		
		// 응답 뷰 지정
		// 포워딩
		RequestDispatcher view = request.getRequestDispatcher("views/1_EL/01_el.jsp");
		view.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 

4. 01_el.jsp(View)

<%@ 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에 담긴 값 뽑기 => classRoom, student
		String classRoom = (String)request.getAttribute("classRoom");
		Person student = (Person)request.getAttribute("student");
		
		// sessionScope에 담긴 값 뽑기 => academy, lecture
		String academy = (String)session.getAttribute("academy");
		Person lecture = (Person)session.getAttribute("lecture");
		
	
	%>
	
	<p>
		학원명 : <%= academy %> <br>
		강의장 : <%= classRoom %> <br>
		강사 정보 : <%= lecture.getName() %>, <%= lecture.getAge() %>, <%= lecture.getGender() %> <br>
		
		수강생 정보 <br>
		<ul>
			<li>이름 : <%= student.getName() %></li>
			<li>나이 : <%= student.getAge() %></li>
			<li>성별 : <%= student.getGender() %></li>
		</ul>
	</p>
	 --%>
	
	<hr>
	
	<h3>2. EL을 이용해서 보다 쉽게 해당 Scope에 저장된 값들을 출력하자</h3>
	
	<p>
		학원명 : ${ academy } <br>
		강의장 : ${ classRoom } <br>
		강사 정보 : ${ lecture.name }, ${ lecture.age }, ${ lecture.gender } <br>
		
		<!-- 
			필드값에 직접접근 XXX
			lecture에 접근했을 때 value값은 Person타입 객체!
			해당 Person객체에 각 필드에 담긴 값을 출력하고자 한다면 키값.필드명으로 접근하면 됨(눈에 보이는 소스코드 상)
			내부적으로 getter메소드를 찾아서 호출을 해서 값을 가져오는 구조
			=> 항상 명심해야할 사항 : getter메소드를 꼭 만들어야 함!!!!!!!!!!!!!!!!
		 -->
		 
		 수강생 정보
		 <ul>
		 	<li> 이름 : ${ student.name }</li>
		 	<li> 나이 : ${ student.age }</li>
		 	<li> 성별 : ${ student.gender }</li>
		 </ul>
	</p>
	
	<p>
		EL은 getXXX(getAttribute, getter메소드들)을 통해 값을 빼올 필요 없이 키값만 제시하면 바로 값에 접근이 가능 <br>
		내부적으로 해당 Scope영역에 키값에 해당하는 Value값을 가져올 수 있음 <br>
		기본적으로 EL은 JSP내장객체 종류(4가지)를 구분하지 않고 모든 내장객체에서 키값을 검색해서 존재하는 경우 값을 가져옴
	</p>
	
	
	<h3>3. EL 사용시 내장객체들에 저장된 키값이 동일할 경우</h3>
	
	scope키값에 담긴 밸류 값 : ${ scope } <br>
	
	<!--  
		EL은 공유범위가 가장 작은 Scope에서부터 해당 키값을 검색함
		page => request => session => application순으로 키값을 찾음
		
		만약에 모든 영역에서 해당 키에 담긴 값을 못 찾았을 경우??
	 -->
	
	EL로 없는 키값을 제시했을 경우 : ${ aaa } <br>
	표현식으로 없는 키값을 제시했을 경우 : &lt;%= aaa %&gt; <br> <!-- 500에러 발생 -->
	
	<hr>
	
	<h3>4. 직접 Scope영역을 지정해서 접근하기</h3>
	
	<%
		// pageScope에 담기
		pageContext.setAttribute("scope", "page");
		
	%>
	
	Quiz. ${ scope }를 작성하면 무슨값이 나올까? => page <br><br>
	
	pageScope에 담긴 "scope" 키값에 해당하는 밸류도 뽑고 싶고,
	requestScope, sessionScope, applicationScope에 있는 "scope"에 해당하는 값도 뽑고 싶다. <br>
	
	pageScope에 담긴 값 : ${ scope } 또는 ${ pageScope.scope } <br>
	requestScope에 담긴 값 : ${ requestScope.scope } <br>
	sessionScope에 담긴 값 : ${ sessionScope.scope } <br>
	applicationScope에 담긴 값 : ${ applicationScope.scope } <br>
	
	잘못된 접근 예시 (session의 classRoom이라는 키값으로 접근하는 경우) : ${ sessionScope.classRoom } <br>
	=> 아무것도 출력 안됨!
	

</body>
</html>

 

74-2. EL 연산자

기본적으로 연산은 가능함

나눗셈은 / 대신 div 사용가능,

나머지는 % 대신 mod 사용가능,

대소 비교 연산 >, < 대신 gt(greater than), lt(less than) 사용가능

>=, <= 대신 ge, le

== 대신 eq (EL에서 동등비교연산자는 equals메소드와 같은 기능을 한다 ==> 문자열로 비교함)

!= 대산 ne

키워드 연산자가 눈에 확 보이므로 이러한 것들을 연산기호보다 더 선호한다~

 

1. index.jsp

	<h3>2. EL의 연산자에 대해서 배워보자!</h3>
	<a href="/action/operation.do">02_EL의 연산자</a>

 

 

2. OperationServlet (Controller)

package com.kh.controller;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.kh.model.vo.Person;

/**
 * Servlet implementation class OperationServlet
 */
@WebServlet("/operation.do")
public class OperationServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public OperationServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		// 테스트 할 수 있는 값 넘기기
		request.setAttribute("big", 10);
		request.setAttribute("small", 3); // 
		
		request.setAttribute("sOne", "안녕");
		request.setAttribute("sTwo", new String("안녕"));
		
		request.setAttribute("pOne", new Person("홍길동", 10, "남자"));
		request.setAttribute("pTwo", null);
		
		ArrayList<String> list1 = new ArrayList();
		request.setAttribute("lOne", list1);
		
		ArrayList<String> list2 = new ArrayList();
		list2.add("ㅎㅇ");
		request.setAttribute("lTwo", list2);
		
		// 여기까지 requestScope에 총 8개의 값을 담았음
		
		request.getRequestDispatcher("views/1_EL/02_elOperation.jsp").forward(request, response);
		
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 

3. 02_elOperation.jsp(View)

 

String은 null이면 빈문자열

객체나 리스트는 null이면 isEmpty로 처리 가능 (반대는 당연히 안됨)

 

ArrayList list = new ArrayList(); ==> 빈리스트 => []로 출력

ArrayList list = new ArrayList();, list.add("ㅎㅇ"); ==> [ㅎㅇ]

ArrayList list = null; ==> 아무것도 출력되지 않음

 

 

null eq와 empty의 차이 => empty는 null이거나 빈문자열일 때를 다 비교해줌.

null은 null일 때만 비교해줌.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

	<h1>EL 연산</h1>
	
	<h3>1. 산술연산</h3>
	
	<p>
		* 기존방식 <br>
		10 + 3 = <%= (int)request.getAttribute("big") + (int)request.getAttribute("small") %> 
		
	</p>
	
	<p>
		* EL 연산 <br>
		10 + 3 = ${ big + small } <br>
		10 - 3 = ${ big - small } <br>
		10 * 3 = ${ big * small } <br>
		10 / 3 = ${ big / small } 또는 ${ big div small }<br>
		10 % 3 = ${ big % small } 또는 ${ big mod small } (모듈러. 나머지연산) <br>
	</p>
	
	<hr>
	
	<h3>2. 숫자간 대소 비교 연산</h3>
	
	<p>
		* 기존 방식 <br>
		10 > 3 : <%= (int)request.getAttribute("big") > (int)request.getAttribute("small") %>
	</p>
	
	<p>
		* EL 방식 <br>
		10 &gt; 3 : ${ big > small } 또는 ${ big gt small } <br>
		10 &lt; 3 : ${ big < small } 또는 ${ big lt samll } <br>
		10 &gt;= 3 : ${ big >= small } 또는 ${ big ge small } <br>
		10 &lt;= 3 : ${ big <= small } 또는 ${ big le small }
	</p>
	
	<hr>
	
	<h3>3. 동등 비교 연산</h3>
	
	<p>
		* 기존 방식 <br>
		10과 3이 일치합니까?
		<%= (int)request.getAttribute("big") == (int)request.getAttribute("small") %> <br>
		sOne과 sTwo가 일치합니까? (주소비교)
		<%= (String)request.getAttribute("sOne") == (String)request.getAttribute("sTwo") %> <br>
		sOne과 sTwo가 일치합니까? (내용물비교)
		<%= ((String)request.getAttribute("sOne")).equals((String)request.getAttribute("sTwo")) %> 
	</p>

	<p>
		* EL 연산 <br>
		
		10과 3이 일치합니까? : ${ big == small } 또는 ${ big eq small } <br>
		big에 담긴 값과 10이 일치합니까? : ${ big == 10 } 또는 ${ big eq 10 } <br>
		sOne과 sTwo가 일치합니까? : ${ sOne == sTwo } 또는 ${ sOne eq sTwo } <br>
		<!-- EL에서의 문자열의 == 비교는 자바에서의 equals()와 같은 동작을 함 -->
		sOne에 담긴 값과 "안녕"이 일치합니까? : ${ sOne == "안녕" } 또는 ${ sOne == '안녕' } <br>
		<!-- EL에서의 문자열 리터럴 비교 시 홑따옴표던 쌍따옴표던 상관 없음 -->
		sOne과 sTwo가 일치하지 않습니까? : ${ sOne != sTwo } 또는 ${ sOne ne sTwo }
		<!-- not equals -->
	</p>
	
	<h3>4. 객체가 null인지 또는 리스트가 비어있는지 체크하는 연산</h3>
	
	<p>
		* 기존방식 <br>
		
		- 객체에 null인지 알고싶을 경우, 객체명 == null로 비교하면 true 또는 false가 나옴 <br>
		- 리스트가 비어있는지 알고싶을 경우, 리스트명.isEmpty() 또는 리스트명.size() == 0을 사용해도 무방
		<%-- 
		<% if(loginUser != null) { %>
			
		<% } %>
		--%>
	</p>
	
	<p>
		* EL 연산 <br>
		pTwo가 null입니까? : ${ pTwo == null } 또는 ${ pTwo eq null } 또는 ${ empty pTwo } <br>
		pOne이 null입니까? : ${ pOne == null } 또는 ${ pOne eq null } 또는 ${ empty pOne } <br>
		pOne이 null이 아닙니까? : ${ !empty pOne } 또는 ${ pOne != null } 또는 ${ pOne ne null } <br>
		
		lOne이 텅 비어있습니까? : ${ empty lOne } <br>
		lTwo가 텅 비어있습니까? : ${ empty lTwo } <br>
	</p>
	
	<hr>
	
	<h3>5. 논리연산자</h3>
	
	<p>
		* 기존방식 <br>
		&&(AND), ||(OR)
	</p>
	
	<p>
		* EL연산 <br>
		AND 연산 : ${ true && true } 또는 ${ true and true } <br>
		OR 연산 : ${ false || true } 또는 ${ false or true }
	</p>
	
	<hr>
	
	<h3>연습</h3>
	
	<p>
		* EL연산에서 배운 최대한 키워드만 사용해볼것! <br>
		big이 small보다 크고 lOne이 텅 비어있습니까? : ${ (big gt small) and (empty lOne) }<br>
		big과 small의 곱은 4의 배수입니까? : ${ ((big * small) mod 4) eq 0 } <br>
		lTwo가 텅 비어있지 않거나 또는 sOne에 담긴 값이 "안녕하세요"와 일치합니까? : ${ (!empty lTwo) or (sOne eq "안녕하세요") } <br>
	</p>

</body>
</html>