Web/Spring

[Spring] Ch02.Spring MVC (13) 서블릿과 JSP(1) ~(16) 서블릿과 JSP(4)

OptimizerStart 2025. 6. 1. 16:48

[Spring] Ch02.Spring MVC (13) 서블릿과 JSP(1) ~(16) 서블릿과 JSP(4)

 

서블릿, JSP, Spring관계

  • JSP ≒ 서블릿
  • Spring = 서블릿 발전시킨 것. early-init
    • 서블릿을 이용해 동작한다.

@WebServlet

  • @Controller + @RequestMapping

조건

  1. HttpServlet 상속
  2. service() (= main()) - 오버라이딩
  3. 메서드 매개변수 2개 - HttpServlet Request, HttpServletResponse

@Controller가 개선한 것.

  1. 상속 안해도 됨 (단일 상속 고려)
  2. 필요한 매개변수만 정의
  3. url 매핑 시 메서드 단위 (클래스 정의 안해도 됨)

서블릿 메서드 -3

  1. init() 서블릿 생성 시 서블릿 초기화
    • 1번만 호출됨.
  2. service() 실제 작업 처리
    • 요청이 올 때마다 반복적으로 호출
  3. destroy() 뒷정리 - 서블릿이 메모리에서 제거될 때, 서블릿 컨테이너에 의해서 자동 호출
    • 서블릿 리로딩 (갱신)
    • 웹 애플리케이션 종료될 때

서블릿 메서드 호출 과정 - 프로그램 변경 시 reload

 

특징

  • Servlet Container가 자동 호출함.
  • 코드 작성만 하면 됨
  • 동일 url 호출 2번이상일 때는 init() 호출 X

 

서블릿 생명주기

서블릿의 생명주기 출처: 남궁성 Spring의 정석

Servlet Context

서블릿 컨테이너

  • 서블릿을 미리 만들어 map에 저장해 사용 - Flyweight 패턴 자주 변경되지 않는 것을 재사용함.
  • 서블릿 - Singleton 패턴 1개 인스턴스만 만들고 재사용

구성 요소

  • children (iv) - map 형태 <서블릿 이름, 서블릿>
    • 서블릿 인스턴스 존재 여부를 map을 참조

Servlet vs JSP 차이점

Servlet Java 안에 html이 들어오는 것

  • Servlet은 java 5% html 95% → 95% print문으로 html 출력해야해서 에러 발생률 높음 = jsp 만든이유
  • 싱글톤
    • lazy-init 늦은 초기화 , 지연된 초기화 (Servlet)
      • 요청이 올 때 객체를 만들고 초기화
      • 미리 초기화하는 방법도 제공하긴함.
    cf. early-init Spring. 미리 객체를 만들고 초기화

JSP html안에 Java 코드<% %>가 있는 것

  • service() 메서드 내부로 들어감
    • <html> 부분이 Servlet의 out.println()으로 자동으로 바뀜
    • <%%> Java 코드는 단순 코드✅로 들어감
  • @WebServlet 매핑을 안해도 자동으로 매핑됨

 

JSP Java Server Pages

  • 자동으로 서블릿으로 변환됨

표현

  • <% %> 지역변수 lv, service() 메서드 내부로 들어감
  • <%! %> 인스턴스 변수 iv, 클래스 변수 cv 선언, 클래스 내부로 들어감
  • 태그 안 붙은 코드 : service ()메서드 내부로 들어감

JSP 페이지 위치 : src/main/webapp/WEB-INF 내부 혹은 밖

 

JSP 호출과정

 

  1. 확장자가 *.jsp 파일은 JSP Servlet이 모두 요청을 받음.
  2. 서블릿 인스턴스가 존재하지 않음 - 시간 지연 존재
    1. *.jsp 파일이 첫번째로 호출
    2. _jsp.java로 변환되어 서블릿 소스파일 생성 _jsp.java
    3. 컴파일 후 서블릿 클래스 파일(_jsp.class) 생성
    4. init() 으로 인스턴스 생성(초기화)
  3. 존재하는 서블릿 인스턴스가 _jspService() 호출 하면서 응답 - 두번쨰 호출

장점

  • 인스턴스 존재하면 다시 생성하지 않아 변환과 컴파일 거치지 않아 속도 빠름.

주의 사항

  • jsp 파일이 변경되면 변환과 컴파일 과정을 다시 해 객체 생성
    • class 파일 수정 시각 (미래) > jsp 파일 (과거)

 

기본 객체

  • 정의 : 생성 없이 사용할 수 있는 객체
  • service() 메서드 지역변수 lv 이기 때문
    • jsp가 servlet으로 변환될 때 service() 메서드 내부로 들어감.

ex. request, response, pageContext, application, config, out, page

 

기본객체 종류 출처: 남궁성 Spring의 정석 교안

 


HTTP 특징

  • Stateless상태 정보 저장 X = 누가 요청했는지 기록 X → 저장소 -4 필요
  • cf. Stateful 상태 정보 저장 O

 

유효범위(scope)과 속성 (attribute)

 

속성

  • attribute. 저장소의 Key값. Map 저장구조
“person” 0x100
“name” “남궁성”

 

유효 범위

  • 저장소 구조 map <속성명, 속성값>
    • lv (기본 객체 포함, request, response 등 ) 저장
  • 저장소 마다 map이 존재

필요성

  • http가 stateless 이기 때문에 요청 기록을 저장할 저장소 필요

특징

  • scope 객체저장소는 서버 메모리에만 머무는 값이고 브라우저에는 전송되지 않음

저장소 분류 기준 -4

  1. 접근 범위
  2. 생존 기간

 

map 형태 객체 저장소 종류 -4

1. pageContext 객체 저장소2

  • 접근 범위 : 하나의 jsp 페이지 내에서만 lv에 접근(R, W) 가능
  • 같은 페이지 임에도 저장소에 lv 저장하는 이유 ⇒ EL 사용하려고
    • <%= lv %>   OK.
    • ${ lv }    X - EL은 lv에 직접 접근 불가.
  • 요청할 때마다 초기화 됨.

2. application 객체 저장소. 공통 저장소

  • 접근 범위 : Web Application 전체에서 접근가능 저장소 1개만 존재
  • 활용 : 로그인 후 같은 클라이언트 구별 X , 프로그램 전체에서 사용하는 데이터
  • 주의사항
    • 개별적인 Key의 Value 저장 부적합. Map은 동일한 Key에 value를 덮어씀

3. session 객체 저장소. 클라이언트 개별 저장소

  • 접근 범위 : 클라이언트(사용자) 마다 1개씩 존재
  • 쿠키를 이용해서 세션 객체가 누구의 것인지 구별
  • 활용 : 로그인, 장바구니, 사용자만 가질 수 있는 정보
    • 로그인 시 개별 저장소 생성. 로그아웃 시 개별 저장소 제거
  • 문제점 :
    • 세션 객체 수 = 사용자 수 이므로 최소한의 데이터만 저장, 서버 메모리 부담이 가장 큼
    • 사용하더라도 잠깐 사용 후 삭제

session 객체 저장소 출처: 남궁성 Spring의 정석

4. request 객체 저장소 ⭕ 사용 추천

  • 접근 범위 : 여러 jsp 페이지
  • 생존 기간 : 서버-측 요청 처리(필터 체인) 흐름이 끝났는가
    • ① 첫 필터/서블릿에 들어올 때 →
    • ② 모든 필터·컨트롤러·JSP를 통과 →
    • ③ 마지막 필터를 벗어날 때 까지가 request 객체의 “생존 구간” 응답과 상관없이
    • 동기 범위: service() 또는 doFilter() 내에서만 request 객체가 유효
    • 비동기 범위: startAsync() → complete() 사이에만 유효
    • [참고] Lifecycle of Request Object - JAVA Servlet Specification p52
  • 기본 객체
  • 요청할 때마다 생기고 요청끼리 독립적
    • redirect도 하나의 요청으로forward와
  • forward 1개 요청을 다른 jsp 페이지가 처리하도록 넘겨주는 기능.
    • request 객체 접근 (R,W)가능
      • 객체에 저장된 iv R,W
    • redirect, forward에 따른 request 생존
      •  return "forward:/..." => 같은 객체 사용
      요청A 에 매핑된 메서드가 return forward:/home  (url) 일 때,  /home에 매핑된 메서드B에서 A메서드의 request 객체 그대로 사용가능model도 B메서드에서 사용가능
      • return "redirect:/..." => 다른 객체임
        수업 자료에서도 redirect는 요청 2번(수동 요청, 자동요청)이라서 forward 와 달리 두번째 요청에서는 request 객체가 첫번째 요청된 request 객체와 같지 않음model도 첫번째 요청, 두번째 요청마다 다른 model 객체를 갖는다.
    컨트롤러 반환값 실제 동작 request 공유 범위
    "login" InternalResourceView → dispatcher.forward(req,res) 으로 /WEB-INF/views/login.jsp 컨트롤러 ↔ login.jsp ↔ (login.jsp가 include한 JSP)
    "forward:/step2" 컨트롤러A → 다른 컨트롤러B 실행 → B가 또 "result" 뷰 반환 → result.jsp 컨트롤러A ↔ 컨트롤러B ↔ result.jsp (모두 동일 req)
  • requestScopemap 객체명

활용

  • 여러 JSP 파일 간 데이터 주고 받기. 다른 페이지에 데이터 전달
    request 객체 활용 - 서로 다른 jsp 파일 데이터 주고 받기

Map 데이터 접근 메서드

  • 쓰기 setAttribute()
  • 읽기 getAtrribute()

 

 

model 과 유효범위 (객체 저장소)

model =/= Scope

  • jsp EL 이 읽는 네가지 범위에 해당되지 않음

Model은 컨트롤러 내부에 임시로 존재하는 Map 자료구조

  • 뷰 렌더링 적에 DS가 Model 안에 저장된 내용을 HTTPServeltRequest의 attribute로 복사
  • model의 내용은 요청-응답은 재요청 될때마다 초기화됨

주의사항

  • request 스코프 안에 잠시 존재하는 객체 x

 

model 객체가 view에서 쓸 수 없는 이유

view 렌더링

  • 컨트롤러의 Model 객체는 view로 전달될 때 request 객체로 변환되어 jsp(view)에 전달됨.
  • 그래서 jsp에서 model 객체에서 값을 꺼내서 쓸수 없고 request 객체로 값을 꺼내 쓸 수 있음.

spring framework view redering Spring 공식문서

https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html

 

17. Web MVC framework

@RequestMapping(method = RequestMethod.POST) public String processSubmit(@ModelAttribute("pet") Pet pet, Model model, BindingResult result) { … } Note, that there is a Model parameter in between Pet and BindingResult. To get this working you have to reor

docs.spring.io

 

 

URL 패턴

특징

  • 배열 처럼 여러개 등록 가능참고. 
    @WebServlet(urlPatterns={”/hello”, “/hello/*} , loadOnStartup=1) 
  • loadOnStartup
    • 서블릿 호출 전에 미리 만듦 (↔ lazy-init),
    • 번호는 미리 초기화 하는 서블릿 중에 우선순위. 중복 가능.

종류 -4 (우선 순위 순)

  1. exact mapping /login/hello.do
    • 정확히 일치하는 것
  2. path mapping /login/*
  • 패턴의 경로로 들어오면 패턴이 등록된 서블릿 처리
  1. extension mapping *.do
    • 확장자
  2. default mapping /
    • 모든 주소와 매핑
    • 앞 3개가 안되면 매핑

[ Spring ] @RequestMapping URL 매핑

  • URL 패턴 존재

url과 메서드 연결

 

 

Servlet Context 구성

  1. children (서블릿) - Map
    • 서블릿의 이름으로 서블릿 주소 찾음
  2. sevletMapping - Map
    1. URL 패턴 저장 위치
    2. 호출할 서블릿 (프로그램)이름 찾음

[Spinrg ] 일치하는 서블릿 없으면 Dispatcher Servlet이 호출됨 @RequestMapping 동작 원리

  • url 패턴과 서블릿 연결한 map이 없음 servletMapping (x)
  • Dispatcher Servlet이 자체적인 url패턴 과 서블릿 연결한 테이블 갖고있음
  • 모든 url은 Dispatcher Servlet을 호출

Dispatcher Servlet이 기존 전체 설정을 덮어서 새로 쓰고 있음

개별 설정
전체 설정

 

 

 

EL Expression Language

목적

  • <%= 값> 없애기 위해 EL ${값} 
  • 짧게 하려고

장점

  • 간단, 편리

특징

  • 문자열 연산 같다.== eq , 같지 않다. != ne

주의사항

  • 산술/비교 연산시 문자가 숫자됨. : “1” + 1 → 1 + 1
  • 문자열 결합 +=
  • null 출력 시 아무것도 출력 안됨.
  • null 산술연산 시 0으로 처리

empty

  1. null
  2. 빈(empty) 컬렉션, 배열

 

테그 종류

  • <% … %> (스크립틀릿 태그)
    • JSP의 _jspService() 메서드 안에 Java 코드를 삽입만. 이 안에 쓴 코드는 실행되지만, 자동으로 HTML에 출력되지는 않음
  • <%= … %> (익스프레션 태그)
    • 세미콜론 끝에 붙이지 않음.
    • 안의 표현식을 평가한 뒤 out.print(…) 호출로 결과 문자열을 HTML에 삽입
  • <%%> 에 들어가는 값은 lv 지역변수.(${})에서 값을 쓰고 싶다면? → 반드시 setAttribute()를 통해 scope에 저장되어 있어야 함Run > Run Configure > -Dwtp.deploy 에 연결된 deploy 경로

 

EL 변환된 파일 보는 위치

  • Run > Run Configure > -Dwtp.deploy 에 연결된 deploy 경로
D:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\ch2\org\apache\jsp

 

 

내장 객체

  • parm http 요청 정보(body) 꺼내는 객체
  • reqeust.getParamerer() 동일
  • GET/POST 쿼리 스트링 및 <form> 파라미터= 값 자동 파싱

종류

  • header http 요청 header 정보 접근 객체
  • cookie
    • ${cookie.쿠키이름.value} 쿠키에 저장된 값을 가져옴

*.jsp 파일을 변경해도 수정사항이 반영되지 않는 경우

방법 1 ) _jsp.class, _jsp.java 파일들 삭제

el_jsp.class 컴파일된 파일

 

구성 파일

  • el_jsp.class 컴파일된 파일
  • el_jsp.java 서블릿 소스파일

방법 2) Servers 탭 우클릭 > Clean Tomcat Work Directory

  • 자동으로 _jsp.java (서블릿으로 변환된 파일)과 _jsp.class 컴파일된 파일들 삭제됨

 

삭제된 결과

 

 

JSTL JSP Standard Tag Library

 

목적

  • <%%> 자바 코드 없이기 위해
  • 블록 구성 없애기

<%= 값> 없애기 위해 EL ${}

<c:set > < c:if> 등 태그가 정의된 라이브러리.

 

태그 종류

  • c jstl core library
  • fmt 형식화 라이브러리 사용

<c:if > </c:if> if문

<c:forEach> </c:forEach> for문

<c: choosen> if-else -if문

<c:when> </c:when>

<c:when> </c:when>

</c: choosen>

 

status

  • count, index

<c:out> 태그 해석 안하고 출력. <p> asdf </p>

  • 스크립트 공격 예방

사용 이유

  • jsp 에서 <%%> 중에 html이 있으면 <%%> 코드가 쪼개지기 때문에 실수 발생. 태그화 진행

원리

  • 태그에 변수명, 값, scope (저장소) 작성 (var= “변수명”, value=’값)
  • 지정된 scope(저장소)의 map에 key, value 형태로 저장

filter

서블릿의 전처리, 후처리의 중복 코드를 분리할 때 사용

  • 서블릿의 전처리와 후처리의 코드가 서블릿 마다 중복될 때, 한번만 전처리 후처리 코드 정의하고 그 사이에 서블릿 호출을 하는 식으로 코드 중복 제거
  • 전처리 서블릿 호출 전 하는 작업
  • 후처리 서블릿 호출 후 하는 작업

사용법

@WebFilter(urlPatterns=”패턴”) 필터 등록 애너테이션. urlPattern에 필터로 적용할 요청을 지정

특징

  • 전처리, 후처리 중 하나만 있어도 됨.
  • 필터 지정후 처음 호출 시 필터 객체 생성에 시간 소요됨.

활용

  • 로깅
  • 인코딩

[ 유사 ] AOP

 

필터 원리 및 실행 흐름 출처: 남궁성 Spring의 정석

특징

  • 필터 여러 개 가능

 

 

참고자료

  • Spring 공식 문서 
  • 남궁성의 Spring의 정석