728x90
강의 요약
- 웹 애플리케이션을 Servlet / 템플릿 / MVC 세 방법으로 개발해보자.
- Servelt 개발 → 템플릿(JSP) 개발 → MVC 패턴
- Servlet은 자바 코드에 HTML이 있어 불편하다.
- 템플릿은 HTML 문서에 서비스 로직 등이 있어 불편하다.
- 그래서 등장한게 MVC 패턴으로 각 역할을 Model, View, Controller로 나눈다.
회원 관리 앱 애플리케이션 요구 사항
기능 요구사항
- 회원 저장
- 회원 목록 조회
회원( Member )도메인 모델
@Getter @Setter
public class Member {
private Long id;
private String username;
private int age;
public Member () {
}
public Member(String username, int age) {
this.username = username;
this.age = age;
}
}
회원 저장소
package com.inflearn.hello.servlet.domain.member;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 동시성 문제가 고려되어 있지 않음, 실무에서는 ConcurrentHashMap, AtomicLong 사용 고려
* */
public class MemberRepository {
private static Map<Long, Member> store = new HashMap<>();
private static long sequence = 0L;
// 싱글톤 패턴은 전체 시스템에서 하나의 인스턴스만 생성하도록 보장하고,
// 이 인스턴스에 전역적으로 접근할 수 있도록 하는 디자인 패턴입니다.
private static final MemberRepository instance = new MemberRepository();
public MemberRepository() {
}
public static MemberRepository getInstance() {
return instance;
}
public Member save(Member member) {
member.setId(++sequence);
store.put(member.getId(), member);
return member;
}
public Member findById(Long id) {
return store.get(id);
}
public List<Member> findAll() {
return new ArrayList<>(store.values());
}
public void clearStore() {
store.clear();
}
}
서블릿으로 회원 관리 웹 애플리케이션 만들기
- 서블릿과 자바코드만으로 HTML을 만들었다.
- 서블릿으로 동적으로 원하는 HTML을 마음껏 만들 수 있는데 정적인 HTML 문서라면 회원의 저장 결과 또는 회원 목록같은 동적인 HTML은 불가능하다.
- 자바 코드에 HTML을 넣는 것은 매우 불편하고 비효율적이다.(Fig 2)
템플릿 엔진
- HTML 문서에서 동적으로 변경해야 하는 부분만 자바코드를 넣을 수 있으면 편리할 수 있다.
- 그래서 나온 것이 템플릿 엔진이다.
- 템플릿 엔진으로 HTML 문서 내부에서 필요한 코드를 적용해서 동적으로 변경 가능하다.
- JSP, Thymeleaf 등이 있다.
JSP 페이지 만들기
- <% %>: 자바 코드를 작성할 수 있다.
자바 코드에서 작성한 서비스 부분을 JSP 템플릿을 사용해서 HTML 문서에 작성할 수 있다.
⭐ 비지니스 부분과 뷰 렌더링 부분이 섞여 있다. ⭐
회원 저장 JSP
<%@ page import="hello.servlet.domain.member.Member" %>
<%@ page import="hello.servlet.domain.member.MemberRepository" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
// request, response 사용 가능
// jsp는 나중에 servlet으로 변환된다.
MemberRepository memberRepository = MemberRepository.getInstance();
System.out.println("MemberSaveServlet.service");
String userName = request.getParameter("userName");
int age = Integer.parseInt(request.getParameter("age"));
Member member = new Member(userName, age);
memberRepository.save(member);
%>
<html>
<head>
<title>Title</title>
</head>
<body>
<li>id=<%=member.getId()%></li>
<li>username=<%=member.getUsername()%></li>
<li>age=<%=member.getAge()%></li>
<a href="/index.html">메인</a>
</body>
</html>
회원 목록 JSP
<%@ page import="java.util.List" %>
<%@ page import="hello.servlet.domain.member.Member" %>
<%@ page import="hello.servlet.domain.member.MemberRepository" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
MemberRepository memberRepository = MemberRepository.getInstance();
List<Member> memberList = memberRepository.findAll();
%>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/index.html">메인</a>
<table>
<thead>
<th>id</th>
<th>username</th>
<th>age</th>
</thead>
<tbody>
<%
for (Member member : memberList) {
out.write(" <tr>");
out.write(" <td>" + member.getId() + "</td>");
out.write(" <td>" + member.getUsername() + "</td>");
out.write(" <td>" + member.getAge() + "</td>");
out.write(" </tr>");
}
%>
</tbody>
</table>
</body>
</html>
서블릿과 JSP 한계
- 서블릿으로 개발할 때는 뷰(View) 화면을 위한 HTML을 만드는 작업이 자바 코드에 섞여서 지저분하고 복잡하다.
- JSP를 사용해서 HTML 작업을 깔끔하게 정리할 수 있지만, JAVA 코드부터 데이터 조회 등 여러 기능을 담당.
MVC 패턴
MVC 등장
- 비즈니스 로직은 서블릿 처럼 다른 곳에서 처리하고, JSP는 목적에 맞게 HTML로 화면(View)을 그리는 일에 집중.
Model-View-Controller
- 컨트롤러(Controller): HTTP 요청을 받아서 파라미터를 검증하고 비즈니스 로직을 실행한다. 그리고 뷰에 전달할 결과를 조회해서 모델에 담는다.
- 모델(Model): 뷰에 출력할 데이터를 담아둔다. 뷰가 필요한 데이터를 모두 모델에 담아서 전달해주는 덕분에 뷰는 비즈니스 로직이나 데이터 접근을 몰라도 되고, 화면을 렌더링 하는 일에 집중할 수 있다.
- 뷰(View): 모델에 담겨있는 데이터를 사용해서 화면을 그리는 일에 집중한다. 여기서는 HTML을 생성하는 부분을 말한다.
MVC 패턴 1탄
- 컨트롤러에 비즈니스 로직을 넣을 수 있다.
- 그러면, 컨트롤러가 많은 역할을 맡게 된다.
MVC 패턴 2탄
- 비즈니스 로직은 서비스(Service)라는 계층을 별도로 만들어서 처리한다.
MVC 패턴 - 적용
WEB-INF
- WAS에서 내부적으로 WEB-INF 폴더 내부에 JSP 파일이 있으면 직접 호출할 수 없다.
redirect vs forward
- 리다이렉트(redirect)는 실제 클라이언트(웹 브라우저)에 응답이 갔다가, 클라이언트가 redirect 경로로 다시 요청한다.
- 따라서 클라이언트가 인지할 수 있고, URL 경로도 실제로 변경된다.
- 포워드(forward)는 서버 내부에서 일어나는 호출이기 때문에 클라이언트가 전혀 인지하지 못한다.
절대경로 vs 상대경로
- 절대경로: /save
- http://localhost:8080/save
- 상대경로: save
- http://localhost:8080/{현재 경로}/save
MVC 패턴 - 한계
MVC 패턴을 적용한 덕분에 컨트롤러의 역할과 뷰를 렌더링하는 역할을 명확하게 구분할 수 있다.
한계
- 포워드 중복
- ViewPath 중복
- 사용하지 않는 코드
문제
- 공동 처리가 어렵다
- 기능이 복잡해질수록 컨트롤러에서 공통으로 처리해야 하는 부분이 점점 더 많이 증가할 것이다.
- 단순히 공통 기능을 메서드로 뽑으면 될 것 같지만, 해당 메서드를 항상 호출해야하고, 실수로 호출하지 않으면 문제가 된다.
결론
- 수문장 역할을하는 프론트 컨트롤러(Front Controller)가필요하다.
(입구를 하나로) - 필터(Filter)랑은 다르다..!!
'온라인 강의 > Spring Framework' 카테고리의 다른 글
[스프링 MVC 1편] 웹 페이지 만들기 (0) | 2024.06.09 |
---|---|
[스프링 MVC 1편] 구조 이해 (0) | 2024.05.25 |
[스프링 MVC 1편] MVC 프레임워크 만들기 (0) | 2024.05.19 |
[스프링 MVC 1편] 서블릿 (0) | 2024.05.08 |
[스프링 MVC 1편] 웹 애플리케이션 이해 (1) | 2024.05.07 |