서블릿
- 일반적으로 jsp와 거의 같은 의미로 사용된다
- 서블릿이 발전된 것이 Spring
- 서블릿의 @Servlet() = 스프링의 @Controller + @RequestMapping
- HttpServlet을 상속받아 사용, service메소드를 상속받아 사용(이때문에 메소드이름은 service로 고정이 된다.)
- 클래스에 매핑을 하기에 매핑마다 클래스르 생성해야 한다. <-> 스프링에서는 메소드에 매핑을 한다.
- request와 response를 매개변수로 받는다.
- HttpServlet은 init, service, destroy 3개의 메소드를 가진다.
- init: 서블릿 초기화- 서블릿이 생성 또는 리로딩 때, 단 한번만 수행됨 (서블릿 컨테이너가 알아서 처리함)
- service: 입력과 처리, 출력을 한다. 호출때마다 반복적으로 수행된다. (개발자가 주로 처리하는 부분)
- destroy: 뒷정리 작업, 서블릿이 제거(unload)될때, 단 한번만 수행됨 (서블릿 컨테이너가 알아서 처리함)
WebServlet의 경우 메소드 단위 매핑이 불가능하다.?
// 서블릿
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/rollDice2")
public class TwoDiceServlet extends HttpServlet {
int getRandomInt(int range) {
return new Random().nextInt(range)+1;
}
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
int idx1 = getRandomInt(6);
int idx2 = getRandomInt(6);
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("</head>");
out.println("<body>");
out.println("<img src='resources/img/dice"+idx1+".jpg'>");
out.println("<img src='resources/img/dice"+idx2+".jpg'>");
out.println("</body>");
out.println("</html>");
out.close();
}
}
//컨트롤러 (스프링)
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@Controller
public class TwoDice {
@RequestMapping("/rollDice")
// public static void main(String[] args) {
public void main(HttpServletResponse response) throws IOException {
int idx1 = (int)(Math.random()*6)+1;
int idx2 = (int)(Math.random()*6)+1;
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("</head>");
out.println("<body>");
out.println("<img src='resources/img/dice"+idx1+".jpg'>");
out.println("<img src='resources/img/dice"+idx2+".jpg'>");
out.println("</body>");
out.println("</html>");
out.close();
}
}
서블릿의 생명주기
- 인스턴스는 한번만 만든다. (싱글톤)
- 스프링도 마찬가지
JSP
- Java Server Pages
- 쉽게 말하면 HTML안에 자바코드가 있는 것
- jsp 페이지를 요청하면 서블릿(자바파일)으로 변환이 된다.
- 클래스영역은 느낌표를 붙여 오른쪽과 같이 표현한다. <%! 자바 코드 %>
- 메서드 영역은 느낌표가 빠지고 오른쪽과 같이 표현한다. <% 자바 코드 %>
- 메서드 영역은 서블릿의 서비스 영역으로 들어 간다. 서블릿코드는 글 맨 위에 있음.
- jsp의 위치: src/main/webapp/twoDice.jsp
<%@ 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의 호출과정
- 확장자가 jsp인 요청이 들어오면 Servlet이 모든 요청을 받는다.
- 초기호출시에는 지연이 생길 수 있다. - 변환과정때서
- 서블릿은 늦은초기화(lazy-init)가 default, 요청이 들어오면 객체를 만듬
- 스프링은 빠른초기화(early-init), 객체를 미리 만들어 놓음
- 아래의 코드사진처럼 jsp가 변환된다.
JSP의 기본 객체
- 생성 없이 사용할 수 있는 객체
- request, response, pageContext, session, application, config, out, page 등
- 아래의 jsp가 어차피 변환되니깐 _jspService안에 있는 로컬변수를 접근할 수 있다.
JSP의 유효범위(scope) 및 속성(attribute)
http는 stateless(상태정보저장X)하기에 저장소가 필요하다.
JSP는 4개의 저장소를 가진다. hashmap형태(key,value)
- pageContext
- EL때문에 씀 ${}
- 로컬변수저장 -> EL(${})때문에 ,EL는 <%=lv%>처럼 변수이름에 접근안돼서 따로 저장을 해놓고 써야함
- 기본객체(request,response)
- 읽기,쓰기 가능
- 새로 접근하면 지워짐
- 같은 페이지 내에서만 접근가능
- application
- WebApp 전체에서 접근가능, pageContext등에서도 접근가능
- 서로 다른 클라이언트가 접근했을 때 이전 아이디가 지워진다. ({id:aaa}엿는데 다른데서 bbb사용자가 들어오면 id:bbb로 바뀜)
그래서 로그인같은 정보는 세션에 저장
- session
- 사용자 개별저장소이다.
- id, 장바구니 등을 저장
- 쿠키를 이용해서 사용
- 사용자수마다 객체를 생성하기때문에 세션에는 최소한의 정보만 담아야한다.
- 프로그래밍에 사용하기엔 편리하지만 서버부담이 제일 크다.
- request
- request객체에 정보를 담아 전달
- jsp에 request를 하면 jsp가 바로 응답을 해주거나 다른 jsp로 넘겨(forward)서 거기서 처리해줄 수 있다.
- request에 담을 수 있는건 requset에 담고 못 담는다면 세션이용
URL 패턴
- @WebServelt("/hello") 뿐만 아니라 @@WebServelt(urlPatterns={"/hello", "/hello/*"}, loadOnstartup=1) 처럼 여러개를 등록 할 수 있다. loadOnstartup=1은 미리 초기화(객체 만들어둠)를 한다는 뜻이다. 1은 우선순위
- 아래의 표는 우선순위 순으로 표기 (위에서 안걸리면 순차적으로 넘어감)
- exact mapping은 정확히 매핑
- exact mapping에 안 걸리면 path mapping으로 넘어감, 또 안걸리면 우선순위 순으로 넘어감
- extension mapping은 확장자 매핑
요청이 들어오면 가장 먼저 sevletMappings으로 들어간다.
그 다음 매핑에 맞는 서블릿으로 넘어간다.
서블릿에선 default는 정적리소스를 이용하고 그 외에 것들은 동적리소스(서블릿)를 다룬다
스프링에서는 default로 모두 넘어가고 default를 DefaultServlet으로 매핑하는 것이 아니라 DisPatcherServlet로 넘겨서 Dispatch에서 모든 것을 매핑한다.
EL과 JSTL
https://yunzae.tistory.com/170
EL과 JSTL
이 둘은 jsp에서 문법을 좀더 간단하고 효율적으로 사용하기 위해 사용되는 문법들이다. EL Expression Lanuge 값들을 간단하게 표시하기 위해 사용 대신 ${값}으로 사용 하는 것 -보다 간단하게 표현가
yunzae.tistory.com
Filter
- 공통적인 요청 전처리와 응답 후처리에 사용 (전처리,후처리가 필수적인건 아니다)
- 로깅, 인코딩 등
- 중복제거
- AOP와 유사
- 필터가 여러개 일수도 있다.
- 필터의 예시( 수행시간 측정의 기능이 있는 필터)
// 필터를 적용할 요청의 패턴 지정 - 모든 요청에 필터를 적용.
@WebFilter(urlPatterns="/*") //필터등록 어노테이션, 어떤 url들에 적용할 건지
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. 후처리 작업
System.out.print("["+((HttpServletRequest)request).getRequestURI()+"]");
System.out.println(" 소요시간="+(System.currentTimeMillis()-startTime)+"ms");
}
@Override
public void destroy() {
// 정리 작업
}
}
- 필터가 없다면 코드는 아래와 같은 코드들이 여러개 존재한다. 전,후처리가 중복됨
@WebServlet("/rollDice2")
public class TwoDiceServlet extends HttpServlet {
int getRandomInt(int range) {
return new Random().nextInt(range)+1;
}
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
// 1.전처리 작업
long startTime - System.currentTimeMillis();
// 2. 작업
int idx1 = getRandomInt(6);
int idx2 = getRandomInt(6);
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("</head>");
out.println("<body>");
out.println("<img src='resources/img/dice"+idx1+".jpg'>");
out.println("<img src='resources/img/dice"+idx2+".jpg'>");
out.println("</body>");
out.println("</html>");
out.close();
//3.후처리 작업
System.out.print("["+((HttpServletRequest)request).getRequestURI()+"]");
System.out.println(" 소요시간="+(System.currentTimeMillis()-startTime)+"ms");
}
}
'I leaned > 스프링,스프링부트' 카테고리의 다른 글
@RequestParam과 @ModelAttribute (0) | 2023.05.19 |
---|---|
EL과 JSTL (1) | 2023.05.19 |
OOP 5대 설계원칙 - SOLID (0) | 2023.05.17 |
Eclipse(STS)와 IntelliJ (0) | 2023.05.10 |
톰캣 (0) | 2023.05.10 |