EL/JSTL

부트캠프(END)/Web|2022. 7. 25. 21:01
https://mvnrepository.com/artifact/javax.servlet/jstl/1.2
위 링크에서 jar파일을 다운로드받아 lib폴더에 추가해 주어야 사용할 수 있다!

 

EL / JSTL 

EL(Expression Language : 표현식)

화면에 데이터 출력할 때 <%=..%> 대신 ${..}을 사용한다.

JSTL(JSP Standard Tag Library)

: 제어문, 변수 선언, 메서드, 화면 이동에 이용된다.
<%..%> 대신 사용한다.

 

즉, <% ... %> 안에 들어가는 코드는 JSTL로 대체할 수 있고,

<%= ..%> 안에 들어가는 코드는  EL로 대체할 수 있다.

 

*MVC구조, Spring, Spring-Boot에서 많이 사용된다.

Java와 HTML을 분리 → MV
Java와 HTML을 분리하고 연결 → MVC

프로그램을 태그형으로 변경하면 유지보수가 편하고 CSS작업이 쉬워진다.

 


(1) EL (${..})

: JSP 페이지 내에서 자바 코드를 최소화하기 위해 만들어진 표현식(출력식)이다.
자바 전용이 아니기 때문에 자바 형식으로 되어 있지 않다.

${..} 안에 들어가고, 들어갈 수 있는 것은 한정되어 있다.

 

request나 session 등에 저장된 데이터를 불러 오는 데 사용할 수 있고,

단순 연산 결과를 담는 것도 가능하다.

 

- 자바의 일반 변수(X) → <%=..%> 써야함

- request.getAttribute() : 출력후 종료를 원할 때

- session.getAttribute() : 데이터를 유지하고 싶을 때

- applitcation.getAttribute()

- request.getParameter()

- request.getParameterValues()

request나 session, application은 JSP에서 사용되는 내장 객체

  → 기존의 데이터 외에 추가된 데이터를 첨부할 수 있다.(setAttribute()로) 먼말?

 

JSP는 1회용이고 보안이 허술하다(데이터를 전송할 때 파일 전체를 전송하기 때문)는 단점이 있다.

→ MVC(MV)를 이용해서 자바와 HTML을 분리하고 재사용성/확장성을 개선한다.

 

 

 

연산자

++, --는 존재하지 않는다.

산술연산자
+ : 순수하게 산술만 가능하다.
(Java) "10"+"20" = 1020 ↔ (EL) ${"10"+"20"}=30
문자열 결합은 += 로 진행

→ ${"Java"+"Hello"} == 오류!

→ ${"Java"+="Hello"} == JavaHello
${null+10} = 10 *null은 0으로 취급
/ : 0으로 나누면 에러 발생!
정수/실수는 실수다.

 

비교연산자 : true/false로 결과 반환

기호 다른 용법
== eq
!= ne
< lt
> gt
<= le
>= ge

비교연산자로 문자열, 날짜 비교가 가능하다.

→ id.equals("admin") 이라고 할 것 없이 ${id=='admin'} 로 간단하게!


논리연산자
&& : 직렬연산자 (두 개의 조건이 TRUE여야 TRUE) == and
|| : 병렬연산자 (둘 중 하나 이상의 조건이 TRUE면 TRUE) == or
! : 부정연산자 == not

 

삼항연산자
(조건)?값1:값2 → 조건이 true면 값1, false면 값2

 

 

연산자 예시

<%@ 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>
	<h3>산술연산자(+,-,*,/(div),%(mod))</h3>
	&#36{10+20}=${10+20}<br>
	&#36{"10"+"20"}=${"10"+"20"}<br>
	&#36{10/3}=${10/3}<br>
	&#36{10 div 20}=${10 div 3}<br>
	&#36{10%3}=${10%3}<br>
	&#36{10 mod 3}=${10 mod 3}<br>
	<h3>비교연산자(==(eq),!=(ne), <(lt), >(gt), <=(le), >=(ge) => true/false)</h3>
	&#36{100==200}=${100==200}<br>
	&#36{100 eq 200}=${100 eq 200}<br>
	&#36{100!=200}=${100!=200}<br>
	&#36{100 ne 200}=${100 ne 200}<br>
	&#36{100<200}=${100<200}<br>
	&#36{100 lt 200}=${100 lt 200}<br>
	&#36{100>200}=${100>200}<br>
	&#36{100 gt 200}=${100 gt 200}<br>
	&#36{100<=200}=${100<=200}<br>
	&#36{100 le 200}=${100 le 200}<br>
	&#36{100>=200}=${100>=200}<br>
	&#36{100 ge 200}=${100 ge 200}<br>
</body>
</html>

 

결과

 

배열은 array[i] 로 i번째 항목을 가져오는 게 가능하다.

일단 지금은 그 정도만!

 

배열 예시

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<%
    List<String> list=new ArrayList<String>();
    list.add("red");
    list.add("blue");
    list.add("green");
    list.add("yellow");
    list.add("white");
    
    request.setAttribute("list", list);//session,application
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
   <h3>자바1</h3>
     <ul>
   <%for(int i=0;i<list.size();i++)
      { %>
         <li><%=list.get(i) %></li>
   <%} %>
    </ul>
    <h3>자바2</h3>
     <ul>
   <%for(String color:list)
      { %>
         <li><%=color %></li>
   <%} %>
    </ul>
   <h3>EL</h3>
   <ul>
     <li>${list[0] }</li>
     <li>${list[1] }</li>
     <li>${list[2] }</li>
     <li>${list[3] }</li>
     <li>${list[4] }</li>
   </ul>
</body>
</html>

 

 

EL 내장객체

${name} → 일반 변수 출력이 아니기 때문에 출력되지 않음.
request, session에 추가된 값을 출력한다.

request.setAttribute("name", "kimdoodoo");
${name} → kimdoodoo 출력
= request.getAttribute("name"); 와 같은 기능을 한다.

 

session.setAttribute("id","admin");
${sessionScope.id} 

1. requestScope***

request.getAttribute("name") == ${request.name} == ${name}
이거로 값을 가져오려면 request.setAttribute(key,value) 로 값을 넣어줘야 함. 
value출력하려면 getAttribute(key) 인데.. ${requestScope.key} 로 다르게 표현할 수 있다.
더 간단하게는 아예 ${key} 로도 가능함.
2. sessionScope***

session.getAttribute("name") == ${sessionScope.name} == ${name}
session.setAttribute(key, value)로 등록하고 ${sessionScope.key} 로 불러올 수 있다.
이것도 마찬가지로.. ${key}로도 불러올 수 있다.
단, request, session에 같은 키가 있는 경우 request가 우선순위임.
3. applicationScope

application.getAttribute("name") == ${application.name}
4. param

request.getParameter("name") == ${param.name}
5. paramValue

request.getParameterValues("hobby") ==${paramValues.hobby}

일반 변수를 출력하는 게 아니라 request, session 등에 추가된 값을 출력한다는 점!!!!!

 

 

사번 eno, 이름 name, 부서 dept를 갖는 클래스 Employee에 데이터를 넣고 불러오기

package main;
import javax.servlet.http.HttpServletRequest;

public class Model {
	public void getEmpData(HttpServletRequest request) {
		Employee e = new Employee();
		e.setEno(1100);
		e.setName("kimdoodoo");
		e.setDept("dev");
		
		request.setAttribute("e", e);
	}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="main.*"%>
<jsp:useBean id = "model" class="main.Model"/>
<%
	model.getEmpData(request); //Controller
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	사번 : ${e.getEno() }<br>
	-> 자바: <%=((Employee)request.getAttribute("e")).getEno() %><br>
	이름 : ${e.getName() }<br>
	-> 자바: <%=((Employee)request.getAttribute("e")).getName() %><br>
	부서 : ${e.getDept() }<br>
	-> 자바: <%=((Employee)request.getAttribute("e")).getDept() %><br>
	<h3>약식</h3>
	사번 : ${e.eno } <br>
	이름 : ${e.name } <br>
	부서 : ${e.dept } <br>
</body>
</html>

 

 

 

(2) JSTL (<c:..>)

Tag로 자바 제어문을 제공한다.

taglib : 자바 제어문, 자바 변수 선언, 화면 이동, 날짜 변경, 숫자 변경, String함수
→ 태그 형태로 만들어져 있다.

HTML/CSS, Javascript, java, SQL 관련 데이터를 분산 처리하기 위해 사용된다.

JSP 페이지에서는 자바 코드 없이 태그형 프로그램만 제어하도록 하면 깔끔하다.

XML태그로 제작되어 있다.
- 대/소문자를 구분함
- 여는 태그와 닫는 태그가 동일해야 함
- 지원하는 속성만 사용할 수 있음
- 속성값은 반드시 큰따옴표("")로 감싸주어야 함

 

이런 식으로 쓰는 것이다. ↓ 

 

<%
for(int i=1;i<=100;i++){
if(i%2==0){
%> 
    HTML 출력 (자바영역과 HTML영역을 반드시 분리해 주어야 한다.) 
    <%=i %>&nbsp; 
<%
    }
} %> 

이거랑 밑에 코드(JSTL:Java Standard Tag URL)랑 똑같음 
<c:forEach var="i" begin="1" end="100" step="1"> (step은 생략해도됨, 감소는 불가!) 
    <c:if test="i%2==0"> ${i}&nbsp; </c:if>
</c:forEach>

 

 

쓰임새에 따라 JSTL도 여러 종류가 있다.

크게 core, fmt, fn 을 많이 사용한다.

 


<core>

: 가장 자주 쓰이는 태그.

변수 선언, 화면 출력, 제어문, 화면 이동에 이용된다.

JSP페이지에서 아래와 같이 import하여 사용한다.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


-변수 선언
*<c:set var="key" value="value">

<c:set var="name" value="kim"/> 
⇒ request.setAttribute("name","kim)

MVC에서는 특별한 경우가 아니라면 잘 사용되지는 않는다.

 

 

-화면 출력
JQuery(javascript 라이브러리)가 $형태로 되어 있기 때문에 충돌을 방지하기 위해 사용한다.

→ ${} == *<c:out value=""> : JS연동할 때 많이 사용

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<%-- 라이브러리 로드 / core라고 해주면 <core: 로 쓸 수 있다.--%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

<%
  String name = "kim"; //${}로 출력하고 싶으면 request.setAttribute("name","kim"); 해줘야 함
  request.setAttribute("name", name);
%>
<c:set var="addr" value="Seoul"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
  이름 : ${name }<br>
  주소 : ${addr }<br>
  <%--$안주고 출력하는법 --%>
  <c:out value="${addr}"/>
  <%-- 근데 굳이 이렇게 할 필요 없죠 JQuery 와 충돌 위험도 있음. --%>
</body>
</html>

 

 

-제어문(반복문)

일반 for문

<c:forEach var="루프변수명" begin="초기값" end="조건" step="증가값"> </c:forEach>
⇒ <c:forEach var="i" begin="1" end="10" step="1"></c:forEach> == for(int i=1; i<=10; i++){}

step이 1일 경우 생략이 가능하고, 마이너스값은 사용할 수 없다.

 

***forEach구문

자바에서 for(Object obj:list){}와 같은 역할을 한다.

<c:forEach var="받는 변수" items="배열/Collection" varStatus="인덱스번호"></c:forEach>
⇒ <c:forEach var="vo" items="list"></c:forEach> == for(VO vo:list){}

 

 

예시!

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h3>자바 if</h3>
	<%for(int i=1; i<=10; i++){ 
		if(i%2==0){
	%>
		<%= i %>&nbsp;
	<%	}
	}%>
	<h3>JSTL if</h3>
	<c:forEach var="i" begin="1" end="10">
		<c:if test="${i%2==0}">
		${i} &nbsp;
		</c:if>
	</c:forEach>
	
	<h3>자바 if2</h3>
	<%
		List<String> list = new ArrayList<String>();
		list.add("kim1");
		list.add("kim2");
		list.add("kim3");
		list.add("kim4");
		list.add("kim5");
		list.add("kim6");
		list.add("kim7");
		list.add("kim8");
		list.add("kim9");
		list.add("kim10");
	%>
	<% for(int i=0;i<list.size();i++){
			if(i%2==0){
		%>
		<%= list.get(i) %><br>
	<%		}
		}%>
	<h3>JSTL if2</h3>
	<c:set var="list" value="<%=list %>"/>
	<c:forEach var="name" items="${list }" varStatus="s"> <%--list의 index번호 --%>
		<c:if test="${s.index%2==0}">
			${name }<br>
		</c:if>
	</c:forEach>
</body>
</html>
<h1>JSTL(MVC)=실무, Spring, Spring-Boot</h1>
<table width=560 border=1>
	<tr>
		<c:forEach var="i" begin="2" end="9">
		<th>${i}</th>
		</c:forEach>
	</tr>
	<c:forEach var="i" begin="2" end="9">
	<tr>
		<c:forEach var="j" begin="2" end="9">
		<td align=center>${j}*${i}=${i*j}</td>
	</c:forEach>
	</tr>
	</c:forEach>
</table>

 

 

 

 

-제어문(조건문)

if문

<c:if test="조건문">

<c:if test="${i>10}">
</c:if>

<c:if> 의 단점 : else가 없다.

else등을 쓰고 싶으면 아래와 같은 다중조건문을 사용해야 한다.

 

다중조건문

<c:choose>
  <c:when test="조건">case1</c:when>
  <c:when test="조건">case2</c:when>
  <c:otherwise>else</c:otherwise>
</c:choose>

 

 

-화면 이동

*<c:redirect>

화면 이동할 때 사용 == sendRedirect() 

<c:redirect url="이동할 주소">

<c:redirect url="sample.jsp"/>

 

-문자열 읽기

<c:forTokens> 

StringTokenizer st → st.hasTokens

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
	List<String> list = new ArrayList<String>();
	list.add("kim1");
	list.add("kim2");
	list.add("kim3");
	list.add("kim4");
	list.add("kim5");
//	request.setAttribute("list", list); //이렇게 하지말구 <c:set>으로
%>
<c:set var="list" value="<%=list %>" />
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h3>자바 forEach문</h3>
	<%for(String name:list){ %>
		<%=name %><br>
	<%} %>
	<h3>JSTL forEach문</h3>
	<c:forEach var="name" items="${list }">
		${name }<br>
	</c:forEach>
	<h3>자바 데이터 구분</h3>
	<%
	String data = "red,green,blue,yellow,white";
	StringTokenizer st = new StringTokenizer(data,",");
	while(st.hasMoreTokens()){
	%>
	<%=st.nextToken() %>&nbsp;
	<%} %>
	<h3>JSTL StringTokenizer</h3>
	<c:forTokens items="red,green,blue,yellow,white" delims="," var="color">
	${color }&nbsp;
	</c:forTokens>
</body>
</html>

 

 


<fmt>

: format = 변환(날짜 변환, 숫자 변환)

→ 오라클에서 받아올 때 많이 사용 == java의 SimpleDateFormat, NumberFormat

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<fmt:formatDate value="${today}" pattern="yyyy-MM-dd"/>
<fmt:formatNumber value="${10000}" pattern="99,999"/>
<fmt:formatNumber value="${10000}" type="number" maxFractionDigits="3"/>

$를 사용하지 않고 곧장 출력한다.

시간을 정확히 가져올 수 없고 대부분의 경우 오라클에서 바로 변환해서 가져오기 때문에 잘 사용되지는 않는다.

 

 


<fn>

: function, String 메서드

최근에는 JSP 없이 HTML 자체를 출력하는 식으로 변경되고 있다.
HTML에서도 루프 등을 자체 처리해서 돌릴 수 있음(ThymeLeaf, Vue, React등으로..)

그 외에 xml, sql 등도 있지만 잘 사용되지 않는다.

 

 

 

예제(참고)

더보기

DAO

package dao;
import java.util.*;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;

public class LocationDAO {
	private Connection conn;
	private PreparedStatement ps;
	public void getConnection() {
		try {
			Context init = new InitialContext();
			Context c = (Context)init.lookup("java://comp/env");
			DataSource ds = (DataSource)c.lookup("jdbc/oracle");
			conn = ds.getConnection();
		}catch(Exception ex) {
			ex.printStackTrace();
		}
	}
	
	public void disConnection() {
		try {
			if(ps!=null) ps.close();
			if(conn!=null) conn.close();
		}catch(Exception ex) {
			ex.printStackTrace();
		}
	}
	
	public List<LocationVO> locationListData(int page){
		List<LocationVO> list = new ArrayList<LocationVO>();
		try {
			getConnection();
			String sql = "SELECT no, title, poster, num "
					+"FROM (SELECT no,title,poster,rownum as num "
					+"FROM (SELECT no, title, poster "
					+"FROM seoul_location ORDER BY no ASC)) "
					+"WHERE num BETWEEN ? AND ?";
			ps = conn.prepareStatement(sql);
			int rowSize = 12;
//			int start = (page*12)-11;
//			int end = page*12; 이렇게 하는것보다 아래처럼 하는 게 더 유지보수에 좋음.
			int start = (page*rowSize)-(rowSize-1);
			int end = page*rowSize;
			
			ps.setInt(1,start);
			ps.setInt(2, end);
			
			ResultSet rs = ps.executeQuery();
			while(rs.next()) {
				LocationVO vo = new LocationVO();
				vo.setNo(rs.getInt(1));
				vo.setTitle(rs.getString(2));
				vo.setPoster(rs.getString(3));
				
				list.add(vo);
			}
		}catch(Exception ex) {
			ex.printStackTrace();
		}finally {
			disConnection();
		}
		return list;
	}
}

jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*, dao.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:useBean id = "dao" class="dao.LocationDAO"/>
<% 
	String strPage = request.getParameter("page");
	if(strPage==null)
		strPage="1";
	int curPage = Integer.parseInt(strPage);
	List<LocationVO> list = dao.locationListData(curPage);
	request.setAttribute("list",list);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
</head>
<body>
	<div class="container">
		<div class="row">
		  <c:forEach var="vo" items="${list }">
		  	<div class="col-md-3">
      		  <div class="thumbnail">
        		<a href="#" target="_blank">
          		  <img src="${vo.poster }" alt="Lights" style="width:250px; height:200px;">
          		  <div class="caption">
            	   <p>${vo.title }</p>
         		  </div>
        		</a>
      		 </div>
    		</div>
		  </c:forEach>
		</div>
	</div>
</body>
</html>

이랬던 걸 자바 처리를 돕는게 Model(자바와 HTML을 분리)

Model

package model;
// EL/JSTL -> MVC용임 -> JSP에서 자바 코딩을 최소화
import javax.servlet.http.HttpServletRequest;
import dao.*;
import java.util.*;
public class SeoulModel {
	public void locationListData(HttpServletRequest request) {
		LocationDAO dao = new LocationDAO();
		String strPage = request.getParameter("page");
		if(strPage==null)
			strPage="1";
		int curPage = Integer.parseInt(strPage);
		List<LocationVO> list = dao.locationListData(curPage);
		request.setAttribute("list",list);
	}
}

JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*, dao.*, model.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:useBean id = "model" class="model.SeoulModel"/>
<% 
	model.locationListData(request);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<style type="text/css">
  .container{
  	margin-top: 50px;
  }
</style>
</head>
<body>
	<div class="container">
		<div class="row">
		  <c:forEach var="vo" items="${list }">
		  	<div class="col-md-3">
      		  <div class="thumbnail">
        		<a href="#" target="_blank">
          		  <img src="${vo.poster }" alt="Lights" style="width:250px; height:200px;">
          		  <div class="caption">
            	   <p>${vo.title }</p>
         		  </div>
        		</a>
      		 </div>
    		</div>
		  </c:forEach>
		</div>
	</div>
</body>
</html>

 

 

'부트캠프(END) > Web' 카테고리의 다른 글

MVC (1)  (0) 2022.07.27
DBCP(DataBase Connection Pool)  (0) 2022.07.22
JSP : 내장 객체 / session  (0) 2022.07.21