본문 바로가기

Jsp

JSTL / EL / Scope

JSP

- HTML과 Java코드를 혼합하여 동적인 웹 페이지를 생성하는데 사용되는게 JSP잖아요? 서블릿을 더 쉽게 사용할 수 있는 버전이라고 보면 됩니다. 요약하면 HTML을 작성하는데 최적화된 템플릿 언어입니다.

 

1. JSTL 

- JSP에서 사용할 수 있는 태그 라이브러리로 일반적인 프로그래밍 작업을 쉽게할 수 있게 합니다. JSP에서 코드의 가독성을 높일 수 있죠. 

 

일단 JSP에서 JSTL을 사용하려면 라이브러리를 추가하고 선언해야 합니다.

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

 

이런 식으로요. 제가 썼던 코어 태그와 포맷 태그를 예시로 설명할게요.

 

1-1. core 태그

  • 조건문, 반복문, URL 처리, 문자열 처리 등을 제공합니다.
  • <c:if> , <c:choose>, <c:forEach>, <c:out>, <c:set>, <c:url> 등
// 조건문 사용
<c:if test = "${not empty param.name}">
   <p> Hello, ${param.name} </p>
</c:if>

// 반복문 사용
<c:forEach var = "item" items = ${itemList}>
   <li> ${item} </li>
</c:forEach>

// 변수에 값 지정
<c:set var = "path" value = "${}"/>

// 데이터 출력
<c:out value = "${path}"/>

// else if
<c:choose>
   <c:when test = "${name eq 'A'}">
      <p> name is A </p>
   </c:when>
   <c:otherwise>
      <p> name is B </P>
   </c:otherwise>
</c:choose>

 

* c:out을 굳이 써야 할까요..? 안 쓰고 출력할 수 있잖아요? 대부분 굳이..? 싶은건 보안 떄문인거 같아요.. 제 느낌상 ㅎ..

 

XSS 공격을 막기 위해서입니다. 악의적인 스크립트 공격을 막기 위해 사용자 입력을 이스케이프 처리하기 위해서 입니다.

 

무슨 말이냐면 예시로 로그인 폼에서 아이디 칸에 <script>alert('XSS 공격!');</script> 이렇게 입력한다고 해볼게요. 만약 이스케이프 처리를 하지 않으면 브라우저는 태그를 인식해서 XSS 공격! 이라는 경고창이 발생하게 될거에요. 우리의 의도와 상관없이.

<p>id: <script>alert('XSS 공격!');</script></p>

 

이런 식으로 사용자가 악의적으로 태그를 삽입해서 원치 않는 결과를 도출해 낼 수 있다는거죠. 하지만 이스케이프 처리를 하게 되면?

<p>id: &lt;script&gt;alert('XSS 공격!');&lt;/script&gt;</p>

 

이런 식으로 HTML 문자를 안전한 문자열로 변환하기 때문에 브라우저에서는 위와 같이 표현됩니다. 

 

1-2. fmt 태그

  • 숫자, 날짜 형식 지정, 메시지 국제화 기능
  • <fmt:formatDate>, <fmt:timeZone>, <fmt:formatNumber> 등
<fmt:formatDate value = "${now}" pattern = "yyyy-MM-dd" type = "date"/>
<fmt:formatDate value = "${now}" pattern = "HH:mm" type = "time"/>

 

2. EL

 

EL이 뭐냐면 기존의 Script tag의 표현식에서 쉽고 간결하게 객체의 property를 출력해주는 기술입니다.

 

예를 들어 객체의 프로퍼티에 접근하려면 자바 코드를 직접 JSP 페이지에 작성해야 했습니다.

<%@ page import="com.example.MyBean" %>
<%@ page import="javax.servlet.http.HttpSession" %>
<%@ page import="javax.servlet.http.HttpServletRequest" %>

<%
    HttpSession session = request.getSession();
    MyBean myBean = (MyBean) session.getAttribute("myBean");
%>

<p>Name: <%= myBean.getName() %></p>
<p>Age: <%= myBean.getAge() %></p>

 

이런 식으로 말이죠. 이는 가독성과 유지보수면에서 아주 복잡했기 때문에 EL이 등장했습니다.

<p>Name: ${myBean.name}</p>
<p>Age: ${myBean.age}</p>

 

이렇게 간단하게 사용할 수 있게 된거죠. 근데 어떻게 이게 가능한 걸까요? 

 

EL은 객체를 검색할 떄 

 

Page Scope -> Request Scope -> Session Scope -> Application Scope 순서로 범위를 검색합니다. 

 

원래는 범위 지정자를 써서 session.myBean.name 이나 requestScope.myBean.age 이렇게 쓰는게 맞지만 검색하는 순서가 정해져 있기 때문에 생략해도 가능은 합니다.

 

2-1. Page Scope

  • JSP 페이지 내에서만 유효한 범위
  • 같은 JSP 페이지에서만 접근할 수 있다.
  • JSP 페이지가 실행될 때 생성되며 처리가 끝나면 소멸된다.
  • JSP 페이지 내에서 임시로 필요한 데이터 저장

2-2. Request Scope

  • 하나의 HTTP 요청 내에서 유효한 범위
  • 여러 JSP 페이지나 서블릿 간 데이터 공유
  • HTTP 요청이 생성될 때 생성 응답 완료 후 소멸
  • 요청에 대한 처리 결과를 다른 페이지로 전달할 때 저장

2-3. Session Scope

  • 하나의 세션 내에서 유효한 범위
  • 같은 클라이언트의 여러 요청 간 데이터 공유
  • 클라이언트 세션 생성시 생성 만료되거나 무효될 때 소멸
  • 사용자 로그인 정보, 장바구니 등 세션 동안 유지해야 하는 데이터 저장

2-4. Application Scope

  • 애플리케이션 전체에서 유효한 범위
  • 모든 클라이언트의 모든 요청 간 데이터 공유
  • 애플리케이션 시작 시 생성 종료 시 소멸
  • 전역에 필요한 설정 정보, 공용 데이터 저장

* 참고로 session은 클라이언트마다 1개씩 가지고 있는 개별 저장소라 부담이 제일 크기 때문에 최소한의 data만 저장하는게 좋다고 합니다.

 

* 우리가 Controller에서 요청에 대한 처리 결과를 모델에 담아서 보내잖아요? 기본적으로 request scope에 저장됩니다. HTTP 요청 내에서의 범위이니까요!

 

* 4개의 저장소들은 map의 형태로 키와 값으로 이루어져 있습니다. 

 

어 근데 param은 뭔가 싶지 않나요? param은 요청 파라미터를 읽는 객체 입니다. 예를 들어 /jsp?name=A&age=20 이렇게 URL로 GET요청을 보낸다고 치면 요청 파라미터인 name과 age를 읽을 때 param.name과 param.age로 접근할 수 있는거죠. (POST 요청으로 본문에 포함된 파라미터 포함)

'Jsp' 카테고리의 다른 글

include를 제대로 알지 못하고 사용한 사람의 최후..  (0) 2024.05.22