EL (Expression Language)
- EL(표현 언어)는 JSP 2.0 스펙에 추가된 개념으로, Java 코드 없이 JSP에서 데이터를 다룰 수 있도록 도와주는 기능입니다.
- 실행 시간에 태그의 속성값을 지정하거나 데이터를 출력할 때 사용됩니다.
- Java Bean Component에 저장된 데이터를 쉽게 접근할 수 있으며, request, application, session 같은 객체의 접근을 간소화합니다.
- 객체 접근은 스코프(scope)를 기반으로 작동하며, 우선순위는 다음과 같습니다:
application scope > session scope > request scope > page scope
- 객체 접근은 스코프(scope)를 기반으로 작동하며, 우선순위는 다음과 같습니다:
표기법
${}
주요 특징
EL을 통해 데이터를 참조할 때 스코프를 생략하면 가장 좁은 스코프부터 순차적으로 탐색합니다. 예를 들어,
${serverTime}
이라고 작성하면 page, request, session, application 순으로 탐색하여 serverTime 변수를 찾습니다.
여러 스코프에 같은 이름의 변수가 존재할 경우 보다 좁은 스코프의 변수가 우선됩니다.
JSP가 실행될 때 EL 표현식은 실행 시점에 평가되고 즉시 결과가 반영됩니다.
EL을 사용하면 복잡한 Java 코드를 대체하여 간결하게 데이터를 처리할 수 있습니다. 예를 들어, 기존에는 다음과 같이 Java 코드를 작성해야 했지만,
<%= request.getAttribute("userName") %>
EL을 사용하면 다음과 같이 간단히 표현할 수 있습니다:
${userName}
EL은 JSP의 내장 객체에도 접근이 가능합니다. 이를 통해 다양한 데이터를 처리할 수 있으며, 주요 내장 객체는 다음과 같습니다:
- pageScope, requestScope, sessionScope, applicationScope: 각각의 스코프에 저장된 데이터에 접근
- param: 요청 파라미터 접근
- header: HTTP 헤더 정보 접근
- cookie: 쿠키 데이터 접근 등
산술 연산 및 조건문도 지원합니다. 예를 들어,
${1 + 1} // 결과: 2
${user.age > 18} // 결과: true
처럼 간단한 연산과 비교를 통해 동적 데이터를 처리할 수 있습니다.
예제
연산자
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL</title>
</head>
<body>
<h2>EL 문법을 학습하자</h2><hr>
<h3>EL 리터럴</h3>
문자열 : ${"데이터1"}<br>
문자열 : ${'데이터2'}<br>
논리값 : ${true}<br>
null : ${null}<br> <!-- null값은 빈문자열로 출력 -->
<h3>el 산술 연산자</h3>
el 안에서 연산식 사용시 연산의 결과만 출력<br>
연산 : ${10+1 }<br>
${10/2 }<br>
${10 div 2 }<br>
${10%2 }<br>
${10 mod 2 }<br>
<h3>el 논리 연산자</h3>
${true && false }<br>
${true and false }<br>
${true || false }<br>
${true or false }<br>
${!true }<br>
${not true }<br>
<h3>el 비교 연산자</h3>
${10 == 11 }<br>
${10 eq 11 }<br>
${10 != 11 }<br>
${10 ne 11 }<br> <!-- not eq = ne -->
${10 < 11 }<br>
${10 lt 11 }<br>
${10 > 11 }<br>
${10 gt 11 }<br>
${10 <= 11 }<br>
${10 le 11 }<br> <!-- lt eq = le -->
${10 >= 11 }<br>
${10 ge 11 }<br> <!-- gt eq = ge -->
<h3>el empty 연산자</h3>
객체가 null이거나 컬랙션 또는 배열의 크기가 0일 때 true<br>
${empty null }<br>
</body>
</html>
EL 문법을 학습하자EL 리터럴문자열 : 데이터1문자열 : 데이터2 논리값 : true null : el 산술 연산자el 안에서 연산식 사용시 연산의 결과만 출력연산 : 11 5.0 5.0 0 0 el 논리 연산자falsefalse true true false false el 비교 연산자falsefalse true true true true false false true true false false el empty 연산자true |
model에 담기
package edu.springMVC1.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import edu.springMVC1.vo.BoardVO;
@Controller
public class ElJSTLController {
@RequestMapping(value = "/el.do")
public String el(Model model) {
model.addAttribute("data1", "10");
model.addAttribute("data2", 10);
BoardVO vo = new BoardVO();
vo.setTitle("제목입니다");
model.addAttribute("title", vo);
return "el";
}
}
객체(vo)의 필드값은 getter를 사용하지 않고도 객체키.필드명으로 바로 출력할 수 있습니다
<h3>el scope attribute 다루기</h3>
${data1 }<br>
${data2 }<br>
${vo.title }<br>
el scope attribute 다루기1010 제목입니다 |
el은 문자열이지만 숫자형식이라면 자동으로 형변환을 하여 연산을 합니다
${data1+10 }
20 |
@RequestMapping(value = "/el.do")
public String el(Model model) {
model.addAttribute("data1", "10");
model.addAttribute("data2", 10);
BoardVO vo = new BoardVO();
vo.setTitle("제목입니다");
model.addAttribute("vo", vo);
BoardVO vo2 = new BoardVO();
vo2.setTitle("안녕하세요. 반갑습니다");
vo2.setPassword("1234");
vo2.setWriteDate("2024-11-19");
vo2.setWriter("홍길동");
vo2.setContent("첫번째 게시글을 작성해요");;
model.addAttribute("details", vo2);
return "el";
}
<h3>el details</h3>
${details.title }<br>
${details.password }<br>
${details.writeDate }<br>
${details.writer }<br>
${details.content }<br>
el details안녕하세요. 반갑습니다1234 2024-11-19 홍길동 첫번째 게시글을 작성해요 |
page scope에 데이터를 담았을 경우 더 좁은 영역이 우선순위가 높기 때문에 페이지 영역에 추가된 데이터로 출력됩니다
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
/* 지역변수이고 scope에 들어가지 않음 */
String data1 = "페이지 데이터입니다.";
/* 페이지 영역에 데이터 추가 */
pageContext.setAttribute("data1", data1);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL</title>
</head>
<body>
<h3>el scope attribute 다루기</h3>
el은 문자열이지만 숫자형식이라면 자동으로 형변환을 하여 연산을 한다<br>
${data1 }<br>
${data2 }<br>
${vo.title }<br><!-- 객체의 필드값은 객체키.필드명으로 바로 출력할 수 있다 -->
</body>
</html>
el scope attribute 다루기el은 문자열이지만 숫자형식이라면 자동으로 형변환을 하여 연산을 한다페이지 데이터입니다. 10 제목입니다 |
만약 requestScope에 있는 데이터를 가져오고 싶으면 지정해주면 됩니다
${requestScope.data1 }
JSTL (JavaServer Pages Standard Tag Library)
- JSP(JavaServer Pages)에서 자주 사용되는 기능들을 간소화하기 위해 제공되는 표준 태그 라이브러리입니다
- Java 코드 대신 XML 처리, 조건문, 반복문, 국제화 등 다양한 기능을 JSP 태그 형태로 제공합니다
- JSP 스크립틀릿(<% %>) 코드를 최소화하여 코드 가독성을 높이고 유지보수를 용이하게 만듭니다
- 라이브러리가 있어야 사용할 수 있지만 spring 프로젝트에서는 pom.xml 의 dependency에 기본으로 들어있어 따로 추가하지 않고도 사용할 수 있습니다
- 접두어 : c(코어), fmt(포매팅), sql(데이터베이스), x(xml 처리), fn(함수)
jsp에서 사용하기 위해 밑의 코드를 추가해줘야 합니다. 스프링 프로젝트 생성시 home.jsp에 기본으로 들어가 있습니다
prefix 의 c를 변경할시 접두어를 변경할 수 있지만, 보통 변경하지 않고 사용합니다
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
주요 기능별 라이브러리
Core 태그 (core)
JSP에서 가장 많이 사용되는 태그로 조건문, 반복문, URL 처리 등을 제공합니다.
주요 태그:
- <c:if>: 조건문 처리
- <c:forEach>: 반복문 처리
- <c:choose>, <c:when>, <c:otherwise>: 다중 조건 처리
- <c:set>: 변수 설정
Format 태그 (fmt)
데이터의 형식화와 국제화를 위한 태그를 제공합니다.
주요 태그:
- <fmt:formatNumber>: 숫자 포맷 변환
- <fmt:formatDate>: 날짜 포맷 변환
- <fmt:bundle>: 국제화 리소스 번들 설정
SQL 태그 (sql)
데이터베이스와의 연동을 쉽게 하기 위한 태그로 간단한 SQL 쿼리 실행을 지원합니다.
주요 태그:
- <sql:query>: SELECT 문 실행
- <sql:update>: INSERT, UPDATE, DELETE 문 실행
XML 태그 (x)
XML 데이터 처리와 변환을 위한 태그를 제공합니다.
주요 태그:
- <x:parse>: XML 데이터 파싱
- <x:forEach>: XML 데이터를 반복 처리
주요 특징
JSTL은 코드의 간결성과 재사용성을 높여줍니다. 기존에는 Java 코드를 사용하여 조건문이나 반복문을 처리해야 했지만, JSTL을 사용하면 간단한 태그로 대체할 수 있습니다. 예를 들어,
<c:if test="${user.age > 18}">
<p>성인입니다.</p>
</c:if>
위 코드는 스크립틀릿 없이 조건문을 구현한 사례입니다.
JSTL 태그는 JSP 페이지의 가독성을 높이는 데 크게 기여합니다.
Java 코드와 HTML 코드가 뒤섞인 복잡한 페이지에서 태그 기반의 접근 방식은 유지보수가 용이합니다.
국제화(i18n)와 데이터 포맷팅을 지원하므로 다국어 웹 애플리케이션 개발 시 매우 유용합니다. 예를 들어, 숫자와 날짜의 포맷을 사용자 국가에 맞게 처리할 수 있습니다.
SQL 태그를 통해 간단한 데이터베이스 연동이 가능하지만, 실제 프로젝트에서는 보안상의 이유로 대부분 JSTL SQL 태그보다는 별도의 데이터 접근 계층(DAO)을 사용합니다.
JSTL은 EL(Expression Language)과 완벽하게 통합되어 동적으로 데이터를 처리할 수 있습니다.
예를 들어, <c:forEach> 태그 내에서 EL 표현식을 사용하여 데이터를 출력하거나 처리할 수 있습니다.
이처럼 JSTL은 JSP의 생산성을 높이고 코드의 품질을 개선하는 핵심 도구로 사용됩니다.
예제
var : 키 , value : 값으로 pageContext.setAttribute("name","홍길동");와 밑의 코드는 같습니다
<c:set var="name" value="홍길동" />
${name}<br>
홍길동 |
scope를 사용하여 영역을 지정할 수 있습니다
request.setAttribute("id","honghong");
<c:set var="id" value="honghong" scope="request"/>
${id}<br>
${requestScope.id}<br>
honghong honghong |
value 속성에 EL을 사용하게 되면 연산의 결과 값을 대입할 수 있습니다
<c:set var="sum" value="${10+20}" />
${sum}<br>
30 |
attribute 제거하기
영역을 지정하지 않았기 때문에 4개의 영역 안에 있는 모든 sum attribute제거합니다
<c:remove var="sum"/>
${sum}<br>
제거되었기 때문에 출력되는 내용이 없습니다
영역 지정하여 지우기
scope 지정시 해당 영역에서 일치하는 attribute 제거합니다
page 영역에 id가 없기 때문에 id값은 문제없이 출력됩니다
<c:remove var="id" scope="page"/>
id : ${id}<br>
honghong |
attribute 출력할 때 바로 EL을 사용하여 출력할 경우 밑의 결과처럼 html 태그가 적용되어 나옵니다
만약 사용자가 스크립트 태그를 사용하여 넣는 등의 행위가 일어날 경우 문제가 발생할 수 있기 때문에 출력방식을 바꿔야합니다.
<c:set var="html" value="${'<h1>hello</h1>'}" />
${html}<br>
hello |
밑의 코드와 같이 c:out을 사용하여 출력합니다.
out 태그를 사용하면 html이 포함되어 있는 문자열의 경우 출력시 html을 무력화 시켜 텍스트로만 출력할 수 있습니다
이때 default 속성을 사용하면 출력값이 null일 시 대체 텍스트를 지정할 수 있습니다
jstl out html : <c:out value="${html }" /> <br>
jstl out html : <h1>hello</h1> |
if문 작성하기
<c:if test="true">
true
</c:if>
<br>
<c:if test="false">
false
</c:if>
true |
<!-- 로그인 X -->
<%-- <c:if test="${loginUser == null}"> --%>
<c:if test="${empty loginUser}">
<a href="<%= request.getContextPath() %>/login.do">로그인</a><br>
</c:if>
<!-- 로그인 O -->
<%-- <c:if test="${loginUser != null}"> --%>
<c:if test="${not empty loginUser}">
<a href="<%= request.getContextPath() %>/mypage.do">마이페이지</a><br>
</c:if>
로그인이 null 일 때
로그인한 경우
session에 값을 넣어 로그인 상태로 만들어 확인하였습니다
<c:set var="loginUser" value="sample" scope="session" />
jstl에서는 else if문법은 없음으로 switch문을 사용하여 표현합니다
<c:choose>
<c:when test="true">
true1
</c:when>
<c:when test="true">
true2
</c:when>
</c:choose>
위에서부터 실행되며 choose 태그 안 when의 test 속성이 최초 true인 태그 안의 실행문이 실행됩니다
위 코드에서는 가장 먼저 실행된 true1만 출력됩니다
true1 |
c:otherwise 는 스위치 케이스의 default로 when이 모두 false인 경우는 otherwise 태그 안의 실행문이 실행됩니다
<c:choose>
<c:when test="${empty loginUser}">
<a href="<%= request.getContextPath() %>/login.do">로그인</a><br>
</c:when>
<c:otherwise>
<a href="<%= request.getContextPath() %>/mypage.do">마이페이지</a><br>
</c:otherwise>
</c:choose>
forEach
begin : 반복의 시작 인덱스를 설정합니다. (0부터 시작)
end : 반복의 끝 인덱스를 설정합니다.
<c:forEach begin="1" end="10">
반복<br>
</c:forEach>
반복 반복 반복 반복 반복 반복 반복 반복 반복 반복 |
step : 반복 인덱스를 증가시키는 단위를 설정합니다
count : 현재 반복의 순서를 알 수 있게 도와주는 내장 변수입니다.
<c:forEach begin="1" end="10" step="2" var="count">
반복${count }<br>
</c:forEach>
반복1 반복3 반복5 반복7 반복9 |
<ul>
<c:forEach var="item" items="${['사과', '바나나', '체리']}">
<li>${count}. ${item}</li>
</c:forEach>
</ul>
1. 사과 2. 바나나 3. 체리 |
count는 내장변수이기 때문에 별도의 선언 없이 안에서 바로 사용 가능합니다.
<ul>
<c:forEach var="number" begin="1" end="10" step="3">
<li>반복 ${count}회: ${number}</li>
</c:forEach>
</ul>
반복 1회: 1 반복 2회: 4 반복 3회: 7 반복 4회: 10 |
List 출력하기
@RequestMapping(value = "/jstl.do")
public String jstl(Model model) {
List<BoardVO> list = new ArrayList<BoardVO>();
BoardVO vo1 = new BoardVO();
vo1.setTitle("첫번째 제목입니다");
BoardVO vo2 = new BoardVO();
vo2.setTitle("두번째 제목입니다");
BoardVO vo3 = new BoardVO();
vo3.setTitle("세번째 제목입니다");
list.add(vo1);
list.add(vo2);
list.add(vo3);
model.addAttribute("list", list);
return "jstl";
}
<c:forEach items="${list}" var="vo">
${vo.title }<br>
</c:forEach>
첫번째 제목입니다 두번째 제목입니다 세번째 제목입니다 |
'Java' 카테고리의 다른 글
[Servlet] FrontController 회원 로그인, 내정보조회 등 (0) | 2024.10.26 |
---|---|
[Servlet] FrontController 게시글 수정하기 삭제하기 (0) | 2024.10.25 |
[Servlet] FrontController 게시글 상세 조회 (0) | 2024.10.24 |
[Servlet] FrontController 글 목록 조회 (0) | 2024.10.20 |
[Servlet] Front Controller (0) | 2024.10.19 |