본문 바로가기
아카이브/스프링

스프링의 정석 (서블릿과 JSP)

by nineteen 2021. 12. 24.
반응형

배운 것

서블릿

JSP

EL

JSTL

Filter

 

 

내용 정리

 

서블릿

    - @WebServlet 애너테이션 사용

    - 메소드단위로 매핑이 안 됨, 클래스 단위로만 매핑이 됨 / 스프링은 메소드에 매핑

    -> 스프링보다 클래스를 많이 만들어야 하는 단점

   

 

서블릿과 JSP는 거의 같음

스프링은 서블릿을 발전시킨 것, 서블릿을 이용하기도 함

 

서블릿은 기본적으로 3개 메소드를 가지고 있음

init(), service(), destroy()

Servlet Container가 자동으로 호출하므로, 우리는 메소드의 내용만 적어주면 된다

 

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
	
	@Override
	public void init() throws ServletException {
		// 서블릿의 초기화를 자동 호출하는 메소드, 처음에 한번만 실행
		// 1. 서블릿의 초기화 작업 담당
		System.out.println("[HelloServlet] init() is called" );
	}
	
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 1. 입력
		// 2. 처리
		// 3. 출력
		System.out.println("[HelloServlet] service() is called" );
		System.out.println("2");
	}

	@Override
	public void destroy() {
		// 3. 뒷정리 - 프로그램이 변경되거나 서블릿이 메모리에서 제거될 때 서블릿 컨테이너에 의해서 자동호출
		System.out.println("[HelloServlet] destroy() is called" );
		
	}
}

 

서블릿은 사용자 요청이 오면, 서블릿 인스턴스가 존재하는지 확인한다

서블릿 인스턴스가 없다? -> 인스턴스를 생성 init() -> service() 호출

서블릿 인스턴스가 있다? -> 바로 service()호출

 

서블릿은 늦은 초기화 - 요청이 올 때 객체를 만들고 초기화

스프링은 빠른 초기화 - 요청이 오지 않아도 미리 객체를 만들어 놓고 초기화

 

 

 

 

JSP

    - HTML안에 자바코드가 있는 것

    - JSP페이지는 자동으로 매핑됨

    - JSP페이지 호출만 하면 됨

    - JSP로 작성하면 컴파일 시, 자동으로 서블릿으로 변환 됨

 

ㅇ <%! ~ %>

  - 클래스 영역

  - 클래스 변수, 인스턴스 변수

ㅇ <% ~ %>

  - 메소드 영역, service() 메소드 내부

  - 지역 변수

ㅇ <%=값%>

  - 값 출력 시 사용

<%@ page contentType="text/html;charset=utf-8"%>
<%@ page import="java.util.Random" %>
<%-- <%! 클래스 영역 %> --%>
<%!  
	int getRandomInt(int range){
		return new Random().nextInt(range)+1;
	}
%>
<%-- <%  메서드 영역 - service()의 내부 %> --%>
<%
	int idx1 = getRandomInt(6);
	int idx2 = getRandomInt(6);
%>
<html>
<head>
	<title>twoDice.jsp</title>
</head>
<body>                       <!-- 값 출력 시, 사용 -->
	<img src='resources/img/dice<%=idx1%>.jpg'>
	<img src='resources/img/dice<%=idx2%>.jpg'>
</body>
</html>

 

 

JSP 기본 객체 (지역변수임)

    - 인스턴스 생성없이 사용할 수 있는 객체

    - service()에 지역변수로 선언되어 있음

    - request, response, session ...

 

 

객체를 쓰려면 생성후에 사용해야 하지만, 생성없이 사용할 수 있는 객체가 있는데, 그것이 기본 객체 (지역변수임)

 

 

 

JSP 유효범위(scope)와 속성(attribute)

    - HTTP가 상태정보를 저장하지 않기 때문에(stateless) 저장소가 필요

    - 접근 범위, 생존 기간에 따라 4가지로 분류

    - 저장소는 Map형태, 원하는 데이터를 저장

 

pageContext

  - 지역변수(lv)저장, 기본객체

  - 같은 페이지 안에서만 접근 가능 (읽기, 쓰기)

  - EL때문에 사용 ${}

    - EL은 저장소에 저장 후 사용 가능하기 때문, 지역변수 사용이 불가

    - 저장소에 저장 후, 읽어와서 사용하는 방식

  - 다른 페이지에서는 접근 불가

 

application

  - WebApp전체에서 접근 가능한 저장소 (1개만 존재)

  - 공통 저장소

  - 개별적인 데이터를 저장하는데 적합하지 않음

 

session

  - 개별 저장소

  - 클리아언트마다 1개

  - 로그인하면 개별저장소 생성, 로그아웃하면 제거 개념

  - 로그인 정보, 장바구니 등, 사용자만 사용할 수 있는 개별정보

  - 서버부담이 가장 큼 (메모리 부담)

    - 사용자마다 1개씩 갖는 개별저장소

    - 최소한의 데이터만 저장해야 함

  - 여러 페이지에서 접근 가능

 

request

  - 요청마다 생성, 서로 독리적

  - 가능하면 서버부담이 가장 적은 request사용을 권장 (다른 페이지에 데이터 전달 시)

 

  forward

    - 요청받음 -> 보인이 응답할 수 없음 -> 다른 JSP에 request객체를 넘겨줌

 

 

기본 객체 유효 범위 설명
pageContext 1개 JSP페이지 JSP페이지의 시작부터 끝까지. 해당 JSP내부에서만 접근 가능, 페이지당 1개
request 1+개 JSP페이지 요청의 시작부터응답까지. 다른 JSP로 전달(forward)가능, 요청마다 1개
session N개 JSP페이지 session의 시작부터 종료까지(로그인~로그아웃) 클라이언트마다 1개
application context 전체 Web App의 시작부터 종료까지. context내부 어디서나 접근가능, 모든 클라이언트가 공유. context마다 1개

 

 

 

웹 프로그래밍

    - 페이지들 간의 이동과 데이터 전달

 

 

 

EL (Expression Language)

    - <%=값%>  -->  ${값}

    - 간단, 편리하게 자바코드를 작성하기 위함

    - 지역변수 사용 불가 -> 저장소 필요(pageContext)

    - 불, 정수, 실수, 문자열, 널을 다룸

 

연산자 종류 연산자 설명
산술 연산자 + 덧셈
- 뺄셈
* 곱셈
/ 또는 div 나눗셈
% 또는 mod 나머지
비교 연산자 == 또는 eq 두 값이 같은지 비교
!= 또는 ne 두 값이 다른지 비교
< 또는 lt 값이 다른 값보다 작은지 비교
> 또는 gt 값이 다른 값보다 큰지 비교
<= 또는 le 값이 다른 값보다 작거나 같은지 비교
>= 또는 ge 값이 다른 값보다 크거나 같은지 비교
논리 연산자 && 또는 and 논리곱 연산
|| 또는 or 논리합 연산
! 또는 not 부정 연산
empty 연산자 empty <값> <값>이 null이거나 빈 문자열이면 true를 반환
조건 연산자 <수식> ? <값1> : <값2> <수식>의 결괏값이 true면 <값1>을 반환, false면 <값2>반환

 

 

<%@ 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" %>
<%@ page import="com.fastcampus.exercise.*" %>
<%
	// 지역변수, EL은 지역변수 사용 불가 -> 저장소에 저장 후 사용
	Person person = new Person();
	request.setAttribute("person", person);
	request.setAttribute("name", "사카");   
	request.setAttribute("list", new java.util.ArrayList());	
%>
<html>  
<head>   
	<title>EL</title>   
</head>  
<body>   
person.getCar().getColor()=<%=person.getCar().getColor() %> <br>
person.getCar().getColor()=${person.getCar().getColor()} <br>
person.getCar().getColor()=${person.car.color} <br>

<!-- request는 지역변수이기 때문에 EL에서 사용 불가, 따라서 request의 저장소인 requestScope사용 -->
name=<%=request.getAttribute("name") %> <br>
name=${requestScope.name} <br>
name=${name} <br>

id=<%=request.getParameter("id") %> <br>
<!-- request는 지역변수이기 때문에 EL에서 사용 불가, pageContext저장소에서 request를 참조하는 식으로 사용 -->
id=${pageContext.request.getParameter("id")} <br>
id=${param.id} <br>

<!-- 문자열 + 숫자 -->
"1" + 1 = ${"1"+1} <br> 			<!-- 숫자 -->
"1" += 1 = ${"1"+=1} <br>			<!-- 문자열 -->
"2" > 1 = ${"2">1} <br>
null = ${null} <br>
null+1 = ${null+1} <br>
null+null = ${null+null} <br>
"" + null = ${""+null} <br>
"" -1 = ${""-1} <br>
empty null = ${empty null} <br>		<!-- 비어있으면 true -->
empty list = ${empty list} <br>
null == 0 = ${null==0} <br>
null eq 0 = ${null eq 0} <br>
name == "사카" = ${name=="사카"} <br>
name eq "사카" = ${name eq "사카" } <br>
name != "사카" = ${name != "사카"} <br>
name ne "사카" = ${name ne "사카"} <br>
name.equals("사카") = ${name.equals("사카")} <br>
</body>
</html>

 

 

 

 

JSTL ( JSP Standard Tag Library )

    - 접두사 활용, tablib에 정의되어 있으면 해당 라이브러리의 태그 사용가능

    - 태그 ex) <c:set>, <c:if>등

    - 변수 선언, 조건식, 반복문등 기능을 자바 코드로 구현하던 것을 태그로 대체하기 위함

 

기능 태그 설명
변수 지원 <c:set> JSP페이지에서 변수 지정
<c:remove> 지정된 변수를 제거
흐름 제어 <c:if> 조건문 사용
<c:choose> switch문 사용
<c:when>과 <c:otherwise>서브 태그가짐
<c:forEach> 반복문 사용
<c:forTokens> 구분자로 분리된 각각의 토큰을 처리할 때 사용
URL 처리 <c:import> URL을 이용해 다른 자원을 JSP페이지에 추가
<c:redirect> response.sendRedirect() 기능 수행
<c:url> 요청 매개변수로부터 URL생성
기타 태그 <c:catch> 예외 처리에 사용
<c:out> JspWriter에 내용을 처리한 후 출력

 

 

EL과 JSTL은 기존의 JSP에서 자바코드를 편리하게 하기위해 등장!

<%=값%>  -->  EL    ${값}

<% ~ %>   -->  JSTL <c:set>, <c:if>등등

 

<%@ 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>
<!-- 저장소에 저장한 것, scope="page"가 생략, EL이 지역변수를 사용못하기 때문에 저장소에 저장 -->
<c:set var="to" value="10"/>			<!-- 변수 선언/초기화 -->
${to} <br>
<!-- 배열 선언/초기화 -->
<c:set var="arr" value="10,20,30,40,50,60,70"/>		
${arr} <br>		
<c:forEach var="i" begin="1" end="${to}">	<!-- 반복문 -->
	${i}
</c:forEach>
<br>

<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>
<br>
<c:if test="${param.msg!=null}">		<!-- 요청으로 msg값이 있다면 출력 -->
	msg=${param.msg}
	msg=<c:out value="${param.msg}"/>	<!-- 매개변수로 태그가 들어와도 해석x -->
</c:if>
<br>
<c:if test="${param.msg==null}">메세지가 없습니다.<br></c:if>
<c:set var="age" value="${param.age}"/>		<!-- 요청으로 들어온 age값을 변수age에 저장 -->
<c:choose>									<!-- if-else문 -->
	<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>

 

참고

https://atoz-develop.tistory.com/entry/JSP-JSTL-%EC%82%AC%EC%9A%A9-%EB%B0%A9%EB%B2%95-%EC%A3%BC%EC%9A%94-%ED%83%9C%EA%B7%B8-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC

 

[JSP] JSTL 사용 방법 - 주요 태그 문법 정리

JSTL을 사용하려면 라이브러리가 필요하다. 라이브러리 다운로드 및 프로젝트 세팅은 이 포스트를 참고한다. 태그 라이브러리 선언 자바에서 import문을 선언하듯 JSP에서도 JSTL 확장 태그를 사용

atoz-develop.tistory.com

 

https://usefultoknow.tistory.com/entry/JSTLJSP-Standard-Tag-Library%EC%9D%B4%EB%9E%80

 

JSTL(JSP Standard Tag Library)이란?

JSTL이란? JSP는 자신만의 태그를 추가할 수 있는 기능을 제공하고 있습니다. 나 과 같은 커스텀 태그처럼 연산이나 조건문이나 반복문인 if문, for문, DB를 편하게 처리할 수 있는것이 JSTL입니다. 즉

usefultoknow.tistory.com

 

 

 

Filter

    - 서블릿 전처리

    - 공통적인 요청 전처리와 응답 후처리에 사용

    - 전처리, 후처리 부분을 Filter로 빼버림

 

// 필터를 적용할 요청의 패턴 지정 - 모든 요청에 필터를 적용.
@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. 후처리 작업
		HttpServletRequest req = (HttpServletRequest)request;
		String referer = req.getHeader("referer");
		String method = req.getMethod();
		System.out.print("["+referer+"] -> "+ method + "["+req.getRequestURI()+"]");
		System.out.println(" 소요시간="+(System.currentTimeMillis()-startTime)+"ms");
	}

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

'1. 전처리 작업', '3. 후처리 작업'만 필터에 넣어주면 된다

'2. 서블릿 또는 다음 필터를 호출'부분은 고정

 

 

 

느낀 점 / 보완할 점

우선은 익숙하지 않아서 낯설고, EL과 JSTL이 헷갈린다.

EL과 JSTL을 직접 써보며 익숙해져야겠다.