
서블릿, JSP, Spring관계
- JSP ≒ 서블릿
- Spring = 서블릿 발전시킨 것. early-init
- 서블릿을 이용해 동작한다.
@WebServlet
- @Controller + @RequestMapping
조건
- HttpServlet 상속
- service() (= main()) - 오버라이딩
- 메서드 매개변수 2개 - HttpServlet Request, HttpServletResponse
@Controller가 개선한 것.
- 상속 안해도 됨 (단일 상속 고려)
- 필요한 매개변수만 정의
- url 매핑 시 메서드 단위 (클래스 정의 안해도 됨)
서블릿 메서드 -3
- init() 서블릿 생성 시 서블릿 초기화
- 1번만 호출됨.
- service() 실제 작업 처리
- 요청이 올 때마다 반복적으로 호출
- destroy() 뒷정리 - 서블릿이 메모리에서 제거될 때, 서블릿 컨테이너에 의해서 자동 호출
- 서블릿 리로딩 (갱신)
- 웹 애플리케이션 종료될 때

특징
- Servlet Container가 자동 호출함.
- 코드 작성만 하면 됨
- 동일 url 호출 2번이상일 때는 init() 호출 X
서블릿 생명주기

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)
- 요청이 올 때 객체를 만들고 초기화
- 미리 초기화하는 방법도 제공하긴함.
- lazy-init 늦은 초기화 , 지연된 초기화 (Servlet)
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 파일은 JSP Servlet이 모두 요청을 받음.
- 서블릿 인스턴스가 존재하지 않음 - 시간 지연 존재
- *.jsp 파일이 첫번째로 호출
- _jsp.java로 변환되어 서블릿 소스파일 생성 _jsp.java
- 컴파일 후 서블릿 클래스 파일(_jsp.class) 생성
- init() 으로 인스턴스 생성(초기화)
- 존재하는 서블릿 인스턴스가 _jspService() 호출 하면서 응답 - 두번쨰 호출
장점
- 인스턴스 존재하면 다시 생성하지 않아 변환과 컴파일 거치지 않아 속도 빠름.
주의 사항
- jsp 파일이 변경되면 변환과 컴파일 과정을 다시 해 객체 생성
- class 파일 수정 시각 (미래) > jsp 파일 (과거)
기본 객체
- 정의 : 생성 없이 사용할 수 있는 객체
- service() 메서드 지역변수 lv 이기 때문
- jsp가 servlet으로 변환될 때 service() 메서드 내부로 들어감.
ex. request, response, pageContext, application, config, out, page

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

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:/..." => 같은 객체 사용
- return "redirect:/..." => 다른 객체임
수업 자료에서도 redirect는 요청 2번(수동 요청, 자동요청)이라서 forward 와 달리 두번째 요청에서는 request 객체가 첫번째 요청된 request 객체와 같지 않음model도 첫번째 요청, 두번째 요청마다 다른 model 객체를 갖는다.
"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) - request 객체 접근 (R,W)가능
- 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 객체로 값을 꺼내 쓸 수 있음.

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 (우선 순위 순)
- exact mapping /login/hello.do
- 정확히 일치하는 것
- path mapping /login/*
- 패턴의 경로로 들어오면 패턴이 등록된 서블릿 처리
- extension mapping *.do
- 확장자
- default mapping /
- 모든 주소와 매핑
- 앞 3개가 안되면 매핑
[ Spring ] @RequestMapping URL 매핑
- URL 패턴 존재
url과 메서드 연결
Servlet Context 구성
- children (서블릿) - Map
- 서블릿의 이름으로 서블릿 주소 찾음
- sevletMapping - Map
- URL 패턴 저장 위치
- 호출할 서블릿 (프로그램)이름 찾음
[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
- null
- 빈(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.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의 정석