EL (Express Language; 표현 언어)
(1) EL 특징
- JSP의 네가지 기본 객체가 제공하는 영역의 속성 사용
- 집합 객체에 대한 접근 방법 제공
- 수치 연산, 관계 연산, 논리 연산자 제공
- 자바 클래스 메서드 호출 기능 제공
- 표현 언어만의 기본 객체 제공
- 일반적으로 MVC패턴일 때만 쓴다
- 데이터를 읽어오는 역할
(2) EL 표기법
${expr}
식별자와 연결된 값을 출력한다. (표현식과 유사함.)
(3) EL의 연산자
- 수치 연산자 : +, - , *, / 또는 div, % 또는 mod
- 비교 연산자 : == 또는 eq, != 또는 ne, < 또는 lt, > 또는 gt, <= 또는 le, >= 또는 ge
- 논리 연산자 : && 또는 and, || 또는 or, ! 또는 not
- empty 연산자
1) 값이 null이면 true 반환
2) 값이 빈 문자열(“”)이면 true 반환
3) 값이 길이가 0인 배열이면 true 반환
3) 값이 빈 Map이면 true를 반환
4) 값이 빈 Collection이면 true를 반환
5) 이외의 경우에는 false를 반환
EL은 값을 출력하는 용도 말고, 연산하는 용도로 쓰지 않는다 이유는 아래와 같다.
<tr>
<td>\${"10"+2}</td>
<td> ${"10"+2}</td>
</tr>
<tr>
<td>\${"10"+"2"}</td>
<td> ${"10"+"2"}</td>
</tr>
Java 문법에서는 문자열과 +연산자가 있으면 문자열을 연결시켰지만.
EL 문법에서는 문자열"" 안에 숫자가 있으면 자동으로 파싱(String->int)하여 연산을 한다.
<tr>
<td>\${"십"+5}</td>
<td> ${"십"+5}</td>
</tr>
내부적으로 파싱을 못해서 NumberFormatException 에러발생
<tr>
<td>\${4/5}</td>
<td> ${4/5}</td>
</tr>
자바스크립트처럼 정수 정수 연산 →실수데이터 출력
(4) EL의 기본객체(내장객체)
기본객체 | 설명 |
pageContext | JSP의 page 기본 객체와 동일 |
pageScope | pageContext 기본 객체에 저장된 속성의 <속성,값>매핑을 저장한 Map 객체 |
requestScope | request 기본 객체에 저장된 속성의 <속성,값> 매핑을 저장한 Map 객체 |
sessionScope | session 기본 객체에 저장된 속성의 <속성,값> 매핑을 저장한 Map객체 |
applicationScope | application 기본 객체에 저장된 속성의 <속성,값>매핑을 저장한 Map객체 |
param | 요청 파라미터의 <파라미터이름, 값> 매핑을 저장한 Map객체 |
paramValues | 요청 정보의 <파라미터이름,값 배열> 매핑을 저장한 Map 객체 |
header | 요청 정보의 <헤더이름,값> 매핑을 저장한 Map 객체 |
headerValues | 요청 정보의 <헤더이름,값 배열> 매핑을 저장한 Map 객체 |
cookie | <쿠키 이름, Cookie> 매핑을 저장한 Map 객체 |
initParam | 초기화 파라미터의 <이름,값> 매핑을 저장한 Map 객체 |
EL의 기본객체(내장객체)는 명시하거나, 생략해서 사용할 수 있다.
◎ Scope
<%
//변수에 값 저장
String str = "여름 여행";
//jsp 4개 영역에 데이터 저장 (속성명, 속성값)
pageContext.setAttribute("msg", "봄"); //page영역
request.setAttribute("msg2", "여름"); //request영역
session.setAttribute("msg3", "가을"); //session영역
application.setAttribute("msg4", "겨울"); //application영역
%>
${내장객체. 속성명} 또는 ${(내장객체생략)속성명}
${pageScope.msg} 또는 ${msg} page영역
${requestScope.msg} 또는 ${msg2} request영역
${sessionScope.msg} 또는 ${msg3} session영역
${applicationScope.msg} 또는 ${msg4} application영역
속성명은 유니크하게 명시하는 편이 좋음
속성명을 동일한 명칭을 사용하는데, 내장객체를 생략해서(${msg}) 호출 시 문제가 발생함
그러므로 동일한 명칭일 땐 내장객체를 명시하여(${pageScope.msg} ) 호출해야한다.
∴ el로 읽을 때는 속성명을 유일(unique)하게 명시했을 때, 내장 객체를 생략해서 사용할 수 있음
변수의 값 : ${str} → EL 은 데이터를 못 읽어옴
EL은 이런식으로 스크립틀릿<%%>에 만든 변수를 사용하는 것이 아니라,
jsp 4개 영역(page, request, session, application)에 저장한 뒤 읽어오는 형태를 취해야한다.
* application은 일반데이터를 저장하지않고, 설정정보를 사용하는 영역
EL을 단독으로만 사용하면 작업이 제한 적. 그래서 단독으로 사용하지않고 JSTL와 함께 사용한다.
◎ param
request.getParameter()의 역할을 한다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
//method="post" 방법이므로 전송된 데이터 인코딩처리한다.
request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL-param</title>
</head>
<body>
<h3>표현언어(EL;Express Language) - 파라미터 값 처리</h3>
<%-- action을 생략해도 기본값이라 자기자신을 호출 --%>
<form action="s02_el.jsp" method="post">
이름 : <input type="text" name="name">
<input type="submit" value="확인">
</form>
<br>
이름은 <%= request.getParameter("name") %> <br>
이름은 ${param.name}
</body>
</html>
* <form>에서 action을 생략해도 기본값이라서 자기자신을 호출한다
[s02_el.jsp]
<form action="s02_el.jsp" method="post">
이름은 <%= request.getParameter("name") %>
이름은 ${param.name }
차이점을 본다면
submit 하기 전 null 상태인 경우
request.getParameter → null로 출력
param → 빈문자로 표시
MVC에서는 선언부, 스크립틀릿, 표현식을 쓸 수 없어서 jstl.jar의 도움을 받는다
WEB-INF/lib 경로에 Jstl.jar 파일을 넣는다.
JSTL
= 커스텀 태그 = 만들어진 태그
java코드로 나열해야 하는 것을 쉽게 사용하기 위해 태그화시킨 것
태그형태로 되어있는데 servlet으로 변환 할 때 java코드가 된다 (전에 사용한 액션태그와 비슷함)
- core 라이브러리 (기본)
jsp 페이지에 core 라이브러리를 사용할 수 있도록 taglib 디렉티브 명시
(액션태그는 톰캣에 내장되어있지만 커스텀태그를 사용하기 위해서는 명시해야 태그 사용이 가능하다)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
prefix : 접두사 (태그앞에 코어라이브러리를 사용하려고 c라고 명시했음)
uri : core 라이브러리가 존재하는 위치 (jar파일의 설정정보를 읽어오는 식별자역할)
jar 파일로 부터 설정정보를 읽어오기 위해서 유니크하게 식별자를 만들었다.
자바빈(vo) 역할을 하기위해
(직접 접근을 못하니까) public한 getter, setter 메서드 생성
<%@ page import="kr.web.member.UserVO" %>
(1) <c:set var="변수명" value="설정값" target="객체" property="값" scope="저장영역" />
- 지정된 변수에 값을 저장하는 태그 (≒setAttribute)
target은 값을 설정하고자 하는 객체를 명시한다. target에 객체를 명시하면 명시된 객체에 값을 셋팅할 수 있다.
property는 taregt에 명시된 객체의 프로퍼티를 의미하며 명시된 프로퍼티에 value에 명시한 설정값을 셋팅합니다.
scope은 값을 셋팅한 범위를 의미(page,request,session,application), 생략하면 기본값인 scope="page"
//테스트로 스크립트릿으로 객체 생성
<% UserVO user = new UserVO(); %>
<c:set target="${user}" property="name" value="홍길동"/>
${user.property명} / ${user.메서드 명시}
회원이름 : ${user.name} (표준)
회원 이름 : ${user.getName()}
명시만 프로퍼티명인 것이고 EL이 자바빈(VO)에 접근하고 "name" 이 private으로 막혀있어서
setName을 찾아서 홍길동을 넣어준다
∴ property="name" : setName(set메서드/get메서드)을 호출하고 거기에 데이터를 넣어준다.
(2) <c:remove var="변수명" scope="범위" />
- 설정된 속성을 제거하는 태그
빈도수는 그닥 높지않음
scope은 값이 셋팅된 범위를 의미(page,request,session,application), 생략하면 scope="page"
(3) <c:out value="출력값" default="기본값" escapeXml="true/false" />
- 지정된 값을 출력하는 태그
value 에 명시한 값을 출력하며 value 가 null 일경우 default에 기술한 값을 출력
escapeXml는 기본값이 true이며 true라고 지정하면 <과 같은 특수문자를 < 엔티티 레퍼런스 형태로 변환한다.즉, escapeXml를 true라고 하면 HTML 태그를 인정하지 않는다는 의미.
false라고 지정하면 태그를 인정함.( HTML태그 인정할 때는 그냥 EL을 쓴다.)
escapeXml="true"이면 html태그 불인정(기본값)
<c:out value="<h1>escapeXml=true 오늘은 목요일</h1>" escapeXml="true"/>
escapeXml="false"이면 html태그 인정
<c:out value="<h1>escapeXml=false 내일은 금요일</h1>" escapeXml="false"/>
static만 되있으면 다 읽어와서 출력한다. 특별한 경우에만 out태그로 사용한다
★(4) <c:if test="조건" var="변수명" scope="범위" > </c:if>
- 조건이 true이면 수행문을 수행하는 태그 단독태그 아님!
test에서 조건을 체크해서 true 또는 false가 되면 var에 지정된 변수의 그 값이 담김
scope은 var에 지정한 변수가 셋팅되는 범위를 의미(page,request,session,application), 생략하면 scope="page"
<c:if test="boolean공간">
<c:if test="true">
true 무조건 수행 <br>
</c:if>
test>
문자열 명시할 때 큰 따옴표지만 밖에 큰따옴표가 있으므로 작은따옴표 써도 인정이 된다.
<c:if test="${param.name.equals('dragon') }">
name 파라미터 값이 ${param.name }입니다 <br>
</c:if>
테스트라서
전송이 안됐고 값이 없어서 false → 빈 문자 출력됨
get방식으로 값을 넘겨서 테스트하려면
http://localhost:8081/jspMain/ch18-jstl/s03_if.jsp뒤에 ?name=dragon 붙여서 테스트 해볼 수 있다(결과 true)
문자열을 비교할 떄 equals메서드나, 비교연산자(==)쓴다
(원래 EL안에서 메서드 호출이 안됐는데 상위버전으로 올라가면서 equals메서드 사용도 인정이 된다. 표준은 비교연산자)
<c:if test="${param.name == 'dragon' }">
name 파라미터 값이 ${param.name }입니다 <br>
</c:if>
단일 if문만 된다. if else, 다중if 가 안된다.
그래서 다중if문을 구현한 choose/when/otherwise를 만들었다
(5) <c:choose>
<c:when test="조건"></c:when>
<c:when test="조건"></c:when>
<c:otherwise></c:otherwise>
</c:choose>
- 여러개의 when 태그에 명시한 조건을 체크하고 조건에 만족하는 수행문을 수행, 만족하는 조건이 없으면 otherwise에 명시한 수행문을 수행. 단독태그 아님!
<c:choose>
<c:when test="${param.name=='dragon'&& param.age >= 20 }"> <%--첫번째 조건 if --%>
당신의 이름은 ${param.name }이고 20세 이상 입니다.
</c:when>
<c:when test="${param.name=='dragon'}"> <%--두번째 조건 else if--%>
당신의 이름은 ${param.name }입니다
</c:when>
<c:when test="${param.age >= 20 }"> <%--세번째 조건 else if --%>
당신은 20세 이상입니다.
</c:when>
<c:otherwise> <%--네번째 조건 else--%>
당신은 dragon이 아니고 20세 이상이 아닙니다.
</c:otherwise>
</c:choose>
★(6) <c:forEach items="객체명" begin="시작 인덱스" end="끝 인덱스" step="증감식" var="변수명" varStatus="상태변수" />
- 수행문을 반복해서 수행 (단순반복문과 확장for문을 합쳐놓은 형태), 목록작업 시 많이 쓰임
items : 속성에 인덱스가 존재하는 객체를 지정하여 반복수행할 때 사용
begin : 수행문을 반복시킬 시작 인덱스 지정
end : 수행문의 반복이 끝날 인덱스 지정
step : 증감식 지정 기본값은 step="1"
var : 현재 반복하고 있는 값이 저장되는 변수지정
varStatus : 반복 상태를 지정하는 변수 지정
예) varStatus ()의 사용예
<c:forEach var="list" items="itemList" varStatus="status">
${status.index} <- 0부터 시작하는 인덱스 표시
${status.count} <- 1부터 시작하여 1씩 증가 반복회차
${status.first} <- forEach 반복의 처음 일 경우 true
${status.last} <- forEach 반복의 마지막 일 경우 true
</c:forEach>
int형 배열 예시> 배열형태보다 List가 빈도 수 높음
<c:set var="intArray" value="<%= new int[]{10,20,30,40,50} %>"/>
EL이 배열에 접근해서 c:forEach가 roop를 돈다
<c:forEach var="i" items="${intArray}" >
그 배열로부터 var="i"가 값을 얻어온다
${i } <br>
<c:set var="intArray" value="<%= new int[]{10,20,30,40,50} %>"/>
EL이 배열에 접근해서 c:forEach가 roop를 돈다
<c:forEach var="i" items="${intArray}" begin="2" end="4" varStatus="status">
그 배열로부터 var="i"가 값을 얻어온다
${status.index }-${status.count }-${i } <br>
Map data 예시>
<% HashMap<String,String> mapData= new HashMap<String,String>();
mapData.put("name","홍길동");
mapData.put("job","경찰"); %>
페이지 영역에 해시맵 저장(저장해야 되니까 set태그 이용)
<c:set var="map" value="<%= mapData %>"/>
<c:forEach var="i" items="${map }">
${i.key }=${i.value } <br>
- functions 라이브러리
(7) <c:forTokens items="객체명" delims="구분자" begin="시작 인덱스" end="끝 인덱스" step="증감식" var="변수명" varStatus="상태변수" />
- 문자열을 구분자로 잘라내어 출력
items : 잘라내고자 하는 문자열이 담겨있는 객체
delims : 구분자 지정 구분자를 여러개 사용가능 (반면에 split 은 하나만 가능)
begin : 시작 인덱스
end : 끝 인덱스
step : 증감식
var : 잘라진 문자열이 담기는 변수
varStatus : 반복 상태지정 변수
(8) <c:catch var="변수명" />
- 예외 발생시 예외 처리 태그
예외가 발생할 수 있는 수행문 앞 뒤에 catch 태그를 배치하고 예외가 발생하면
var에 지정한 변수명에 예외 문구를 저장한다. out 태그 또는 el 를 통해 예외 문구를 호출해 출력할 수 있다.
(9) <c:import url="URL" var="변수명" scope="범위" varReader="변수명" context="context" charEncoding="인코딩" />
- 지정한 url 페이지의 내용을 읽어와 출력
(10) <c:redirect url="URL" context="context" />
- 지정한 url로 redirect
(11) <c:url var="변수명" scope="범위" value="값" context="context" />
- url 생성
(12) <c:param name="파라미터명" value="값" />
- 파라미터로 전달하고 싶은 값을 name에 기술된 파라미터명과 value에 명시한 값의 쌍으로 전송
예) forEach를 사용할 때 List의 크기 구하기
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<- 페이지 상단에 명시
${fn:length(itemList)}
접두사를 붙이고 함수 호출
- formatting 라이브러리
-JSTL i18n capable formatting 라이브러리의 국제화 태그를 이용해 국제화 지원
빼버리고 싶은 정보가 출력되거ㅏㄴ 짧게 출력하고싶을 때 반영이안되서 이때 패턴을 사용하여 조절한다.,
jsp 페이지에 i18n capable formatting 라이브러리를 사용할 수 있도록 taglib 디렉티브 명시
<%@ taglib prefix="fmt" uri=http://java.sun.com/jsp/jstl/fmt %>
prefix : 접두사
uri : i18n capable formatting 라이브러리가 존재하는 위치
(1) <fmt:bundle basename="properties파일경로및 파일명" prefix="prefix">....</fmt:bundle>
- 국제화를 적용을 위해 properties 파일경로 및 파일을 읽어와서 언어 적용
basename : 사용할 언어별 데이터가 key와 value의 쌍으로 작성된 properties 파일의 경로및 파일명 지정
prefix : bundle 태그 내에서 message 태그를 통해 value를 읽어올 때 key속성 앞에 접두사 지정
(2) <fmt:message key="메시지의 key값" bundle="setBundle 태그를 통해 로딩한 번들을 얽어올 때 사용함" var="변수명" scope="범위" />
- 국제화를 적용한 메시지의 key에 대한 value를 호출
key : 메시지의 key값을 통해 value 호출
var : 변수명을 지정하면 message태그를 출력기능을 상실하고 변수를 out 태그 또는 el를 통해 호출 하여 value를 출력해야 함
(3) <fmt:setBundle basename="properties파일경로및 파일명" var="메시지를 저장할 변수명" scope="범위" />
- 페이지 전체에서 사용할 번들을 지정
--------------------------------------------------
국제화 처리 예)
1. 각 페이지에서 읽어갈 key와 value가 저장될 properties 파일 작성
message.properties <- default 언어가 사용될 파일
message_ko.properties <- 한글이 사용될 파일
message_en.properties <- 영어가 사용될 파일
2. properties 파일이 들어갈 폴더 생성
WEB-INF/classes/폴더 생성(bundle) <- 배포시 (Dynamic Web Project를 만들어 이클립스에서 작업중이라면 Java Resources:src 에 폴더를 만듬, 자동적으로 classes 이하에 폴더가 복사됨)
3. 생성한 폴더에 message.properties, message_ko.properties 파일 등을 만들고 내용 입력
message_ko.properties 예
member_admin_title=회원관리
member_admin_name=관리자
member_admin_email=admin@test.com
member_admin_phone= 관리자 연락처는 {0}입니다. <- {0}은 message 태그 호출시 param 태그로 전달되는 데이터를 받음
4-1. properties 파일의 내용을 읽어갈 jsp 파일 작성(bundle 태그 이용시)
bundle 태그를 사용하면 지정된 영역내에 단일한 언어를 적용함
---------------------------------------------------------------
<%@ page contentType = "text/html; charset=euc-kr" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<fmt:bundle basename="bundle.message">
<html>
<head>
<title><fmt:message key="member_admin_title"/></title>
</head>
<body>
<fmt:message key="member_admin_name"/>
<br>
<fmt:message key="member_admin_phone">
<fmt:param value="${phone}" />
</fmt:message>
</body>
</html>
</fmt:bundle>
------------------------------------------------------------------
4-2. properties 파일의 내용을 읽어갈 jsp 파일 작성(setBundle 태그 이용시)
setBunde 태그를 사용할 경우 setBundle 태그에 변수를 지정해서 페이지내에서
적용할 bundle를 선택적으로 사용할 수 있음
------------------------------------------------------------------
<%@ page contentType = "text/html; charset=euc-kr" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<fmt:setBundle var="msg" basename="bundle.message"/>
<html>
<head>
<title><fmt:message bundle="${msg}" key="member_admin_title"/></title>
</head>
<body>
<fmt:message bundle="${msg}" key="member_admin_name"/>
<br>
<fmt:message bundle="${msg}" key="member_admin_phone">
<fmt:param value="${phone}" />
</fmt:message>
</body>
</html>
------------------------------------------------------------------
(4) <fmt:requestEncoding value="인코딩값" />
- request.setCharacterEncoding()과 같이 전송된 데이터의 인코딩 처리
(fmt:formatNumber5) <fmt:setLocale value="로케일값" variant="브라우저 스펙" scope="범위" />
- 로케일 지정
value : 로케일 값 지정 ex) ko, en
(6) <fmt:bundle basename="properties파일경로및 파일명" prefix="prefix">....</fmt:bundle>
- 국제화를 적용을 위해 properties 파일경로 및 파일을 읽어와서 언어 적용
basename : 사용할 언어별 데이터가 key와 value의 쌍으로 작성된 properties 파일의 경로및 파일명 지정
prefix : bundle 태그 내에서 message 태그를 통해 value를 읽어올 때 key속성 앞에 접두사 지정
(7) <fmt:message key="메시지의 key값" bundle="setBundle 태그를 통해 로딩한 번들을 얽어올 때 사용함" var="변수명" scope="범위" />
- 국제화를 적용한 메시지의 key에 대한 value를 호출
key : 메시지의 key값을 통해 value 호출
var : 변수명을 지정하면 message태그를 출력기능을 상실하고 변수를 out 태그 또는 el를 통해 호출 하여 value를 출력해야 함
(8) <fmt:setBundle basename="properties파일경로및 파일명" var="메시지를 저장할 변수명" scope="범위" />
- 페이지 전체에서 사용할 번들을 지정
(9) <fmt:formatNumber value="Number로 형식화할 수치 데이터"
type="숫자, 통화, 퍼센트 중 하나{number|currency|percent}"
pattern="사용자 지정 패턴"
currencyCode="통화코드지정"
currencySymbol="통화기호"
groupingUsed="{true|false}출력시 그룹 분리 기호(,)
포함여부"
maxIntegerDigits="출력시 integer 최대 자릿수 지정"
minIntegerDigits="출력시 integer 최소 자릿수 지정"
maxFractionDigits="출력시 소수점 이하 최대 자릿수 지정"
minFractionDigits="출력시 소수점 이하 최소 자릿수 지정"
var="변수"
scope="범위" />
- 수치 데이터를 숫자, 통화, 퍼센트로 변환
(10) <fmt:parseNumber value="Number로 파싱할 수 있는 수치 데이터"
type="숫자, 통화, 퍼센트 중 하나{number|currency|percent}"
pattern="사용자 지정 패턴"
parseLocale="로케일지정"
integerOnly="integer로만 파싱할지 지정"
var="변수"
scope="범위" />
- 문자열에서 숫자로 파싱
(11) <fmt:formatDate value="형식화할 날짜와 시간 데이터"
type="{time|date|both}"
deteStyle="{short|full}"
timeStyle="{short|full}"
pattern="사용자 지정 패턴"
timeZone="타임존 지정"
var="변수"
scope="범위" />
- 날짜에 형식 지정
(12) <fmt:parseDate value="파싱할 날짜 데이터"
type="{time|date|both}"
dateStyle="{short|full}"
timeStyle="{short|full}"
pattern="사용자 지정 패턴"
timeZone="타임존 지정"
parseLocale="로케일 지정"
var="변수"
scope="범위" />
- 문자열에서 날짜로 파싱
(13) <fmt:setTimeZone value="타임존 지정"
var="변수"
scope="범위" />
- 타임존 지정
value : ex) Australia/Brisbane, America/New_York 등등
(14) <fmt:timeZone value="">....</fmt:timeZone>
- 타임존 지정
value : ex)GMT, KST, UTC
'WEB > ✿JSP' 카테고리의 다른 글
[JSP] 🔗/MVC (2) 실습 (0) | 2022.01.25 |
---|---|
[JSP] 🔗MVC (0) | 2022.01.20 |
[JSP] 🔗모델1 구조(3) 실습 (0) | 2022.01.18 |
[JSP] 🔗모델1 구조(2) 실습 (0) | 2022.01.15 |
[JSP] 🔗JDBC와 커넥션 풀 (0) | 2022.01.15 |
댓글