JSP - 28. EL과 JSTL

갓김치·2020년 12월 28일
0

JSP+Spring

목록 보기
29/43
  • 11/elDesc.jsp
  • jstlDesc.jsp

EL (표현언어)

  • 속성데이터를 표현할 목적의 스크립트 형태 언어
    • JSP의 네 가지 기본 객체(스코프)가 제공하는 영역의 속성 사용
  • 주로 모델2 이상에서 사용함
    • 모델1은 scope통해 변수 이동할 일이 없음
Servlet SpecJSP SpecEL SpecTomcat Version
3.12.33.08.0
3.02.22.27.0
  • 톰캣 버전에 따른 EL 버전 변화
    • EL3.0: EL2.2 이전에 메서드 호출 못하던 단점을 보완하기 위해 만들어짐

1. 속성 데이터 출력

// 일반 데이터
String data = "데이터";

// 속성 데이터
pageContext.setAttribute("data", "페이지 데이터");
request.setAttribute("data", "요청데이터");
session.setAttribute("data", "세션 데이터");
application.setAttribute("data", "어플리케이션 데이터");
  • 영역 관계 없이 꺼내기 : ${data}
    • 작은 영역부터 검색하며, 찾으면 검색 중지
  • 영역 객체 사용하여 스코프를 특정하여 꺼내기
    • ${pageScope.data}
    • ${requestScope.data}
    • ${sessionScope.data}
    • ${applicationScope.data}

2. 수치 연산, 관계 연산, 논리 연산자 제공

  • el에서는 연산의 중심이 연산자 (java에서는 피연산자)
  • EL은 할당연산자는 지원하지않음
    • el은 논리구조를 지원하지 않고 값을 출력하는 목적이기때문에 할당연산자를 지원하지않음

1) 단항연산자 : empty

  • 속성이 비어있으면 true
  • 문자열, 배열, collection 피연산자에 사용
  • 유/무 -> null 여부 -> length/size
    • 존재 여부 확인 -> 없으면 true
    • 존재한다면 null인지 아닌지 확인
      • pageContext.setAttribute("data", null); : null이면 true
    • null이 아니라면 length(문자열)/size(컬렉션,array) 확인
      • pageContext.setAttribute("data", ""); : true

2) 이항연산자

  • 산술연산자 : +(concat지원x)-*/%
    • ${1+1 } : 2
    • ${1+"1" } : 2
    • ${"1"+"1"} : 2
    • ${4/2 } : 2.0
    • ${3/2 } : 1.5
  • 논리연산자 : &&(and), ||(or), !(not)
    • ${true and true }, ${true or false }, ${not false }
    • ${ab and bc }, ${ab or bc} : 존재하지 않아서 false
    • ${true and bc}, ${true or bc}, ${not abc}
    • ${abc + 1} : 1 - abc가 없어서 0 으로 바뀜
    • ${abc - bcd} : 0
  • 비교연산자 : >(gt), <(lt), >=(ge), <=(le), ==(eq), !=(ne)

3) 삼항연산자 : 조건식 ? 참문장 : 거짓문장

  • ${empty abc ? "없음" : "있음"}
  • ${not empty abc ? "있음" : "없음"}

3. 집합 객체에 대한 접근 방법 제공

String[] array = new String[]{"value1", "value2"};
pageContext.setAttribute("array", array);
  • <%=array[3] %> : IndexOutOfBoundException
  • ${array[3] } : 화이트스페이스
List<String> list = new ArrayList<>();
list.add("value1");
list.add("value2");
pageContext.setAttribute("list", list);
  • <%=list.get(3) %> : IndexOutOfBoundException
  • ${list.get(3) } : el2.0에는 메소드 호출 불가능
  • ${list[3] } : array처럼 접근
Set set = new HashSet();
set.add("value1");
set.add("value2");
pageContext.setAttribute("set", set);
  • <%=set %>, ${set }
  • set에는 순서없음 -> n번째 element 꺼낼수없음
Map map = new HashMap();
map.put("key-1", "value1");
map.put("key2", "value2");
pageContext.setAttribute("map", map);
  • <%=map.get("key-1") %>, ${map.get("key-1") }, ${map["key-1"]}
  • ${map.key-1 } : 산술연산자로 인식하여 연산 후 -1로 출력됨
  • map에는 순서없음, element없음 -> 순서없이 entry로 존재

4. 객체의 멤버에 대한 접근 방법 지원

  • 속성으로 공유되고 있는 객체에 대한 자바 클래스 메서드(객체가 가진 인스턴스메서드) 호출 기능 제공
  • EL은 모든 자바빈 객체가 자바빈 규약에 따라 만들어졌다고 가정하고 출발함
  • member.mem_id => 자바빈 규약이 거꾸로 적용되어 getter를 호출하는 것
    • <%=member.getMem_id() %>
    • ${member.getMem_id() }
    • ${member.mem_id }
    • ${member["mem_id"] }

5. 11개의 EL 기본객체(Map<String, ?>) 제공

1) 영역 객체 : pageScope, requestScope, sessionScope, applicationScope

  • pageScope
  • requestScope
  • sessionScope
  • applicationScope

2) 파라미터 객체 : param, paramValues

  • param(Map<String, String>)
  • paramValues(Map<String, String[]>)
  • jsp기본객체 =/= el기본객체

3) 헤더 객체 (request header) : header, headerValues

  • header(Map<String, String>)
  • headerValues(Map<String, String[]>)
  • cookie(Map<String, Cookie>)
    • <%=(new CookieUtils(request)).getCookie("JSESSIONID").getValue() %>
    • ${cookie.JSESSIONID.value }
    • ${cookie["JESSIONID"]["value"] }

5) 컨텍스트 초기화 파라미터 객체 : initParam

6) pageContext

  • 유일하게 code assist 가능

JSTL: Java Standard Tag Library

  • 커스텀 태그들 중 널리 쓰이는 것들을 모아놓은 라이브러리.
  • 사용방법
    • 1) taglib 커스텀 태그 로딩(prefix 결정)
    • 2) <prefix:tagname attributes>

1. core

1) EL변수(속성데이터) 지원

  • set
    • <c:set var="test" value="테스트" scope="page" />
  • remove
    • <c:remove var="test" scope="page"/>
      • 만약 jstl이 el변수가 아닌 실제 변수를 지원하는 것이라면 remove 불가능.. (코드 짜면서 변수 지워본적있나요?)
    • remove 단점 - scope 명시하지 않을 시, 4개의 스코프 전부에서 같은 이름의 변수를 지움

2) 조건문 : if, choose~when~otherwise

  • 예시: test 속성 존재여부
  • el: ${empty test ? "지워졌음" : test }

단일조건문 : if

<c:if test="${empty test }">
	"지워졌음"
</c:if>
<c:if test="${not empty test }">
	${test }
</c:if>

다중조건문 : choose~when~otherwise

<c:choose>
	<c:when test="${empty test }">
		"지워졌음"
	</c:when>
	<c:otherwise>
		${test }
	</c:otherwise>
</c:choose>

3) 반복문 : forEach, forTokens

forEach

  • var(블럭변수)
  • begin(초기값)
  • step(증감자)
    • step이 1이면 생략가능, step은 양수만 지원함
  • end(마지막)
  • items(집합객체)
  • varStatus(LoopTagStatus 객체에 대한 참조)

forTokens

  • 문장을 구성하고 있는 토큰들에 대해 일정한 작업 반복
  • items(문장)
  • var(문장에 대한 토큰을 참조하는)
  • delims(구분자)
<c:forTokens items="1,2,3" delims="," var="num" varStatus="vs">
${num * 3 } ${not vs.last ? ", " : ""}
</c:forTokens>

4) url 재처리 (url rewriting) : url, redirect

  • 클라이언트사이드 절대경로시 req.getcontextpath 귀찮은점해소

url: url 재작성

<c:url value="/11/jstlDesc.jsp" var="clientURL"/>
<a href="${clientURL } ">세션유지하기</a>
세션 아이디 : ${pageContext.session.id }	
  • 쿠키못쓸때 url재작성하여 서버에 sessionid넘길때 사용할 수 있음
    • <a href="/webStudy03_MVCFramework/11/jstlDesc.jsp ">세션유지하기</a>
    • contextPath를 포함하는 url로 재작성됨
<c:url value="/prod/prodView.do" var="viewURL">
  <c:param name="prod_id" value="P101000001"/>
</c:url>
<a href="${viewURL} ">상품상세조회</a>
  • 쿼리스트링도 가능
    • <a href="/webStudy03_MVCFramework/prod/prodView.do?prod_id=P101000001 ">상품상세조회</a>

redirect

-<c:redirect url="/"/>

  • url 재작성되어 redirect 되는 것

5) 기타 : import, out

import

  • <c:import url="https://www.daum.net" var="daum"/>
    • 페이지 소스가 그대로 들어와서 실제 화면처럼 출력됨

out

  • <c:out value="${daum }" escapeXml="false"></c:out>
    • escape를 false 로 두어 모든 문자가 escape되어 실제 소스가 출력됨
    • escape여부 개발자가 결정할 수 있음

2. fmt 국제화

  • parsing/formatting, message 처리.
    • parsing: 문자열을 형식에 맞는 데이터타입으로 ex) parseInt
    • formatting: 특정 데이터를 특정한 형식의 문자열로

국제화 메시지 처리 단계

  1. 언어 선택(영어, 한글)
  2. 메시지 번들 작성(message_ko, message_en)
    <fmt:setLocale value="<%=Locale.ENGLISH %>"/>
    <fmt:bundle basename="kr.or.ddit.msg.message">
  3. 메시지 번들 로딩 : 로케일에 따라 각 메시지 번들을 읽어 메모리에 로드
  4. 메시지 키를 이용하여 사용
    <fmt:message key="bow" />
    </fmt:bundle> : 번들을 블럭처럼 지정할 수 있음

3. XML (거의 쓰이지 X)

  • 마셜링, 언마셜링
  • 이제는 json이 더 많이 쓰이기때문에 잘안쓰임
  • 마셜링을 한다면 컨트롤러단에서 마셜링하고 응답데이터 내보내고 끝이지 jsp까지 오지 않을 것임

4. 데이터베이스 (사용X)

  • L.A로 persistence layer에서 db 접근하며 따로 돌아가는데 굳이 jsp에서 db접근할일 없음

5. functions(fn)

  • core와 fmt의 차이점: custom tag가 아닌 el안에서 쓰는 함수
  • code assist 가능
  • <c:set var="array" value='<%=new String[]{"value1", "value2"} %>'/>

functions 만들어보기

1) 라이브러리를 위한 클래스

package kr.or.ddit.taglibs;

import java.util.Calendar;

public class CalendarGenerator {
	public static Calendar generate() {
		return Calendar.getInstance();
	}
}

2) 태그라이브러리 데피니션 파일(tld)생성

  • 클래스를 el안에서 접근할 수 있도록 태그라이브러리 데피니션 파일 만들어야함 (tld파일 참조)
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" <!--중요-->
  version="2.0">
  
<function>
  <description>
    Tests if an input string contains the specified substring.
  </description>
  <name>contains</name>
  <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
  <function-signature>boolean contains(java.lang.String, java.lang.String)</function-signature>
  <example>
    &lt;c:if test="${fn:contains(name, searchString)}">
  </example>
</function>

3) 톰캣에게 나 이런거 쓸거야 하고 알려줘야함

  • 어케 알려주죠.. 서버껏다키세요...

과제

  • 파일업로드 예습
  • localeTimer.jsp
    • 타임존리스트를 ui 제공, TimeZone의 static method 이용하려면 함수라이브러리 필요함
    • 클릭하면 타임존따라 시계?
  • 모든 view에서 스크립틀릿, 표현식
profile
갈 길이 멀다

2개의 댓글

comment-user-thumbnail
2020년 12월 28일

오늘두 잘보구갑니당!👀👍❤

1개의 답글