'

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [STUDY20] JSP, JSP TAG EL&JSTL
    FISA 2026. 1. 22. 16:35

    1. JSP의 개요 및 동작 원리

    2. JSP TAG?

    3. JSP TAG's EL(Expression Langauge) &

        JSTL( JSP Standard Tag Library )

    4. CoreTage

    5. 실습 Code

     

    1. JSP의 개요

    Java Server Page예요. 이름에서도 볼 수 있듯이, 서버에서 실행되어 ""동적"" 웹 페이지를 만들어 브라우저로 내려주는 자바 기반 템플릿 기술입니다. 실행 시점에서 servlet으로 변환, 컴파일 되어서 servlet컨테이너에서 동작하여 변경되기 전까지 캐시되어 재사용되는 구조로 설명되어요.

     

    Servlet과 JSP의 공통점은

    1. 웹 컨텐츠를 생성하기 위한 JAVAEE지원 스펙

    2. Web Container내에서 실행

    3. client요청을 thread로 처리해요.

    차이점은

    servlet은 

    확장자 *.java / 구성잊 자바 문법 / controller로직 권장

    jsp는

    확장자 *.jsp / 구성이 java+html tag+jsp scripting tag+ jsp action tag + el + jstl / 실행시 web container가 servlet으로 자동변환 / view 로직을 권장해용.

     

    1.2. JSP 동작 원리 및 LIFE CYCLE

    (1)최초 client가 요청시 servlet으로 변환 - (2) servlet으로 변환 - (3) 컴파일 - (4) byte code를 메모리에 로딩 - (5) servlet 객체 생성 및 service 메소드 실행

    두번째 client요청시부터는 service 메소드로 실행해요.

     

    (1)은 url로 클라이언트가 요청하겠죠.

    (2)는 jsp가 servlet으로 변환될 때, Was가 해당 jsp파일을 확인해요.

    서버에서 파일을 확인하고, jsp파일을 java로 변환해서 servlet소스로 만들어요.

    이 파일은 보통

    /work/Catalina/localhost/프로젝트명/org/apache/jsp/example_jsp.java

    에 저장됩니다. 이단계에서

    html->out.write()

    <% %> ->java코드

    <%=%> ->out.print()로 변환되어요.

     

    (3) servlet컴파일

    변환된 .java 파일을 jdk컴파일러로 컴파일해요. .class파일이 나오겟죠

    (4) bytecode를 메모리에 로딩해요. 이때부터 실행 가능한 상태가 되어요

    (5)servlet객체 생성

    jsp는 servlet이므로 객체가 단 한개만 생성되어요. = 싱글톤구조입니다.

     

     

    만약 두번째 client요청은 이미 생성된 상태이므로 service()메소드만 실행되어요

    JSP Life Cycle 단계

    1. Translation
      • JSP → Servlet(.java)
    2. Compilation
      • Servlet → Byte Code(.class)
    3. Loading
      • JVM 메모리에 로딩
    4. Instantiation
      • Servlet 객체 생성
    5. Initialization
      • jspInit()
    6. Request Processing
      • service() → _jspService()
    7. Destroy
      • jspDestroy()

    라고볼수있네용


    2.2. JSP TAG

    비지니스 로직과 view를 분리하기위해 사용해요

    과거 정통방식이고 비추천되는 코드는

    JSP Scripting Tag입니다.

     

    <%@ page contentType="text/html; charset=UTF-8" import="java.util.*" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

     

    이렇게 쓰는거요,,

     

    그리고 <%-- --%>는 서버에서만 처리되어서 안전한 주석이빈다.

     

    JSP ACtion Tag도 있어요

    <jsp:forward page="nextPage.jsp" />   <!-- 페이지 이동 -->
    <jsp:include page="header.jsp" />     <!-- 다른 JSP 포함 -->
    <jsp:useBean id="user" class="com.example.User" scope="request" />
    <jsp:setProperty name="user" property="name" value="지혜"/>
    <jsp:getProperty name="user" property="name" />

     

     

     

    3.1. JSP TAG's EL & JSTL & coreTag

     

    EL 은 ${}와같이 표현해요.

    클라이언트 부라우저 화면에 출력하는 기능을 제공합니다. java코드를 간소화합니다.

    <!-- (기존) 스크립틀릿 -->
    <%
      MemberVO vo = (MemberVO) request.getAttribute("mvo");
    %>
    <%= vo.getName() %>
    <!-- (EL) -->
    ${requestScope.mvo.name}
    <!-- requestScope는 보통 생략 가능 -->
    ${mvo.name}
    <!-- (기존) -->
    <%= request.getParameter("name") %>
    
    <!-- (EL) -->
    ${param.name}

     

    딱봐도 .... 줄어든게 보이죠!! 

     

    자바 빈 프로퍼티 접근을 객체.프로퍼티 형태로 합니다. 마치like js에서 json변수가저오는 느낌?

    근데 scope가 뭐고 자바 빈 프로퍼티는 뭐냐...

     

    스코프는, 어떤 값을 어디까지 얼마동안 공유해서 쓸 수 있나를 정해둔 생명주기예요

    JSP/servlet에선 보통 page/request/session/application 네가지로 구분합니다.

    page-현재 jsp페이지 안에서만 유효,페이지 지역변수 느낌

    request - client요청후 응답까지 유효하는 요청1번에 생애주기

    session - 한 브라우저 단위로 여러 요청에 걸쳐유지됨. 로그인!세션!쿠키!

    application - 젤큰단위.애플리케이션 시작~종료까지 유지

     

    자바빈 프로퍼티?
    자바빈은 보통 “기본 생성자 + getter/setter 규칙”을 따르는 자바 객체를 의미하고, 그 객체가 외부에 노출하는 name, age 같은 값 단위를 “프로퍼티”라고 부른다. EL에서 ${mvo.name}처럼 쓰면 “mvo 객체의 name 프로퍼티”를 읽는 의미로 사용되며, 내부적으로는 관례에 따라 getter(getName())를 호출하는 방식으로 이해하면 된다.

     

     

     

    JSTL은 JSP에서 조건/반복/변수설정/URL생성 같은 작업을 태그로 제공해서 스크립틀릿을 거의 쓰지 않도록 도와주는 표준 라이브러리! EL이 데이터를 꺼내는 방식이라면 이건 제어문(if/for)같은 로직을 태그로 쓰는 도구

     

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    
    
    출력: c:out
    ${mvo.name}
    <c:out value="${mvo.name}" />
    
    
    변수 저장: c:set
    어떤 값을 스코프에 담거나(변수처럼) 재사용할 때 씁니다.
    <c:set var="userName" value="${mvo.name}" />
    안녕하세요, ${userName}
    
    
    조건문: c:if
    <c:if test="${empty loginUser}">
      로그인 해주세요
    </c:if>
    
    <c:if test="${not empty loginUser}">
      ${loginUser.name} 님 환영합니다
    </c:if>
    
    다중 분기: c:choose / c:when / c:otherwise
    <c:choose>
      <c:when test="${param.role == 'ADMIN'}">
        관리자 화면
      </c:when>
      <c:when test="${param.role == 'USER'}">
        사용자 화면
      </c:when>
      <c:otherwise>
        권한 없음
      </c:otherwise>
    </c:choose>
    
    반복문: c:forEach
    <c:forEach var="item" items="${items}">
      <div>${item.name}</div>
    </c:forEach>
    <c:forEach var="item" items="${items}" varStatus="st">
      ${st.index} : ${item.name}
    </c:forEach>

    이런식으로 c....를씁니다.

     

     

     

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ page import="java.util.ArrayList, model.domain.People" %>   
     
    <%@ 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>
    
    <% //scriptlet 이라는 이름의 순수 자바 코드 개발하는 tag
    
    	//단순 test를 위한 데이터 구성용으로만 사용 예정
    	request.setAttribute("rData1", "꿈이 뭐야/명리학자/부자");
    	session.setAttribute("sData1", "가장 중요한 요소/건강/가족");
    	session.setAttribute("sData2", "가장 중요한 요소/건강/건강");
    
    	//ArrayList에 문자열들 저장
    	ArrayList<String> all1 = new ArrayList<>();
    	all1.add("n8n");
    	all1.add("art&tech");
    	all1.add("시간 쪼깨기");
    	all1.add("부자되세요, 마음이 편해짐, 시간 여유!!!⭐🌟🌟");
    	
    	//ArrayList에 DTO 저장
    	ArrayList<People> all2 = new ArrayList<>();
    	all2.add(new People("연아", 30));
    	all2.add(new People("재석", 50));
    	all2.add(new People("이순신", 50));
    	
    	session.setAttribute("sData3", all1);
    	session.setAttribute("sData4", all2);
    	
    %>
    
    	<h3>EL tag</h3>
    
    	<table border="1">
    		<tr><td>non-EL</td><td>EL</td></tr>
    		
    		<tr><td>1+3</td><td>${1+3}</td></tr>	
    		
    		<tr><td>'a' == 'a'</td><td>${'a' == 'a'}</td></tr>
    		<tr><td>'a' != 'a'</td><td>${'a' != 'a'}</td></tr>
    		<tr><td> 50 != 50 </td><td>${ 50 != 50 }</td></tr>
    		
    		<tr>	
    			<td>request.getAttribute("rData1")</td>
    			<td>${requestScope.rData1}</td>
    		</tr>
    
    		<tr>
    			<td>session.getAttribute("sData1")</td>
    			<td>${sessionScope.sData1}</td>
    		</tr>
    
    		<tr>
    			<td>((ArrayList<String>)session.getAttribute("sData3")).get(0)</td>
    			<td>${sessionScope.sData3[0]}</td>
    		</tr>
    
    		<%-- ? sData4로 저장된 연아 이름만 출력 
    			.name : getName() 호출 의미
    		--%>
    		<tr>
    			<td>((ArrayList<People>)session.getAttribute("sData4")).get(0).getName()</td>
    			<td>${sessionScope.sData4[0].name}</td>
    		</tr>
    
    	</table>
    
    	<br><hr><br>
    	<!-- ? sData4로 세션에 저장된 ArrayList의 People들의 나이 비교를 해서
    	age가 50인 사람의 이름와 나이값 브라우저 출력 
    	deptAllView.jsp의 3단계 참조 - jstl의 forEach 활용 요청
    	 -->
    	<c:forEach items="${sessionScope.sData4}" var="data">
    		<c:if test="${data.age == 50}">
    			${data.name}-${data.age}<br>
    		</c:if>
    	</c:forEach>
    	
    	<br><hr><br>
    	<h5>데이터가 null의 경우의 EL 처리 방식</h5>
    	<%
    		//로컬 변수는 선언시 자동 초기화 미진행
    		//선언만 했을 경우 null도 아니고 아무데이터도 아님
    		//String value = null; 
    		//out.println(value);//브라우저에 null 출력  	
    	
    //		String value = "연아"; 
    		//System.out.println(value.charAt(1));
    		//out.println(value.charAt(1));
    		
    		//EL에서 브라우저에 출력을 위한 test 코드 구성
    		/* 주의사하 : EL 브라우저에 null인 경우 blank 로 정리함
    		 null 경우 출력 정보 꼼꼼하게 관리 필요
    		*/
    		String value = null; 
    		out.println(value);//브라우저에 null 출력  
    		request.setAttribute("rData2", value);		
    	%>
    	<hr color="red" size="3">
    	rData2가 null인 경우에는 "데이터가 없음" 출력 / 있을 경우 data 출력  (비교 적용)<br>
    	ELtag의 null값 처리 비교 학습 : == / != / empty / not empty<br>
    		
    	1. ${requestScope.rData2}  <br>
    	2. ${requestScope.rData2 == null} <br>
    	3. ${empty requestScope.rData2} <br>
    	3. ${not empty requestScope.rData2} <br>
    	
    	<hr>
    
    	
    </body>
    </html>

     

     

    728x90

    댓글

Designed by Tistory.
티스토리 친구하기