김영한 님의 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 강의를 보고 작성한 내용입니다.
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
@WebServlet
어노테이션을 통해 urlPatterns 지정
HttpServletRequest
객체와 메서드를 이용하여 요청 메세지 파싱
HttpServletResponse
객체와 메서드를 이용하여 응답 메세지 헤더, body를 작성
setXXX()
를 이용해서 헤더 작성
response.getWriter().write
를 이용해서 body 작성
동적 HTML 작성이 가능하지만 자바 코드로 HTML을 작성해야하기 때문에 불편함
writer.write("<li>id="+member.getId()+"</li>\n")
HTML 문서에서 필요한 곳만 자바 코드를 적용해서 동적으로 변경이 가능하도록 하는 것이 바로 템플릿 엔진
템플릿 엔진 종류 : JSP, Thymeleaf, Freemarker, Velocity
JSP를 사용하려면 아래 라이브러리를 추가해야함
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
implementation 'javax.servlet:jstl'
JSP 사용
<% %>
사이에 자바 코드를 입력할 수 있다
<%= %>
사이에 자바 코드를 출력할 수 있다
JSP도 서버 내부에서 servlet으로 변환되기 때문에 JSP 파일에서 request, response 사용 가능
서블릿과 JSP
서블릿은 자바 코드 내부에 HTML 태그들을 사용
JSP는 HTML 문서 내부에 필요한 부분만 자바 코드로 작성
결국 서블릿과 JSP 모두 자바 코드와 HTML 코드가 한 파일 내에 섞여있음
➡️ MVC 패턴 등장
MVC ( Model View Controller ) : 하나의 서블릿이나, JSP로 처리하던 것을 로직을 처리하는 컨트롤러(Controller)와 화면을 그리는 뷰(View)라는 영역으로 서로 역할을 나눈 것
Controller
HTTP 요청을 받아서 파라미터를 검증하고, 비지니스 로직을 실행
뷰에 전달할 결과 데이터를 조회해서 모델에 담는다
Model
뷰에 출력할 데이터를 담아둔다
뷰가 필요한 데이터를 모두 모델에 담아서 전달해주는 덕분에 뷰는 비지니스 로직이나 데이터 접근을 몰라도 되고, 화면을 렌더링 하는 일에 집중할 수 있다
View
모델에 담겨있는 데이터를 사용해서 화면을 그린다
HTML을 생성하는 부분
Service 계층 : Controller가 너무 많은 역할을 수행하기 때문에 Service 계층을 만들어 비지니스 로직을 처리하도록 하고 Controller는 Service 계층을 호출하는 역할을 담당
서블릿은 로직을 실행하는데 최적화 → Controller 역할
JSP는 화면을 랜더링 하는데 최적화 → View 역할
HttpServletRequest
→ Model 역할
request는 내부에 데이터 저장소가 있음
setAttribute()
, getAttribute()
를 사용해 데이터를 저장 및 조회
JSP 파일에서 ${}
를 사용해서 담긴 데이터를 조회 가능
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
Member member = new Member(username, age);
System.out.println("member = " + member);
memberRepository.save(member);
// Model에 데이터를 보관
request.setAttribute("member", member);
String viewPath = "/WEB-INF/views/save-result.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
/WEB-INF
이 경로 안에 있으면 외부에서 JSP를 직접 호출할 수 없다
항상 Controller를 통해 호출해야함
request.getRequestDispatcher("경로")
Controller에서 View로 이동할 때 사용
경로는 JSP가 위치한 경로 ( View 경로 )
dispatcher.forward(request, response)
서블릿에서 JSP를 호출 ( Controller에서 View를 호출 )
다른 서블릿이나 JSP로 이동할 수 있는 기능
서버 내부에서 호출이 발생하는 것임 ( 클라이언트에게 전달되었다가 변경되는 리다이렉트가 아님 )
redirect
클라이언트에 응답이 나갔다가, 클라이언트가 redirect 경로로 다시 요청
호출이 두 번 이루어짐
클라이언트가 인지할 수 있고, URL 경로도 실제로 변경된다
foward
Controller에서 View로 이동하는 forward()가 모든 Controller에 중복 작성
다른 템플릿 엔진으로 변경하게 되면 전체 코드를 변경해야함
공통 처리가 어렵다
이를 해결하기 위해 Controller 호출 전에 공통 기능을 처리해야한다
➡️ Front Controller 패턴