Spring의 MVC 패턴 개요/적용/한계

Hansu Kim·2022년 4월 12일
0

Spring MVC

목록 보기
5/6

기존 방식의 문제점

기존 방법인 View 생성시 Servlet을 통한 처리나, jsp를 통한 처리는 아래와 같은 문제들이 존재했다.

  • Single Responsibility 원칙 위반
    • 하나의 모듈이 비지니스 로직 수행과 뷰 렌더링을 동시에 수행하게 됨.
  • Dependency Inversion 원칙 위반
    • 추상화에 의존해야하나, 비지니스 로직과 뷰 간의 의존성이 구체화되게 된다.
  • 유지보수의 어려움
    • 비지니스 로직과 UI 수정은 각각 다르게 발생할 가능성이 높으나, 추상화에 의존하지 않았기에 변경시 서로 영향을 주게되어 유지보수에 어렵다.

MVC 패턴 개요

MVC 패턴은 JSP로 처리하던 것을 Controller와 View 영역으로 서로 역할을 나눈 것이다.

Controller

  • HTTP 요청을 받는다.
  • 파라미터를 검증한다.
  • 비지니스 로직을 실행한다.
  • 뷰에 전달할 결과 데이터를 조회해서 모델에 담는다.

Model

  • View에 출력할 데이터를 담아둔다.

View

  • Model의 데이터를 기반으로 화면을 그리는 일에 집중한다.

MVC 패턴 적용

@WebServlet(name = "mvcMemberFormServlet", urlPatterns="/servlet-mvc/members/new-form")
public class MvcMemberFormServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //요청정보 받고
        String username = req.getParameter("username");
        int age = Integer.parseInt(req.getParameter("age"));

        //비지니스 로직 호출
        Member member = new Member(username, age);
        memberRepository.save(member);

        //Model에 데이터 보관
        req.setAttribute("member", member);

        String viewPath = "/WEB-INF/views/save-result.jsp";
        RequestDispatcher dispatcher = req.getRequestDispatcher(viewPath);
        dispatcher.forward(req, resp);
    }
}
  • dispatcher : Controller -> View로 넘어가기 위해 사용한다.
    • dispatcher.forward(source, destination): 다른 Servlet이나 JSP로 서버 내부적으로 호출하여 이동한다.

redirect vs forward
redirect는 클라이언트가 redirect 응답을 받기에, 해당 동작을 인지하고 있다.
forward는 서버 내부적인 동작이기에 client에서 알지 못한다.

WEB-INF
'WEB-INF' 경로 안에 JSP 파일은 외부에서 호출되지 않는다.
JSP 파일에 접근시 Controller를 통해서만 강제하기 위해 사용된다.

JSP의 Property 접근법

<ul>
    <li>id=<%=((Member)request.getAttribute("member")).getId()%></li>
    <li>username=${member.username}</li>
    <li>age=${member.age}</li>
</ul>

Servlet에서 데이터는 Object 형태로 전달되기에, request.getAttribute()를 통해 값을 꺼내야 한다.
하지만 JSP에서는 ${} 문법을 제공해줘서 ${member.username} 등과 같이 호출할 수 있고, 해당 호출시 자동으로 member.getUsername()이 호출된다

HTML Form 태그의 상대경로 사용법

<form action="save" method="post">
	username: <input type="text" name="username" /> 
  	age: <input type="text" name="age" /> 
  	<button type="submit">전송</button>
</form>

action="save" 지정시, 현재 계층 경로의 상대 경로로 url이 지정된다.
만약, action="/save" 지정시, URL:PORT/save 로 URL이 지정된다.
상대경로 사용시 재사용성이 높으나, 유지보수의 어려움으로 대부분의 경우 절대경로를 기입해주는 것이 좋다.

0개의 댓글