spring

[Spring MVC 1편] 서블릿, JSP, MVC 패턴

kimkim615 2024. 8. 7. 02:57

회원 관리 웹 애플리케이션 요구사항

서블릿으로 만들고, 서블릿을 개선한 JSP로 만들고, JSP를 개선한 MVC 패턴으로 만들어볼 것이다.

회원정보

이름 'username'

나이 'age'

기능 요구사항

회원 저장

회원 목록 조회

 

hello/servlet/domain/member/Member.class

id, username, age 필드 선언한다. id의 경우, 데이터베이스에 저장하면 발급이 된다.

 

hello/servlet/domain/member/MemberRepository.class

여기서 repository란 엔티티에 의해 생성된 데이터베이스 테이블에 접근하는 메서드들을 사용하기 위한 인터페이스이다

1. save

2. findById

3. findAll

return new ArrayList<>(store.values));    ->  store에 있는 모든 값들을 다 꺼내서 새로운 ArrayList에 넘겨준다

이유는 store에 있는 value들을 건드리고싶지 않기때문이다.

4. clearStore

 

서블릿으로 회원 관리 웹 애플리케이션 만들기

hello/servlet/web/servlet/MemberFormServlet.class

싱글톤이라서 MemberRepository.getInstance()로 가지고온다. 

http 응답으로 html이 나가므로 content body를 잡아주고 encoding 설정해줌

 

서블릿으로 하면 PrintWriter w = response.getWriter(); w.write( ) 이런걸로

자바 코드로 다 더해야되기때문에 불편하다.

 

hello/servlet/web/servlet/MemberSaveServlet.class

저장하려면 MemberRepository 필요

request.getParameter로 이름,나이 꺼냄

 

hello/servlet/web/servlet/MemberListServlet.class

List<Member> members = memberRepository.findAll(); 로 데이터 꺼낸다음에

응답 html 만든다.

 

결론...

서블릿은 html 만드는 방식이 정말 별로다

그래서 템플릿 엔진을 사용한다. html에다가 자바 코드를 넣는 방식

템플릿 엔진을 사용하면 HTML 문서에서 필요한 곳만 코드를 적용해서 동적으로 변경할 수 있음 

템플릿 엔진에는 JSP, Thymeleaf가 있음

 

JSP로 회원 관리 웹 애플리케이션 만들기

webapp/jsp/members/new-form.jsp

<%@ page contentType~~~ 이러한 코드는 이게 jsp 파일이라는걸 알려주는거

 

webapp/jsp/members/save.jsp

비즈니스 로직은 서블릿이랑 같음

<%    %> 사이에 자바 코드를 넣는다

 

webapp/jsp/members.jsp

List<Member> members = memberRepository.findAll()

 

회원등록 폼 JSP를 보면 첫 줄 제외하고 HTML랑 완전히 똑같음

JSP는 서버 내부에서 서블릿으로 변환되는데, 서블릿의 MemberFormServlet이랑 거의 비슷하게 변환됨

 

서블릿과 JSP의 한계

서블릿으로 개발하면 View 화면을 위한 HTML을 만드는 작업이 자바코드랑 섞여서 지저분하다.

JSP는 뷰를 생성하는 HTML을 깔끔하게 작업하고 중간중간 동적으로 변경이 필요한 부분만 자바 코드를 적용했다.

그치만 JSP도 문제가 있다

회원저장JSP를 보면, 코드 절반은 회원 저장을 위한 비즈니스 로직이고 나머지 절반만 뷰 영역이다

그리고 다양한 코드 모두가 JSP에 노출되어있고 JSP가 많은 역할을 한다.

 

그니까 비즈니스 로직은 서블릿처럼 다른곳에서 처리하고, JSP는 HTML로 View를 그리는 일에 집중하도록 하자

-> MVC 패턴의 등장

 

MVC 패턴 -개요

하나의 서블릿이나 JSP만으로 비즈니스 로직, 뷰 렌더링까지 모두 처리시 너무 많은 역할을 하며 유지보수가 어렵다.
그리고 UI를 일부 수정하는일과 비즈니스 로직을 수정하는 일은 서로 영향을 주지않으므로 변경의 라이프 사이클이 다르므로 유지보수가 어렵다.
 
그래서 하나의 서블릿이나 JSP로 처리하던 것을 컨트롤러와 뷰라는 영역으로 서로 역할을 나눈 것을 MVC 패턴이라고 한다.

 
고객이 요청을 하면 컨트롤러는 HTTP 요청이 제대로 맞는지 파라미터를 검증하고 로직이 잘 맞으면,
서비스나 리포지토리를 호출해서 데이터를 저장하거나 상품을 주문하거나 하는 로직을 실행한다.
그리고나서 잘되었는지 안되었는지 결과를 받고 모델에 전달한다. 
그리고 뷰에 전달해서 모델에서 값을 꺼내서 출력해준다.
 

MVC 패턴- 적용

서블릿을 컨트롤러로 사용하고, JSP를 뷰로 사용해서 MVC 패턴을 적용해보자

Model은 HttpServletRequest 객체를 사용한다. request는 내부에 데이터 저장소를 가지고 있는데,

request.setAttribute(), request.getAttribute를 사용해서 데이터 보관과 조회가 가능하다.

 

hello/servlet/web/servletmvc/MvcMemberFormServlet.class

controller가 되는 부분이다

 

controller를 거쳐서 view로 들어가야된다

viewPath = "/WEB-INF/views/new-form.jsp

getRequestDispatcher(viewPath)  -> controller에서 view로 이동해야될때 사용

forward(request, response) 다른 서블릿이나 JSP으로 이동할 수 있는 기능. 서버 내부에서 다시 호출이 발생

 

webapp/WEB-INF/views/new-form.jsp

controller에서 거쳐서 불러오고싶을때는 WEB-INF 밑에 넣기. 외부에서 호출 안되게 함

form의 action에서 절대경로 (/)가 아닌 상대경로로 한다.

회원 저장의 경우 서블릿 컨트롤러가 요청정보를 받아서 파싱하고 username, age를 가져오고 멤버객체 만들어서 저장

그리고 모델에 데이터를 보관한다.

redirect vs forward

리다이렉트는 실제 클라이언트(웹 브라우저)에 응답이 나갔다가, 클라이언트가 redirect 경로로 다시 요청한다

따라서 클라이언트가 인지할 수 있고, URL 경로도 실제로 변경된다.

그러나 포워드는 서버 내부에서 일어나는 호출이기에 클라이언트가 전혀 인지하지 못한다.

 

 

 

MVC 패턴 - 한계

MVC 패턴을 적용하여서 컨트롤러의 역할과 뷰를 렌더링하는 역할을 명확히 구분 가능했다.
그러나 컨트롤러에서 중복이 많고 필요하지 않은 코드가 많이 있다.
 
단점1. 포워드 중복 - View로 이동하는 코드가 항상 중복 호출된다.
단점2. ViewPath에 중복
단점3. 사용하지 않는 코드
단점4. 공통 처리가 어렵다 - 프론트 컨트롤러 패턴을 도입해서 입구를 하나로 만드는 기능이 필요하다