2020-12-10 TIL

4 minute read

build 도구와 설정 파일

image-20201210161027886

  • 프로젝트 폴더

    • /src
    • pom.xml <- mavem 빌드 도구의 설정 파일
    • build.gradle <- gradle 빌드 도구의 설정 파일
      • Java 빌드 도구
    • /src/main/webapp/package.json <- npm 패키지 관리자의 설정 파일
      • Web library(javaScript, Css)

front Controller

도입 전

image-20201210161013551

  • — 요청 —> s1 — 업무 처리 위임—> service

    ​ — ui 위임 —> jsp

  • — 요청 —> s2 — 업무 처리 위임—> service

    ​ — ui 위임 —> jsp

도입 후

image-20201210160932251

​ ——> jsp, exception

  • — 요청 —> front — 위임 —> s1 — 업무 처리 위임—> service

    ​ <- jsp 경로-

    ​ — 요청 —> s2 — 업무 처리 위임—> service

    ​ <- jsp 경로-

pms 프로젝트 정보 조회 구조 변경

image-20201210160914709

page controller 의 POJO화

image-20201210160901039

​ ——> jsp, exception

  • — 요청 —> front — execute —> controller

    <— boardListController
    <— boardDetailController

    ​ .

    ​ .

    ​ .

  • Page controller가 일반 클래스로 변경되면 객체 생성을 직접 관리할 수 있다.

    • 의존 객체 주입 가능
      • 물론 객체관리 코드를 짜야한다.

@Retention(RetentionPolicy.RUNTIME

  • 클래스를 컴파일하고 유지한다.

실행 과정

image-20201210160842465

load on startup - 서블릿 객체 자동 생성하기(애노테이션으로 설정하기)

package com.eomcs.web.ex06;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// 클라이언트가 실행을 요청하지 않아도 서블릿을 미리 생성하고 싶다면,
// loadOnStartup 프로퍼티 값을 지정하라.
// loadOnStartup=실행순서
// 미리 생성할 서블릿이 여러 개 있다면, loadOnStartup에 지정한 순서대로 생성한다.
// 언제 서블릿을 미리 생성하는가?
// => 서블릿이 작업할 때 사용할 자원을 준비하는데 시간이 오래 걸리는 경우
// 웹 애플리케이션을 시작시킬 때 미리 서블릿 객체를 준비한다.
// => 예) DB 연결, 소켓 연결, 필요한 환경 변수 로딩, 스프링 IoC 컨테이너 준비 등
//
//@WebServlet(value = "/ex06/s1", loadOnStartup = 1)
//@SuppressWarnings("serial")
public class Servlet01 extends HttpServlet {

  @Override
  public void init() throws ServletException {
    // 클라이언트가 서블릿의 실행을 요청할 때 서블릿 객체가 없으면 생성된다.
    // 서블릿 객체가 생성될 때 이 메서드가 호출된다.
    System.out.println("/ex06/s1 => init()");
  }

  @Override
  protected void service(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    System.out.println("/ex06/s1 => service()");
  }
}

세션 활용

  • 한 작업을 여러 서블릿을 거쳐 수행하는 경우 서블릿들의 중간 작업 결과를 보관하는 용도로 이용한다.
    • 예) 보험 가입

image-20201211114512315

세션

image-20201211114530391

​ => 클라이언트를 식별하는 기술이다.

​ => HTTP 프로토콜은 Stateless 방식으로 통신을 한다.

​ 즉 연결한 후 요청하고 응답을 받으면 연결을 끊는다.

​ 그래서 서버는 클라이언트가 요청할 때 마다 누구인지 알 수 없다.

​ => 이를 해결하기 위해

​ 클라이언트가 접속하면 웹 서버는 그 클라이언트를 위한

​ 고유 번호를 발급(쿠키 이용)한다.

​ 이 고유 번호를 ‘세션 아이디’라 부른다.

​ => 웹 브라우저는 세션 아이디를 쿠키에 보관해 두었다가

​ 그 서버에 요청할 때 마다 세션 아이디를 보낸다.

​ 왜? 세션 아이디는 쿠키이다.

​ => 세션 아이디를 쿠키로 보낼 때 유효기간을 설정하지 않았기 때문에

​ 웹 브라우저를 종료하면 세션 아이디 쿠키는 삭제된다.

​ => 세션 아이디 쿠키의 사용 범위는 웹 애플리케이션이다.

​ 예) /eomcs-java-web

​ 따라서 같은 웹 애플리케이션의 서블릿을 실행할 때는

​ 무조건 세션 아이디를 보낸다.

​ 세션 아이디는 언제 발급하는가?

​ => 새 세션을 생성할 때 세션 아이디를 발급한다.

​ 언제 새 세션을 생성하는가?

​ => 세션이 없는 상태에서 request.getSesssion()을 호출할 때 생성한다.

​ => 생성한 세션의 ID는 쿠키를 통해 응답할 때 웹브라우저로 보낸다.

​ => HTTP 응답 프로토콜

​ HTTP/1.1 200

​ Set-Cookie: JSESSIONID=5801C115615A2C9074AC0B78E31C5F21; Path=/eomcs-java-web; HttpOnly

​ Content-Type: text/plain;charset=UTF-8

​ Content-Length: 44

​ Date: Wed, 08 Apr 2020 03:10:58 GMT

​ Keep-Alive: timeout=20

​ Connection: keep-alive

​ 세션 생성하기 : getSession() 호출

​ 1) 클라이언트가 세션 아이디를 쿠키로 전송

​ - 서버에서는 해당 아이디의 세션을 찾는다.

​ - 있으면, 그 세션을 리턴한다.

​ - 있는데 세션의 유효 기간이 지났다면, 새로 세션을 만들어 리턴한다.

​ - 없다면, 새로 세션을 만들어 리턴한다.

​ 2) 클라이언트가 세션 아이디를 보내지 않은 경우

​ - 서버는 새 세션을 만들어 리턴한다.

​ 항상 새 세션을 만들면, 응답할 때 새 세션의 아이디를 쿠키로 보낸다.

세션에서 값 꺼내기

package com.eomcs.web.ex11;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("/ex11/s2")
@SuppressWarnings("serial")
public class Servlet02 extends HttpServlet {

  @Override
  protected void service(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    // 테스트 방법:
    // => http://localhost:8080/java-web/ex11/s2
    //

    // 세션 아이디 보내기
    // => 서버로부터 쿠키를 통해 받은 세션 아이디는
    // 웹 브라우저가 해당 서버에 요청할 때마다
    // 쿠키로 세션 아이디를 보낸다.
    // => HTTP 요청 프로토콜
    //
    // GET /eomcs-java-web/ex11/s2 HTTP/1.1
    // Host: localhost:9999
    // Connection: keep-alive
    // ...
    // Cookie: JSESSIONID=AAEEF5A0E55596AB47FF69573B179CB5 <--- 세션아이디

    HttpSession session = request.getSession();
    // 1) 세션 아이디가 있다면,
    //    => 세션 아이디가 유효하다면,
    //       => 기존에 생성한 HttpSession 객체를 리턴한다.
    //    => 세션 아이디가 유효하지 않다면,
    //       => 2) 번으로 간다. 
    // 2) 세션 아이디가 없다면,
    //    => 새 HttpSession 객체를 생성하여 리턴한다.
    //    => 응답 프로토콜에 새로 생성한 HttpSession 객체의 세션ID를 
    //       쿠키로 보낸다.

    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();

    // 세션에서 값 꺼내기
    // => 웹 브라우저를 종료하면 이전에 /ex11/s1 을 실행했을 때
    // 서버로부터 받은 세션 아이디 쿠기가 삭제된다.
    // => 그런 후에 웹 브라우저에서 이 서블릿을 요청하면
    // getSession() 메서드를 새 세션 객체를 생성한 후 리턴한다.
    // 따라서 새 세션에는 v1 이라는 이름으로 저장된 값이 없기 때문에
    // null을 출력할 것이다.
    //
    out.printf("v1=%s\n", session.getAttribute("v1"));
  }
}

실무에서의 세션

  • 여러 작업을 수행하는 동안 공유할 객체를 저장하는 용도로 세션 보관소를 활용한다.

타임아웃

package com.eomcs.web.ex11;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("/ex11/s21")
@SuppressWarnings("serial")
public class Servlet21 extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    HttpSession session = request.getSession();

    // 세션의 유효 시간(초)을 설정한다.
    // => 클라이언트가 요청하는 순간부터 세션 시간을 카운트한다.
    //    만약 10초 이내에 클라이언트의 요청이 없으면
    //    10초를 초과하는 순간 httpSession 객체를 무효화시킨다.
    //    10초 이내에 다시 클라이언트 호출이 있다면
    //    카운트를 0부터 다시 시작한다.
    session.setMaxInactiveInterval(10);

    session.setAttribute("v1", "aaa");

    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter out = response.getWriter();
    out.println("/ex11/s21 실행함!");
  }
}

pojo

  • Plain old java object

  • https://happyer16.tistory.com/entry/POJOplain-old-java-object%EB%9E%80

Categories:

Updated: