본문 바로가기

백엔드 개발/SpringMVC

JSP와 서블릿(4)

1. JSTL 

(1) JSTL 이란? 

JSP Standard Tag Library 

JSP에서 자바 코드 문을 태그 형태로 표현 한 것

(2) 필요한 이유? 

JSTL 안 쓰고 JSP에서 자바 코드 문 쓰는 기본 문법으로 쓸 경우 위와 같이 코드 문이랑, EL 문이랑, 그냥 문자열이랑 다 따로 나눠서 써야한다. 너무 복잡하다. 

그래서 HTML 문 답게 자바코드든 EL이든 다 태그문법으로 쓸 수 있게 바꾼 것이다. 

(3) 코드 리뷰

<%@ page contentType="text/html;charset=utf-8"%>

<!-- c 접두사 -> jstl의 core library를 쓰겠다. core library는 태그 라이브러리
	접두사 fmt은 형식화 출력을 사용하겠다. -->
<%@ taglib prefix="c"   uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>


<html>
<head>
	<title>JSTL</title>
</head>
<body>
<!--선언 및 초기화 구문 to에 10을 대입-->
<c:set var="to"   value="10"/>

<!--이건 배열 선언 및 초기화 구문-->
<c:set var="arr"  value="10,20,30,40,50,60,70"/> 

<!--for Each 문-->
<c:forEach var="i" begin="1" end="${to}">
	${i}
</c:forEach>
<br>
<!--if 문 test는 ~라면의 뜻  
		배열이 비어있지 않다면~-->
<c:if test="${not empty arr}">
	<c:forEach var="elem" items="${arr}" varStatus="status">
		${status.count}. arr[${status.index}]=${elem}<BR>
	</c:forEach>
</c:if>	
<!--msg로 들어오는 값이 null이 아니라면-->
<c:if test="${param.msg != null}">
	msg=${param.msg} 
<!--c:out은 value의 내용에 태그도 그냥 있는 그대로 전부 출력하라는 뜻-->    
	msg=<c:out value="${param.msg}"/>
</c:if>
<br>
<c:if test="${param.msg == null}">메시지가 없습니다.<br></c:if>
<c:set var="age" value="${param.age}"/>
<c:choose>
	<c:when test="${age >= 19}">성인입니다.</c:when>
	<c:when test="${0 <= age && age < 19}">성인이 아닙니다.</c:when>
	<c:otherwise>값이 유효하지 않습니다.</c:otherwise>
</c:choose>
<br>
<c:set var="now" value="<%=new java.util.Date() %>"/>
Server time is <fmt:formatDate value="${now}" type="both" pattern="yyyy/MM/dd HH:mm:ss"/>	
</body>
</html>

(4) 스스로 써보기 

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

<html>
<head>
<title> JSTL</title>
</head>
<body>
<c:set var="to" 	value="10"/>
<c:set var="arr" 	value="10,20,30,40,50,60,70" />
<c:forEach var="i" begin="1" end="${to}">
	${i}
</c:forEach>
<br>

<c:if test="${param.msg != null }">
	msg=${param.msg }
	msg=<c:out value="${param.msg }"></c:out>
</c:if>
<br>
<c:if test="${param.msg == null}"> 메세지가 없습니다. <br> </c:if>
<c:set var="age" value ="${param.age }"/>
<c:choose>
	<c:when test="${age > = 19}"> 성인입니다.</c:when>
	<c:when test="${0 <= age && age < 19 }"> 성인이 아닙니다. </c:when>
	<c:otherwise>값이 유효하지 않습니다. </c:otherwise>	
</c:choose>
<br>
<c:set var = "now" value = "<%=new java.util.Date() %>"/>
Server time is <fmt:formatDate value = "${now}" type="both" pattern = "yyyy/MM/dd HH:mm:ss"/>

</body>
</html>

2. Filter에 대해 

(1) Filter의 존재 이유 

객체지향 설게의 5대 원칙 중 첫번째 관심사 분리 

분리의 3가지 종류 중 마지막 

공통(중복) 코드 분리를 해주기 위해서이다. 

(2) Filter가 낀 서블릿의 작동구조 

모든 servlet이 공통적으로 전처리, 후처리를 갖는다. 이들이 하는 역할은 같다. 따라서 전처리, 후처리를 해줄 Filter를 따로 만들어서 뽑아낸다. 

Filter는 전처리 후 해당 요청을 처리할 수있는 서블릿을 호출하여 정보를 처리한다 그 후 다시 후처리를 하고 클라이언트에게 응답한다.

전처리 후처리는

inint() 초기화 작업, destroy() 정리 작업과 다른 것이다. 

전,후처리는 처리 작업 중 해야하는 앞과 뒤의 루틴이다.

(3) 이중 Filter인 경우

순서는 F1의 전처리 -> F1의 다음 필터 호출 -> F2의 전처리 -> 정보처리할 서블릿 호출 -> 다시 F2로 돌아와 F2가 후처리 > F1으로 돌아와 F2가 후처리 후 클라이언트에게 응답. 

(4) 코드 리뷰 

// 전처리 후처리 하는 일 -> 처리 작업이 걸리는 속도 체크 
// 전처리 때 시작 시간을 체크하고 후처리에서 끝난 시간 - 시작 시간 해서 얼마나 걸렸는지 체크 

package com.fastcampus.ch2;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

// 필터를 적용할 요청의 URL 지정 - 모든 요청에 대해 이 필터를 적용.
@WebFilter(urlPatterns="/*")
public class PerformanceFilter implements Filter {
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// 초기화 작업
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// 1. 전처리 작업
        // 전처리 후처리는 선택사항이라 둘 다 없어도 되고 하나만 있어도 됨.
		long startTime = System.currentTimeMillis();

		// 2. 서블릿 또는 다음 필터를 호출 (고정)
		chain.doFilter(request, response); 
		
		// 3. 후처리 작업
		System.out.print("["+((HttpServletRequest)request).getRequestURI()+"]");
		System.out.println(" 소요시간="+(System.currentTimeMillis()-startTime)+"ms");
	}

	@Override
	public void destroy() {
		// 정리 작업
	}

}

(5) 스스로 써보기 

package com.fastcampus.ch2;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

// 필터를 적용할 요청의 URL 지정 - 모든 요청에 대해 이 필터를 적용.
@WebFilter(urlPatterns="/*")
public class PerformanceFilter implements Filter {
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// 초기화 작업
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// 1. 전처리 작업
		long startTime = System.currentTimeMillis();
		
		//2. 서블릿 또는 다음 필터 호출
		chain.doFilter(request, response);
		
		//3. 후처리 작업
		System.out.println("["+((HttpServletRequest)request).getRequestURI()+"]");
		System.out.println("소요시간=" + (System.currentTimeMillis()-startTime)+"ms");
	}

	@Override
	public void destroy() {
		// 정리 작업
	}

}