TIL_20221122_웹 기본 동작 방식 이해하기

창고·2022년 11월 22일
0

서적 : http://www.yes24.com/product/goods/112373280
Spring + MyBatis + JSP 실습 겸 리마인드용으로 공부 중입니다.

1. 웹 프로그래밍의 시작

(1) 웹 프로젝트의 기본 구조

  • 브라우저 <-> 서버 <-> 데이터베이스 의 구조에서
  • 브라우저, 혹은 클라이언트 프로그램
    • 서버에 전송한 결과를 화면에 보여주고(렌더링), 사용자의 화면 조작을 이용하여 서버에 원하는 데이터를 보내고 받는 프로그램(request, response)
    • 관련 기술 : HTML / CSS / JavaScript
  • 웹 서버(Web Server) 혹은 WAS(Web Application Server)
    • 정적인 데이터를 제공하거나 (웹 서버) 동적으로 매번 새로운 데이터를 만들어낼 수 있는 WAS
    • 관련 기술 : 서블릿 / JSP, 각종 프레임워크 + 언어
  • 데이터베이스 (DB)
    • 영구적으로 데이터를 보관, 운영, RDBMS를 대부분 사용

2. 웹 기본 동작 방식 이해하기

(1) Request

  • GET 방식 : 주소 창에 직접 원하는 데이터를 입력하거 링크를 클릭하여 호출
    • 특정 정보 조회 용도
    • 구성 : URL 뒤의 '?' 와 쿼리 스트링
    • 사용자가 손쉽게 사용할 수 있는 링크 제공
    • 브라우저에 따라 길이 제한됨
    • URL 뒤의 쿼리 스트링으로 모든 정보가 전달됨
    • 쿼리 스트링 길이에 대한 제한이 있음
  • POST 방식 : 입력 화면에서 필요한 내용 작성 후 전송 등을 클릭해 호출
    • 웹 화면을 통해 실제 처리가 필요한 작업을 위해 사용
    • URL 전달 후 HTTP Body로 쿼리 스트링
    • 단순 조회가 아닌 CUD 등의 원하는 작업 처리 가능
    • GET 방식에 비해 많은 양의 데이터를 전송
    • 주소창 만으로는 테스트가 어려움

(2) Response

  • 정적(static) 데이터
    동일하게 고정된 데이터 전송, 주로 파일로 고정 (HTML / CSS / 이미지 파일 등)
    -> 정적 데이터를 보내는 역할만을 수행하는 서버는 웹 서버 (Web Server)
  • 동적(dynamic) 데이터
    매번 필요 시마다 다른 데이터를 동적으로 구성해서 전송
    -> 서버에서 데이터를 만들어 보내는 방식
    -> 동적 데이터를 만들어 보내는 경우는 웹 애플리케이션 서버 (WAS)
    • 대부분의 WAS는 웹 서버 기능도 같이 포함
  • HTTP
    비연결성 (Connectionless) : 하나의 요청과 응답을 처리한 후에 연결을 종료. 하나의 요청을 빨리 처리하고 연결을 종료하여 다음 요청을 받을 수 있게 되면 적은 리소스를 이용해 많은 수의 요청을 처리할 수 있다는 장점이 있음

(3) 자바 서버 사이드 프로그래밍

  • 서버 쪽에서 프로그래밍을 통해 데이터를 처리할 수 있도록 구성하는 것
  • 고려 사항
    • 동시에 여러 요청이 들어온다면 처리 방법은?
    • 서버에서 문제가 생기면 처리 방법은?
    • 어떤 방법으로 데이터 전송을 최적화 할 수 있는가?
    • 분산 환경이나 분산 처리는 어떻게?
  • 자바에서 서버 사이드 프로그래밍은 JavaEE 라는 기술 스펙으로 정리, 서블릿과 JSP는 이런 JavaEE의 여러 기술 중 하나

(4) 서블릿 기술과 JSP

  • 서블릿
    • 쉽게 이야기하여 서버에서 동적으로 요청과 응답을 처리할 수 있는 API들을 정의한 것
    • 서블릿을 지원하는 환경에서 서블릿 API를 이용, 코드를 작성, 이를 설정하는 방식으로 서블릿 프로그램을 작성
    • 서블릿 컨테이너 : 서블릿을 실행할 수 있는 환경, 서블릿 코드를 실행하는 주체
      - 객체를 생성하거나 호출하는 주체는 사용자가 아닌 서블릿 컨테이너
      - 서블릿 클래스에서 생성하는 객체의 관리 자체는 서블릿 컨테이너에 의해 관리
      - 서블릿/JSP의 코드 개발은 기본적인 자바 API와 더불어 서블릿 API도 같이 사용해야 함
  • JSP
    • Java Server Page의 약자로 서블릿 기술과 동일하게 서버에서 동적으로 데이터를 구성하는 기술
    • 근본적으로 서블릿과 같은 원리지만 좀 더 HTML을 쉽게 이용할 수 있는 방식
    • JSP와 서블릿의 차이
      • JSP 기술은 서블릿과 달리 HTML 코드를 그대로 이용, 필요할 때 약간의 자바 코드를 넣음
      • 서블릿 코드는 자바 코드를 이용, HTML 문자열을 만들어냄
    • JSP 코드는 자바 코드가 아님에도 서블릿과 동일하게 처리. JSP 파일도 서블릿 코드로 변환되어서 컴파일되고 실행되기 때문
  • 서블릿 / JSP 정리
    • 서블릿, JSP 모두 Java EE 스펙의 일부
    • 서블릿 / JSP를 실행하기 위해서는 서블릿 컨테이너 필요
    • 서블릿 컨테이너가 서블릿 / JSP 객체를 생성, 생명 주기를 관리
    • JSP는 내부적으로 서블릿과 같은 방식의 코드로 변환
    • JSP는 HTML 내에 자바 코드를 추가하는 방식
    • 서블릿 방식은 자바 코드 안에 HTML 코드를 추가하는 방식
  • 서블릿 기술 + JSP = 서블릿으로는 코드를 처리, JSP로는 화면 개발
  • JSP 위주 개발의 한계 및 문제점
    • GET/POST 방식의 호출을 구분하지 않음 -> POST 방식으로 접근해야 하는 경우에도 GET 방식으로도 얼마든지 호출이 가능해짐
    • 유지 보수 측면에서도 문제가 있음
  • JSP는 상기 이유로 제한적인 용도로 사용
    • JSP에서 쿼리 스트링이나 파라미터를 처리하지 않음 -> 서블릿을 통해 처리
    • JSP는 입력 화면을 구성하거나 처리 결과를 보여주는 용도로만 사용
    • 브라우저는 직접 JSP 경로를 호출하지 않고 서블릿 경로를 통해서 JSP를 보는 방식으로 사용
  • 이로 인해 Web MVC 방식이 등장 -> JSP는 결과만 출력, 처리는 서블릿

3. Web MVC 방식

(1) MVC 구조와 서블릿/JSP

  • 서블릿/JSP를 통해 요청 / 응답 처리
  • 웹 MVC 구조 (Model - View - Controller)의 역할을 분리해서 처리
    • 데이터는 컨트롤러에서, 결과는 뷰에서 처리
    • 서블릿이 컨트롤러 역할, JSP가 뷰 역할
    • 컨트롤러 역할을 하는 서블릿은 JSP에 필요한 데이터를 가공하는데 이 때 필요한 데이터를 제공하는 객체가 모델(Model)
  • MVC 구조 유념할 포인트
    • 브라우저의 호출은 반드시 컨트롤러 역할을 하는 서블릿을 호출하도록 구성
    • JSP는 브라우저에서 직접 호출하지 않도록 하고 Controller를 통해서만 JSP에 접근하도록 구성
  • GET 입력 화면의 설계
    • 브라우저는 /input과 같이 특정한 주소를 호출
    • /input에 맞는 서블릿을 InputController로 작성, GET 방식일 때만 동작
    • InputController의 화면 처리는 input.jsp를 이용하도록 지정
    • input.jsp에는 HTML 코드를 이용, 브라우저에서 볼 수 있는 결과를 생성
  • POST 처리의 설계
    • input.jsp의 <form> 태그의 action을 'calcResult'와 같이 변경, 이에 해당하는 CalcResultServlet 서블릿을 컨트롤러로 작성
    • 해당 서블릿은 <form> 으로 전달되는 데이터를 읽어 결과 데이터를 만들어야 함
    • 만들어진 결과를 calcResult.jsp와 같이 JSP로 전달, JSP에서는 결과 데이터를 출력
  • 서블릿의 RequestDispatcher의 forward() : 서블릿에 전달된 요청을 다른 쪽으로 전달 혹은 배포하는 역할을 하는 객체
  • HttpServletResponse의 sentRedirect() : 리다이렉션을 담당

(2) PRG 패턴 (Post-Redirect-Get)

  • PRG 패턴의 흐름
    • 사용자는 컨트롤러에 원하는 작업을 POST 방식으로 처리하기를 요청
    • POST 방식을 컨트롤러에서 처리, 브라우저는 다른 경로로 이동(GET)하라는 응답(Redirect)
    • 브라우저는 GET 방식으로 이동


4. HttpServlet

(1) HttpServlet의 특징

  • 주요 특징
    • GET/POST 등에 맞게 doGet(), doPost() 등을 제공, 개발자들은 본인에게 필요한 메소드를 오버라이드하는 것만으로 GET/POST 방식 처리를 나눌 수 있음
    • HttpServlet을 상속 받은 클래스 객체는 톰캣과 같은 WAS의 내부에서 자동으로 객체를 생성 / 관리하므로 개발자가 객체 관리에 신경 쓸 필요가 없음
    • HttpServlet은 멀티 스레드에 의해 동시에 실행될 수 있도록 처리 -> 개발자는 동시에 많은 사용자를 어떻게 처리해야 하는지에 대한 고민을 줄일 수 있음
    • HttpServlet은 GenericServlet를 상속 받으며 HTTP 프로토콜에 특화된 기능들을 처리할 수 있음
  • HttpServlet의 라이프 사이클
    • 웹이라는 특수한 환경 -> 개발자가 직접 객체를 생성하지 않고 톰캣에서 객체들을 관리
    • 브라우저가 톰캣에 서블릿이 처리해야 하는 특정 경로 호출
    • 톰캣은 해당 경로에 맞는 서블릿 클래스를 로딩, 객체 생성
    • 생성된 서블릿 객체는 브라우저의 요청(Request)에 대한 정보를 분석, GET/POST 등의 정보와 함께 전달되는 파라미터들을 HttpServletRequest라는 타입의 파라미터로 전달 받음
    • 이 때 응답을 처리하는데 필요한 기능들은 HttpServletResponse라는 타입의 객체로 전달 받음
    • 서블릿 내부에서는 GET/POST에 맞게 doGet()/doPost() 등의 메소드 실행 -> 이 후 동일한 주소의 호출이 있을 시 서블릿은 동일한 객체 하나만을 이용하여 이를 처리
    • 톰캣 종료 시 서블릿의 destroy() 라는 메소드를 실행
    • 중요한 점은 서블릿의 객체는 경로에 맞게 하나만 만들어진다는 점, 매번 호출 시에는 자동으로 doGet() / doPost()를 이용해서 처리

(2) HttpServletRequest의 주요 기능

  • HTTP 메시지 형태로 들어오는 요청(Request)에 대한 정보 파악용
  • HTTP 헤더 관련 : HTTP 헤더 내용들을 찾아내는 기능
    • getHeaderNames()
    • getHeader(이름)
  • 사용자 관련 : 접속한 사용자의 IP 주소
    • getRemoteAddress()
  • 요청 관련 : GET/POST 정보, 사용자가 호출에 사용한 URL 정보 등
    • getMethod()
    • getRequestURL()
    • getRequestURI()
    • getServletPath()
  • 쿼리 스트링 관련 : 쿼리 스트링 등으로 전달되는 데이터를 추출하는 용도
    • getParameter() -> 결과는 항상 String이며 null check 필수 (숫자 등을 처리할 때는 예외 발생 가능)
    • getParameterValues() -> 동일 파라미터 내에 여러개의 값이 있을 경우 사용, String[] 타입으로 반환
    • getParameterNames()
  • 쿠키 관련 : 브라우저가 전송한 쿠키 정보
    • getCookies()
  • 전달 관련
    • getRequestDispatcher()
  • 데이터 저장 : 전달하기 전에 필요한 데이터를 저장하는 경우에 사용
    • setAttribute() : JSP로 전달할 데이터를 추가할 때 사용, key-value 형식으로 저장 (key는 문자열, value는 모든 객체 타입 가능)
  • RequestDispatcher : 현재의 요청을 다른 서버의 자원(서블릿 혹은 JSP) 에게 전달하는 용도로 사용
    • forward() : 현재까지의 모든 응답(Response) 내용은 무시하고 JSP가 작성하는 내용만을 브라우저로 전달 << 가장 많이 사용
    • include() : 지금까지 만들어진 응답(Response) 내용 + JSP가 만든 내용을 브라우저로 전달 (거의 안 씀)

(3) HttpServletResponse의 주요 기능

  • HttpServletRequest가 '읽는' 기능을 제공한다면 반대로 '쓰는' 기능을 담당
  • 웹 MVC 구조에서 HttpServletResponse는 주로 JSP에서 처리되므로 서블릿 내에서 직접 사용되는 일은 많지 않으며 주로 sendRedirect()를 이용
  • MIME 타입 : 응답 데이터의 종류를 지정(이미지/html/xml 등)
    • setContentType()
  • 헤더 관련 : 특정 이름의 HTTP 헤더 지정
    • setHeader()
  • 상태 관련 : 404, 200, 500 등 응답 상태 코드 지정
    • setStatus()
  • 출력 관련 : PrintWriter를 이용, 응답 메시지 작성
    • getWriter()
  • 쿠키 관련 : 응답 시 특정 쿠키 추가
    • addCookie()
  • 전달 관련 : 브라우저에 이동을 지시
    • sendRedirect()

5. 모델(Model)

(1) 모델과 3티어

  • View-Controller-Model
  • MVC 구조를 제외하고 전체 시스템의 구조를 정리 : 3티어 구조
  • DTO(Data Transfer Object)
    • 3티어와 같이 계층을 분리하는 경우 반드시 계층이나 객체들 간 데이터 교환이 이루어짐
    • 이 경우 여러 개의 데이터를 묶어서 하나의 객체로 전달하는 것을 DTO라고 함
    • 대부분 Java Beans 형태로 구성 (최소한의 규칙 3가지)
      • 생성자가 없거나 반드시 파라미터가 없는 생성자 함수를 가지는 형태
      • 속성(멤버 변수)는 private으로 작성
      • getter/setter를 제공
    • 이외에 Serializable 인터페이스를 구현하는 등의 규칙이 있으나 앞의 3가지 규격이 최소한의 규격
  • 서비스 객체
    • 기능(로직)들의 묶음. 프로그램이 구현해야 하는 기능들의 실제 처리를 담당
    • enum 타입으로 클래스 작성 시 정해진 수만큼만 객체 생성이 가능, 필요한 기능 호출 시 관련 객체만 1회 생성, 이후 반복 사용 -> 싱글톤 패턴

(2) 컨트롤러에서 모델 처리하기

  • 컨트롤러 - 서비스 - JSP 흐름
  • 웹 MVC 구조에서는 화면에 필요한 데이터를 처리하고자 컨트롤러는 서비스 객체를 이용하여 처리
  • 이 때 HttpServletRequest의 setAttribute()로 데이터를 보관한 후 JSP에서 꺼내서 사용

(3) JSP - EL(Expression Language)

  • 과거에는 JSP에서 자바 문법을 이용, 화면에 결과를 출력했으나 최근에는 JSP에 자바 코드를 사용해서 결과를 출력하는 일이 거의 없음
  • JSP 2.0부터 출력용 언어인 EL이 지원
  • HTML 태그, 자바스크립트, CSS 등을 이용하여 코드를 작성
${list[0].tn0} --- ${list[0].title}
  • 자바 코드에서는 private으로 선언된 필드에 대해 외부에서 바로 접근이 불가능하나, EL은 get~() 클래스를 자동으로 호출하기 때문에 내부에 표현식이 결과를 만들어낼 수 있다면 언제든지 사용이 가능
<h3>${1 + 2+ 3}</h3>
<h3>${"AAA" += "BBB"}</h3>
<h3>${"AAA".equals("AAA")}</h3>
6
AAABBB
true
  • EL은 JSP에서 간단한 표현식을 이용해서 데이터를 출력하는 용도
  • 제어문 / 반복문과 같이 '식'이 아닌 '문(statement)'를 처리하기 위해서는 JSTL 라이브러리 필요

(4) JSP - JSTL(JavaServer Pages Standard Tag Library)

  • build.gradle에 의존성 추가 필요
  • 태그 관련 설정 추가
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
  • 지시자(directives) : JSP에서 '%@%' 로 작성되는 코드
  • 반복문 처리 <c:forEach>
    • 배열, 리스트 처리에 사용
    • var : EL에서 사용될 변수 이름
    • items : List, Set, Map, Enumeration, Iterator 등의 컬렉션
    • begin/end : 반복의 시작 / 끝값
<ul>
  <c:forEach var="dto" items="${list}">
    <li>${dto}</li>
  </c:forEach>
  <c:forEach var="num" begin="1" end="10">
    <li>${num}</li>
  </c:forEach>
</ul>  
  • 제어문 <c:if>, <c:choose>
    • <c:if> : 속성값이 true/false로 나올 수 있는 식이나 변수 등 처리 시
    • <c:choose> : switch 구문과 비슷한 역할.
      • <c:when test=..>, <c:otherwise> 를 이용하여 if else 처리가 가능
<c:if test="${list.size() % 2 == 0}">
  짝수
</c:if>
<c:if test="${list.size() % 2 != 0}">
  홀수
</c:if>
<c:choose>
  <c:when test="{list.size() % 2 == 0}">
    짝수
  </c:when>
  <c:otherwise>
    홀수
  </c:otherwise>
</c:choose>
  • <c:set>
    • 반복문, 제어문 처리 시 새로운 변수를 생성해야 할 때가 있음. 이 때 사용
    • VAR 속성으로 변수명을 지정, VALUE 속성으로 값을 지정
    • 아래 예제는 target이라는 변수 선언, 반복문 내부에서 <c:if>를 이용
<c:set var="target" value="5"></c:set>

<ul>
  <c:forEach var="num" begin="1" end="10">
    <c:if test="${num == target">
      num is target
    </c:if>
  </c:forEach>
</ul>
profile
공부했던 내용들을 모아둔 창고입니다.

0개의 댓글