✅ 스프링 MVC ✅ 스프링 부트 ✅ Spring WebFlux ✅ JSP ✅ Freemarker ✅ Velocity ✅ Thymeleaf
클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술
@WebServlet(name = "memberListServlet", urlPatterns = "/servlet/members")
public class MemberListServlet extends HttpServlet {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
List<Member> members = memberRepository.findAll();
PrintWriter w = response.getWriter();
w.write("<html>");
w.write("<head>");
w.write(" <meta charset=\"UTF-8\">");
w.write(" <title>Title</title>");
w.write("</head>");
w.write("<body>");
w.write("<a href=\"/index.html\">메인</a>");
w.write("<table>");
w.write(" <thead>");
w.write(" <th>id</th>");
w.write(" <th>username</th>");
w.write(" <th>age</th>");
w.write(" </thead>");
w.write(" <tbody>");
for (Member member : members) {
w.write(" <tr>");
w.write(" <td>" + member.getId() + "</td>");
w.write(" <td>" + member.getUsername() + "</td>");
w.write(" <td>" + member.getAge() + "</td>");
w.write(" </tr>");
}
w.write(" </tbody>");
w.write("</table>");
w.write("</body>");
w.write("</html>");
}
}
HTML 생성이 어려움
HTML 생성은 편리하지만, 비즈니스 로직까지 너무 많은 역할 담당
<%@ page import="java.util.List" %>
<%@ page import="hello.servlet.domain.member.MemberRepository" %>
<%@ page import="hello.servlet.domain.member.Member" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
MemberRepository memberRepository = MemberRepository.getInstance();
List<Member> members = 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 : members) {
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>
모델, 뷰 컨트롤러로 역할을 나누어 개발
공통 처리가 어렵다.
기능이 복잡해질수록 컨트롤러에서 공통으로 처리해야 하는 부분이 더 많아진다.
단순히 공통 기능을 메서드로 뽑으면 될 것 같지만, 결과적으로 해당 메서드를 항상 호출해야 하고, 실수로 호출하지 않으면 문제된다.
그리고 호출하는 것 자체도 중복이다.
👉 이 문제를 해결하려면 컨트롤러 호출 전에 먼저 공통 기능을 처리해야 한다.
이것을 가능하게 하는 것이 프론트 컨트롤러(Front Controller) 패턴
이며 스프링 MVC의 핵심도 바로 이 프론트 컨트롤러에 있다.
MVC 패턴 자동화, 복잡한 웹 기술을 편리하게 사용할 수 있는 다양한 기능 지원
애노테이션 기반의 스프링 MVC 등장
스프링 부트는 서버를 내장하여 빌드 배포 단순화
👉 Web Servlet
👉 Web Reactive
- 비동기 넌 블러킹 처리
블로킹 Vs 논블로킹, 동기 Vs 비동기- 최소 쓰레드로 최대 성능 - 쓰레드 컨텍스트 스위칭 비용 효율화
- 함수형 스타일로 개발 - 동시처리 코드 효율화
- 서블릿 기술을 사용하지 않음 👉 Netty 사용
Netty 기본 개념
속도 느림, 기능 부족
속도 문제 해결, 다양한 기능
내추럴 템플릿: HTML의 모양을 유지하면서 뷰 템플릿 적용 가능