배운 것
서블릿
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>
참고
[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을 직접 써보며 익숙해져야겠다.
'아카이브 > 스프링' 카테고리의 다른 글
스프링의 정석 (@RequestParam, @ModelAttribute) (0) | 2021.12.27 |
---|---|
스파르타 코딩클럽 [ 웹개발의 봄, Spring ] - 1주차 (0) | 2021.12.26 |
스프링의 정석 (관심사 분리와 MVC패턴) (0) | 2021.12.24 |
스프링의 정석 ( 클라이언트-서버, 웹 어플리케이션 서버, 텍스트 파일, 바이너리 파일 ) (0) | 2021.12.22 |
스프링의 정석 ( 원격 프로그램, HTTP 요청/응답 ) (0) | 2021.12.21 |