Servlet이나 JSP만으로 비지니스 로직과 View Rendering 까지 모두 처리하면
너무 많은 역할을 하게 되고, 유지보수가 굉장히 어려워져서(책임이 너무 많음) 고안된 패턴이다.Web Application은 일반적으로 MVC(Model View Controller) 패턴을 사용한다.
@WebServlet("/hello-world")
public class HelloWorldServlet extends HttpServlet {
// User 저장소
private UserRepository repository = new UserRepository();
public HelloWorldServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
try {
// 비지니스 로직을 처리하는 코드
// 파라미터 조회
String userIdParam = request.getParameter("userId");
Long userId = null;
if (userIdParam != null) {
userId = Long.parseLong(userIdParam);
}
// 회원 조회
String userInfo = repository.findById(userId);
// 화면을 그리는 코드 START
out.println("<h1>Hello World!</h1>");
out.println("<div>조회한 회원의 정보: " + userInfo + "</div>");
// 화면을 그리는 코드 END
} catch (NumberFormatException e) {
// parsing 에러가 발생한 경우
out.println("<div>Invalid user ID format</div>");
} finally {
out.close();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}


HttpServletRequest , HttpServletResponse 객체를 생성함service() 메서드를 호출한 뒤 브라우저의 요청 Method에 따라 doGet() 혹은 doPost() 등의 메서드를 호출한다.HttpServletResponse 객체에 응답을 담아 Client(브라우저)에 반환HttpServletRequest , HttpServletResponse 객체를 소멸한다.<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<!-- HTML 코드... -->
<!-- <%...%> 영역에는 Java 코드를 사용할 수 있다. -->
<%
// 게시글 저장소 싱글톤으로 인스턴스 생성
BoardRepository boardRepository = BoardRepository.getInstance();
// 게시글 제목, 내용
String title = request.getParameter("title");
String content = request.getParameter("content");
// 게시글 객체 생성
Board board = new Baord(title, content);
// 게시글 객체 저장
repository.save(board);
%>
<div>
ID : <input type ="text" name = "id" value="<%=id %>">
</div>
<!-- JSP 코드... -->
<!-- HTML 코드... -->
<jsp:forward page="<%=url %>" />
</body>
</html>
View 가 분리되었음
하나의 Servlet이나 JSP로 처리하던 것들을
Model,View,Controller영역으로 나눈 것
View 의 수정 원인은 별개로 발생비즈니스 로직 과 View 을 완전히 독립적으로 분리
Controller 가 비즈니스 로직을 처리함Controller 가 처리한 비즈니스 로직의 결과를 Model 에 전달Model 은 데이터를 임시로 저장하고 있음View 는 필요한 데이터를 Model 에서 참조해서 사용Layered Architecture 를 통해 Controller 의 역할을 더욱 세분화MVC 패턴을 적용 후 View의 역할은 필요한 데이터를 Model 에서 참조하여 화면을 그리는 역할만 수행하면 된다. 하지만 Controller에 해당하는 부분은 여전히 문제를 가지고 있다.

dispatcher.forward(request, response)String path= “/WEB-INF/views/new-form.jsp”HttpServletResponse 객체를 사용하는 경우가 적다.HttpServletRequest 와 HttpServletResponse 는 Test 코드를 작성하기도 매우 힘들다.모든 컨트롤러에서 공통으로 적용되는 기능을 뜻함
ex) Log 출력, 인증, 인가 등

각각의 컨트롤러마다 공통적으로 처리해야하는 코드가 포함되어야 함
Q. 공통 기능을 Method로 분리해서 각각의 컨트롤러에서 사용하면 되는 거 아닌가?
A. 공통 기능으로 만들어놓은 Method 또한 항상 중복적으로 호출이 필요합니다.
또한, 사람인 개발자가 작업하다보면 Method를 호출하는 일을 깜빡 할수도 있고 Method가 많아지면 많아질수록 Controller의 책임이 점점 커지겠죠?Method를 분리하여도 여전히 해결하지 못하는 문제점으로 남습니다.
Servlet(Controller)이 호출되기 전, 공통 기능을 하나의 Servlet에서 처리해주는 패턴
프론트 컨트롤러(Servlet) 하나에 모든 클라이언트측 요청이 들어온다.

HttpServlet 을 상속받거나, @WebServlet 을 사용하지 않아도 됨
다양한 컨트롤러(이하 Handler)를 유연하게 만들기위해 어댑터 패턴을 도입하게 되었다.
- 컨트롤러들은 동일한 인터페이스를 구현하도록 한다.
- 해당 인터페이스와 공통 로직 사이에 어댑터를 두어 유연하게 만든다.
- 서로 다른 인터페이스를 갖는 두 클래스를 연결해주는 패턴이다.

Spring 입문 - 3주차