[WEB기본] Servlet & JSP(EL, JSTL)
Servlet
: 서블릿이란 클라이언트가 어떠한 요청을 하면 그에 대한 결과를 다시 전송
1. 동작방식
- 사용자(클라이언트)가 URL을 입력하면 HTTP Request가 Servlet Container로 전송합니다.
- 요청을 전송받은 Servlet Container는 HttpServletRequest, HttpServletResponse 객체를 생성합니다.
- web.xml을 기반으로 사용자가 요청한 URL이 어느 서블릿에 대한 요청인지 찾습니다.
- 해당 서블릿에서 service메소드를 호출한 후 클리아언트의 GET, POST여부에 따라 doGet() 또는 doPost()를 호출합니다.
- doGet() or doPost() 메소드는 동적 페이지를 생성한 후 HttpServletResponse객체에 응답을 보냅니다.
- 응답이 끝나면 HttpServletRequest, HttpServletResponse 두 객체를 소멸시킵니다.
2. Servlet Container(서블릿 컨테이너) 역할
1) 웹서버와의 통신 지원
서블릿 컨테이너는 서블릿과 웹서버가 손쉽게 통신할 수 있게 해줍니다. 일반적으로 우리는 소켓을 만들고 listen,
accept 등을 해야하지만 서블릿 컨테이너는 이러한 기능을 API로 제공하여 복잡한 과정을 생략할 수 있게 해줍니다.
2) 서블릿 생명주기(Life Cycle) 관리
서블릿 컨테이너는 서블릿의 탄생과 죽음을 관리합니다. 서블릿 클래스를 로딩하여 인스턴스화하고,
초기화 메소드를 호출하고, 요청이 들어오면 적절한 서블릿 메소드를 호출합니다.
또한 서블릿이 생명을 다 한 순간에는 적절하게 Garbage Collection(가비지 컬렉션)을 진행하여 편의를 제공합니다.
3) 멀티쓰레드 지원 및 관리
서블릿 컨테이너는 요청이 올 때 마다 새로운 자바 쓰레드를 하나 생성하는데, HTTP 서비스 메소드를
실행하고 나면, 쓰레드는 자동으로 죽게됩니다.
3. 생명주기
init() & @PostConstruct
- 서블릿이 메모리에 로드될 때 한 번 호출
- 코드 수정으로 인해 다시 로드되면 다시 호출
service(): 모든 요청은 service()를 통해서 doXXX()메소드로 이동
- doGet()
- GET 방식으로 data 전송 시 호출
- doPost()
- POST 방식으로 data 전송시 호출
destroy() & @PreDestroy
- 서블릿이 메모리에서 해제되면 호출
- 코드가 수정되면 호출
서블릿 객체는 싱글톤으로 관리
- 고객의 요청이 올 떄 마다 계속 객체를 생선하는 것은 비효율
- 최초 로딩 시점에 서블릿 객체르 미리 만들어두고 재활용
- 모든 고객 요청은 동일한 서블릿 객체 인스턴스에 접근
- 공유 변수 사용 주의
- 서블릿 컨테이너 종료시 함께 종료
레이지로딩(lazy loading)
: 클라이언트가 객체생성을 요청한 후에야 늦게 생성 하는 것을 레이지 로딩이라고 한다.
장점 : 메모리 차지를 덜한다.
단점 : 프리로딩에 비해 느리다.
프리로딩(free loading)
: 사용자의 요청과 무관하게 컨테이너가 구동되는 시점에 XML 설정 파일에 등록된 객체를 생성하는 것을 의미한다
장점 : 레이지로딩에 비해 빠르다.
단점 : 메모리를 차지한다.
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.example.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<load-on-startup> 태그의 값은 Servlet이 시작될 때 로딩될 순서를 나타냅니다. 이 값이 양수이면 Servlet은 서버 시작 시 즉시 로딩됩니다. 값이 음수이거나 생략되면 Lazy 로딩됩니다.
load-on-startup
- 톰캣 컨테이너가 실행되면서 미리 서블릿을 실행.
- 지정한 숫자가 0 보다 크면 톰켓컨테이너가 실행되면서 서블릿이 초기화 된다.
- 지정한 숫자는 우선순위를 의미하며, 작은숫자부터 먼저 초기화 된다.
서블릿 스펙
JSP
: JSP(JavaServer Pages)는 Java 언어를 기반으로 하는 서버 측 웹 프로그래밍 기술입니다. JSP를 사용하면 동적으로 웹 페이지를 생성하고 웹 애플리케이션의 로직을 작성할 수 있습니다. JSP는 HTML 내에 Java 코드를 삽입하여 사용자에게 동적으로 생성된 컨텐츠를 제공할 수 있습니다.
1. 동작원리
웹 브라우저 > 웹 서버 > JSP 컨테이너 > *.jsp >*.java >*.class > 웹 서버 > 웹 브라우저
- 간단하게 설명하자면 클라이언트가 *.jsp에 대한 요청을 웹 서버에 하게 된다.
- 웹 서버는 다시 이 요청을 JSP 컨테이너로 넘긴다.
- JSP 컨테이너는 해당 JSP 페이지를 찾아 서블릿(자바 파일/*.java)으로 변환 시킨다. 자바 파일을 컴파일 한다.
- 자바 파일의 결과가 다시 사용자의 웹 브라우저로 전송되어 클라이언트가 요청한 결과를 받아볼 수 있게 된다.
2. LifeCycle
- Translation(번역):
- JSP 파일(.jsp)은 서블릿 파일(.java)로 번역됩니다.
- JSP 컨테이너는 JSP 파일을 서블릿 파일로 변환합니다. 변환된 서블릿은 Java 컴파일러에 의해 컴파일되어 클래스 파일(.class)로 생성됩니다.
- Compilation(컴파일):
- 번역된 서블릿 파일(.java)은 컴파일되어 클래스 파일(.class)로 변환됩니다.
- 이 단계에서는 Java 컴파일러가 사용되며, 변환된 서블릿은 실행 가능한 Java 코드로 컴파일됩니다.
- Initialization(초기화):
- 생성된 서블릿 클래스는 로딩되고 인스턴스화됩니다.
- 서블릿 객체의 init() 메서드가 호출되어 초기화 작업을 수행합니다. 이 단계에서는 주로 서블릿이 필요로 하는 리소스를 초기화하거나 데이터베이스 연결을 설정하는 등의 작업이 이루어집니다.
- Request Handling(요청 처리):
- 클라이언트로부터 HTTP 요청이 도착하면 JSP 컨테이너는 해당 요청을 처리합니다.
- 요청에 따라 서블릿의 service() 메서드가 호출되고, 이 메서드에서는 클라이언트에게 응답을 생성합니다.
- Destroy(소멸):
- 서블릿의 라이프사이클이 종료될 때(웹 애플리케이션이 종료될 때 또는 서블릿이 언로드될 때) destroy() 메서드가 호출됩니다.
- 이 단계에서는 서블릿이 사용한 리소스를 정리하거나 데이터베이스 연결을 닫는 등의 마무리 작업을 수행합니다.
:
3. JSP옵션
- page: JSP 페이지 속성을 설정합니다.
- language: JSP 페이지에서 사용할 스크립트 언어를 설정합니다. 주로 "java"가 사용됩니다.
- extends: JSP 페이지가 상속할 클래스를 지정합니다.
- import: JSP 페이지에서 사용할 클래스를 지정합니다.
- session: JSP 페이지가 세션을 사용할 지 여부를 설정합니다. (default : true)
- errorPage : JSP 페이지의 오류 페이지를 설정합니다.
- include: 외부 리소스를 포함시킵니다.
- file: 포함시킬 파일의 경로를 지정합니다.
- taglib: 태그 라이브러리를 사용할 때 필요한 정보를 설정합니다.
- uri: 태그 라이브러리의 URI를 지정합니다.
- prefix: 태그 라이브러리의 접두사를 지정합니다.
- contentType: Http Client(웹브라우저)가 받아볼 페이지의 인코딩 방식 (Http 헤더에 기록되어 있음)
- text/html, application/xml, text/plain 등이 일반적으로 사용됩니다.
- pageEncoding: JSP파일(페이지)에 기록된 소스코드 자체의 인코딩 방식
- UTF-8, EUC-KR, ISO-8859-1 등이 자주 사용됩니다.
- buffer: JSP 페이지의 버퍼링을 설정합니다. 웹브라우저에 ?kb씩 전달한다. (default : 8kb)
- none, 8kb, sizekb 등으로 설정할 수 있습니다.
- autoFlush: 버퍼를 자동으로 플러시할 지 여부를 설정합니다. (default : true)
- true 또는 false로 설정합니다.
- isThreadSafe: JSP 페이지가 스레드 안전한지 여부를 설정합니다. (default : true)
- true 또는 false로 설정합니다.
//exception발생 시 에러페이지(error.jsp)로 이동
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" errorPage="/error.jsp"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Header Options Example</title>
</head>
<body>
<%-- JSP 내용 --%>
<h1>Hello, JSP!</h1>
<%-- JSTL 사용 예제 --%>
<c:forEach var="i" begin="1" end="5">
<p>Iteration <%= i %></p>
</c:forEach>
</body>
</html>
3. JSP내장객체
내장 객체반환값 타입설명
내장객체 | 타입 | 설명 |
request | javax.servlet.http.httpServletRequest 또는 javax.servlet.ServletRequest |
웹 브라우저의 요청 정보를 저장하고 있는 객체 |
response | javax.servlet.http.httpServletResponse 또는 javax.servlet.ServletResponse |
웹 브라우저의 요청에 대한 응답 정보를 저장하는 객체 |
out | javax.servlet.jsp.JspWriter | JSP 페이지의 출력할 내용을 가지고 있는 출력 스트림 객체 |
session | javax.servlet.http.HttpSession | 하나의 웹 브라우저 내에서 정보를 유지하기 위한 세션 정보를 저장하고 있는 객체 |
application | javax.servlet.ServletContext | 웹 애플리케이션 Context의 정보를 담고 있는 객체 |
pageContext | javax.servlet.jsp.PageContext | JSP 페이지에 대한 정보를 저장하고 있는 객체 |
page | java.lang.Object | JSP 페이지를 구현한 자바 클래스 객체 |
config | javax.servlet.ServletConfig | JSP 페이지에 대한 설정 정보를 담고 있는 객체 |
exception | java.lang.Throwable | JSP 페이지에서 예외가 발생한 경우 사용하는 객체 |
page 영역
|
request 영역
|
session 영역
|
application 영역
|
EL / JSTL
1. EL태그
기존 JSP와 EL 사용 비교
기존 JSP Code | EL을 이용한 Code |
request.getParameter("name"); | ${param.name} |
request.getAttribute("name"); | ${name} |
Member m = (Member)request.getAttribute("member"); m.getName(); |
${member.name} |
List list = (List)request.getAttribute("list"); list.get(0); |
${list["0"]}, ${list.get(0)} |
EL 내장 객체
내장 객체 | |
param | 파라미터 값을 불러올 때 |
paramValue | 파라미터 값을 배열로 불러올 때 |
pageScope | page영역의 객체를 참조 할 때 |
requestScope | request영역의 객체를 참조 할 때 |
sessionScope | session영역의 객체를 참조 할 때 |
applicationScope | application영역의 객체를 참조 할 때 |
cookie | 쿠키 객체를 참조 할 때 |
initParam | 초기 context 파라미터 조회 |
pageContext | context 객체를 참조 할 때 |
주의
> ${"1" + 1} > 2로 출력
2. JSTL Core Tag (c tag)
: JSTL에는 코어, 포맷팅, 함수, 데이터베이스, XML처리와 같이 다섯개의 라이브러리를 지원
태그이름 | 설명 |
<c:set /> | 변수의 선언 및 제거 |
<c:remove /> | |
<c:out /> | 변수의 출력 |
<c:catch /> | 예외 처리 |
<c:if /> | 조건문 (else는 없다) |
<c:choose /> | Switch문과 비슷 |
<c:when /> | |
<c:otherwise /> | |
<c:forEach /> | 반복문 |
<c:forTokens /> | 구분자로 분할하여 반복문 |
<c:url /> | URL 생성 |
<c:param /> | 파라미터 추가 |
<c:import /> | 페이지 첨부 |
<c:redirect /> | URL 이동 |
1. <c:set /> Tag
- JSP의 setAttribute()와 같은 역할
- <c:set var="변수명"
value="변수에 넣을 값"
property="자바빈 객체 or Map 객체 값을 설정할 프로퍼티 명"
scope="변수 공유 범위" />
2. <c:remove /> Tag
- JSP의 removeAttribute()와 같은 역할
- <c:remove var="변수명"
scope="변수 공유 범위" />
3. <c:out /> Tag
- '<%=...>'와 같다. JSP의 표현식을 대체
- <c:out var="변수명"
default="기본값"
escapeXML="true|false" />
4. <c:catch /> Tag
- Body에서 실행되는 코드의 예외 처리
- <c:catch var="에러메시지가 포함될 변수명" />
5. <c:if /> Tag
- 조건문
- <c:if test="조건 판별식"
var="변수명"
scope="변수 공유 범위" />
6. <c:choose />, <c:when />, <c:otherwise />
- Switch문과 동일, 여러개의 when 태그와 하나의 otherwise 태그를 가진다
- <c:if /> 태그에 else가 없으므로 대체식으로도 많이 사용
- <c:choose>
<c:when test="조건 판별식"> .... </c:when>
<c:when test="조건 판별식"> .... </c:when>
<c:when test="조건 판별식"> .... </c:when>
</c:choose>
7. <c:forEach /> Tag
- 객체 전체에 걸쳐 반복 실행에 사용
- <c:forEach var="현재 아이템의 변수명"
items="반복 데이터가 있는 아이템 Collection 명"
begin="시작 값, 기본값은 0"
end="종료 값"
step="증가 값"
varStatus="반복 상태 값을 지닌 변수" />
※ varStatus는 forEach의 상태를 알 수 있는 값이 들어 있다.
- $(변수.current} : 현재의 인덱스
- $(변수.index} : 0부터의 인덱스
- $(변수.count} : 1부터의 인덱스
- $(변수.first} : 현재 루프가 처음인지 확인
- $(변수.last} : 현재 루프가 마지막인지 확인
- $(변수.begin} : forEach문의 시작 값
- $(변수.end} : forEach문의 끝 값
- $(변수.step} : forEach문의 증가 값
8. <c:forTokens /> Tag
- 문자열을 구분자(delimiter)로 분할
- <c:forTokens var="현재 아이템의 변수 명"
items="반복 데이터가 있는 아이템 Collection 명"
delims="구분자, 여러개 지정 가능"
begin="시작 값, 기본 값은 0"
end="종료 값"
step="증가 값"
varStatus="반복 상태 값을 지닌 변수" />
9. <c:url /> Tag
- URL의 생성
- <c:url var="생성한 URL이 저장될 변수 명"
value="생성할 URL"
scope="변수 공유 범위" />
10. <c:param /> Tag
- 파라미터 추가
- <c:param name="파라미터 명" value="값" />
11. <c:import /> Tag
- 페이지 첨부
- import 태그 내에 param 태그도 사용할 수 있다.
- <c:import url="첨부할 URL" />
12. <c:redirect /> Tag
- sendRedirect()와 동일
- <c:redirect url="이동할 URL" />
- context path를 자동으로 포함시키므로 서버 소스를 수정함에 따른 변화를 자동으로 적응해준다.
<c:out>을 사용하는 이유
> 보안성때문이 크다.
XSS(Cross-site Scripting) 란 ?
-XSS공격은 웹사이트에 스크립트 코드를 주입시키는 방법으로 웹사이트 공격방법 중 기초적인 것에 해당됩니다.
해결 방법은 html코드를 해석하지 않게 만들면 간단히 방어할 수 있습니다.
c:out 태그는 자동으로 <, >, ", ', &와 같은 특수 문자를 HTML 엔티티(<, >, ", ', &)로 변환
즉, JSP view페이지를 만들 때 XSS공경 방지를 위해 " <c:out> "을 사용하여 막을 수 있습니다.
|JSP<c:out>을 사용하는 이유 ?
- 1) html이나 스크립트가 실행되어 위험합니다.
- 2) 엄격한 태그 규칙을 위해 사용합니다.
- 3) 개행문자 파싱의 차이 때문에 사용합니다.
- 4) 보안성 때문에 사용합니다.
c:out은 다음과 같이 문제(?)가 될 수 있는 HTML 문자를 탈락(escape)시키는 기능도 가지고 있기 때문입니다
정의 - https://mangkyu.tistory.com/14
생명주기 - https://velog.io/@yoonjy1106/JSPServlet-Servlet-Life-Cycle%EC%84%9C%EB%B8%94%EB%A6%BF-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0
JSP내장객체 - https://pathas.tistory.com/184
lazy loading - https://velog.io/@wawakdev/Servlet-%EC%84%9C%EB%B8%94%EB%A6%BF-%EA%B7%9C%EC%B9%99%EA%B3%BC-%EB%9D%BC%EC%9D%B4%ED%94%84-%EC%82%AC%EC%9D%B4%ED%81%B4
eltag - https://agileryuhaeul.tistory.com/entry/EL-%ED%83%9C%EA%B7%B8-%EB%9E%80-Expression-Language-Tag
c out 사용이유 - https://2ham-s.tistory.com/274
c tag - https://hackersstudy.tistory.com/42