변경된 코드의 반영
- jsp 파일 : 소스 코드 변경하는 것만으로 반영
- java 파일: ‘services’ - ‘deploy all’을 통해 현재 코드를 다시 빌드해야 반영
GET 방식
- 주소창에 직접 원하는 데이터를 적거나 링크를 클릭해서 호출
- 데이터를 ‘?’과 ‘&,=’를 이용해서 전송
- 주소 + 데이터를 한 번에 보냄
- 주로 정보 조회 용도
POST 방식
- 입력 화면에서 필요한 내용을 작성한 후에 ‘submit’ 버튼 클릭하여 호출
- 주소와 데이터를 따로 보냄
- ex) 회원 가입이나 로그인
- 웹 화면을 통해서 실제 처리가 필요한 작업
서버가 브라우저로 보내는 응답에 따른 분류
- 정적 데이터 (고정된 파일 전송) → 웹 서버가 보냄
- 동적 데이터 (필요할 때마다 다른 데이터로 구성해서 전송, 서버 사이드 프로그래밍이라고도 함) → 웹 어플리케이션 서버(WAS)가 보냄
- 톰캣의 경우, 엄밀하게 WAS지만 웹 서버 기능도 같이 포함하므로 이미지, CSS/JS 파일과 같은 정적인 자원들과 서블릿/JSP 같은 동적인 자원 모두를 처리할 수 있음
HTTP 메세지
- Header - Body로 구성
- HTTP의 비연결성: 항목 하나당 요청과 응답이 하나의 단위로 처리됨. 하나의 요청과 하나의 응답이 끝나면 연결이 종료.
자바 서버 사이드 프로그래밍
- 서버 쪽에서 프로그래밍을 통해 데이터를 처리할 수 있도록 구성한 것
- “만약 동시에 여러 요청이 들어온다면? 서버에 문제가 생긴다면?” 등등 데이터 처리와 관련된 문제에 어떻게 대처할 것인지 정리해놓은 것이 JavaEE이고, Servlet과 JSP는 JavaEE의 기술 중 하나.
🚩서블릿(Servlet) 기술
- 서버에서 동적으로 요청과 응답을 처리할 수 있는 API들을 정의한 것
- 개발자들은 서블릿에서 제공하는 API를 이용해서 코드를 작성하고 이를 설정하는 방식으로 서블릿 프로그램을 작성
- 서블릿은 서블릿을 실행할 수 있는 환경 = 서블릿 컨테이너 (= 우리는 톰캣)에서 실행 가능
- 일반 자바 프로그램과의 차이점:
-
객체 생성, 호출, 관리 주체는 서블릿 컨테이너 (사용자 x)
-
서블릿/JSP의 코드 개발은 기본적인 자바 API와 더불어 서블릿 API도 같이 사용
ex) HelloServlet.java 파일을 살펴보자
-
import javax. = 서블릿 API
-
init(), doGet(), destroy() = 서블릿 API에 지정된 메소드
메소드들의 호출 주체는 개발자가 아닌, 서블릿 컨테이너가 서블릿들을 관리하면서 호출
- JSP와의 차이점: 근본적으로 서블릿과 같은 원리. HTML을 좀 더 쉽게 이용할 수 있는 방식의 코드 작성. →서블릿으로는 코드를 이용한 처리, JSP로는 화면 개발
🚩JSP 기술
- Java Server Pages. 서블릿 기술과 동일하게 서버에서 동적으로 데이터를 구성하는 기술

- JSP 기술은 HTML 코드를 그대로 이용
- Servlet 기술은 자바 코드를 이용해서 HTML 문자열을 만들어냄
JSP를 이용해서 GET 처리하기
JSP를 이용해서 POST 처리하기
- 로 제출한 input 값 확인
→ 개발자 도구 - Network - Name에서 원하는 파일 - Payload

<h1>NUM1 ${param.num1}</h1> 꼴로 사용
- 그러나 JSP는 여러가지 문제가 많아서 입력 화면, 처리 결과 보여주기 정도에만 사용한다. 브라우저는 직접 JSP 경로를 호출하지 않고 서블릿 경로를 통해서 JSP를 보는 방식으로 사용한다. → 이러한 문제를 해결하기 위해 ‘웹 MVC’ 방식 등장. → JSP는 결과만 출력하고, 처리는 서블릿을 이용
🚩Web MVC
- ‘Model - View - Controller’의 역할을 분리해서 처리하는 구조
- 데이터는 컨트롤러에서 처리, 결과는 뷰에서 처리, 필요한 데이터 제공하는 객체는 모델
- 서블릿 = 컨트롤러, JSP = 뷰
- 계산기 예제에서 브라우저의 호출 = ‘/input’, 컨트롤러 = InputController, 뷰 = input.jsp


- MVC 구조의 원칙
- 브라우저의 호출은 반드시 컨트롤러 역할을 하는 서블릿을 호출하도록 구성
- JSP는 브라우저에서 직접 호출하지 않도록 하고 컨트롤러를 통해서만 JSP에 접근하도록 구성
GET 방식 - RequestDispatcher를 이용한 요청 배포
@WebServlet(name = "inputController", urlPatterns = "/calc/input")
public class inputController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("InputController...doGet...");
RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/calc/input.jsp");
dispatcher.forward(req,resp);
}
}
- RequestDispatcher란 서블릿에 전달된 요청을 다른 쪽으로 전달/배포하는 객체
- RequestDispatcher를 이용하면 InputController는 버스 정류장처럼 "/WEB-INF/calc/input.jsp"라는 목적지로 가는 중간 경유지가 된다.
- 실행 순서
- 사용자가 ‘/calc/input’이라는 url을 입력해서 접근한다. = doGet()
- @WebServlet(name = "inputController", urlPatterns = "/calc/input")에 따라 ‘/calc/input’ 라는 url로 실행이 되었으면, inputController라는 이름의 서블릿이 실행되어 HTTP 요청을 처리하기 시작한다
- "InputController...doGet..." 출력
- RequestDispatcher에 의해 "/WEB-INF/calc/input.jsp" 로 이동
- 사용자의 브라우저에는 "/WEB-INF/calc/input.jsp"가 보인다

- WEB-INF 밑에 파일을 둔다 = 브라우저에서 jsp로 직접 호출이 불가능하다

POST 방식 - 처리 요청과 sendRedirect()
@WebServlet(name = "calcController", urlPatterns = "/calc/makeResult")
public class CalcController extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("InputController...doGet...");
String num1 = req.getParameter("num1");
String num2 = req.getParameter("num2");
System.out.printf("num1: %s", num1);
System.out.printf("num2: %s", num2);
resp.sendRedirect("/index");
}
}
- req.getParameter()라는 메소드를 이용해서 쿼리 스트링으로 전달되는 num1, num2 파라미터를 처리하고 있다. 서블릿에서 HttpServletRequest라는 API를 사용한 것!!
- resp.sendRedirect("/index")를 통해 GET 방식으로 해당 주소를 호출한다
PRG 패턴(Post-Redirect-GET)
- 웹 MVC 구조에서 가장 흔하게 사용하는 패턴
- 사용자는 컨트롤러에 원하는 작업을 POST 방식으로 처리하기를 요청
- POST 방식을 컨트롤러에서 처리하고 브라우저는 다른 경로로 이동(GET)하라는 응답(Redirect)
- 브라우저는 GET 방식으로 이동
HttpServlet
- 서블릿의 객체는 경로에 맞게 하나만 만들어진다
- 서블릿 객체에서 최종적으로 요청(Request)를 처리하는 doGet()/doPost() 등은 HttpServletRequest와 HttpServletResponse를 파라미터로 전달받는다.
HttpServletRequest의 주요 기능
- HttpServletRequest는 HTTP 메세지 형태로 들어오는 요청(Request)에 대한 정보를 파악하기 위해 제공되는데 주요 기능은 다음과 같다.

- getParameter()의 결과 = 항상 String
- getParameterValues() = 파라미터가 여러 개 있을 때 사용
- setAttribute()는 JSP로 전달할 데이터를 추가할 때 사용한다. 키-값 형태로 데이터를 저장할 수 있다. JSP에는 서블릿에서 setAttribute()로 전달된 데이터를 화면에 출력하게 된다.
- getRequestDispatcher()로 RequestDispatcher 타입의 객체를 구할 수 있다.
- RequestDispatcher에서 주로 쓰는 메소드 : forward() -현재까지의 모든 응답(Response) 내용은 무시하고 JSP가 작성하는 내용만을 브라우저로 전달
RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/calc/input.jsp");
dispatcher.forward(req,resp);
HttpServletResponse의 주요 기능
- sendRedirect()를 사용하면 브라우저의 주소가 아예 변경되기 때문에 사용자의 ‘새로고침’과 같은 요청을 미리 방지 + 특정 작업 완전히 끝나고 새로 시작하는 흐름 생성
TodoList 실습 (1) - todoRegisterController
@WebServlet(name = "todoRegisterController", urlPatterns = "/todo/register")
public class TodoRegisterController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("입력 화면을 볼 수 있도록 구성");
RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/todo/register.jsp");
dispatcher.forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("입력을 처리하고 목록 페이지로 이동");
resp.sendRedirect("/todo/list");
}
}
- “/todo/register” url로 들어왔을 때 (= GET 방식) doGet() 호출
- “/todo/register”에서 제출 버튼을 눌렀을 때 (=POST 방식) doPost() 호출
- 하나의 서블릿 안에서 여러 개의 메소드를 오버라이드/정의해서 사용하는 사례
모델
- 모델 영역 = 서비스(로직 처리) 계층 + 영속(데이터 처리) 계층
- DTO(Data Transfer Object) : 여러 개의 데이터를 묶어서 하나의 객체로 전달하는 것. 주로 Java Beans 형태로 구성

- Java Beans의 형식
- 생성자가 없거나 반드시 파라미터가 없는 생성자 함수를 가지는 형태
- 속성(멤버 변수)은 private로 작성
- getter/setter를 제공할 것
- 컨트롤러는 DTO를 서비스 계층으로 보내기도 (호출), 서비스 계층에서 DTO를 받기도 한다. 따라서 서비스 계층 구성 전에 DTO를 위한 클래스를 먼저 구성해야한다. (ex) todo 패키지 아래 dto 패키지를 구성하고 TodoDTO 클래스 생성)
서비스 객체
- 서비스 객체란 ‘기능(로직)들의 묶음’. 프로그램이 구현해야 하는 기능들의 실제 처리 담당 ex) CRUD (등록/조회/수정/삭제) 기능들은 모두 서비스 객체에 모아서 구현 ex) Todo라는 대상을 다루고 있을 때, 이를 담당하는 서비스 객체는 TodoService라는 이름으로 클래스를 이용해서 처리하고, 앞의 컨트롤러들은 TodoService의 객체를 이용해서 자신이 원하는 작업을 처리하도록 구성
- DTO는 주로 서비스 객체 메소드들의 파라미터나 리턴 타입으로 사용
TodoService 클래스

package org.zerock.demo.todo.service;
public enum TodoService {
INSTANCE;
}
- enum 타입 장점: 정해진 수만큼만 객체를 생성할 수 있음
- INSTANCE = 객체의 개수를 결정하는 부분. 한 개만 지정되어 있으므로 하나의 객체만을 생성하여 사용할 수 있음. → TodoService.INSTANCE와 같이 사용 가능 → TodoService.INSTANCE는 항상 하나의 객체만을 가르킴 → 이러한 패턴을 ‘싱글톤 패턴’이라고 함
컨트롤러에서 모델 처리
- 웹 MVC 구조에서 화면에 필요한 데이터를 처리하려는 컨트롤러는 서비스 객체의 힘을 빌려서 처리.
- 컨트롤러 → 모델(서비스 객체)에 데이터 요청 (ex 메소드, 객체) → 데이터를 받아서 뷰(JSP)에 전달 → 뷰(JSP)가 브라우저에 데이터를 띄움

JSP - EL(Expression Language)
- 자바를 모르는 사람도 간단하게 사용할 수 있는 출력용 언어/ 표현식
- ex) ‘’,<h4>‘{list[0].getTitle()}’
JSTL
- JSP에서 동작하는 새로운 태그들의 묶음
- 자바 문법보다 간결하게 제어문, 반복문, 선언문 등을 처리, 확장 가능