Free Lines Arrow
본문 바로가기
Spring/spring framework 구현 스터디

[Spring] MVC 패턴 적용

by skahn1215 2021. 10. 17.
728x90
반응형

MVC 패턴 적용

  • 앞서 JSP 서블릿에서 뷰와 서블릿(컨트롤러) 를 분리해본다.
  • 그렇게 MVC 패턴으로 프로젝트를 변경해 본다.

 

MVC 패턴 컨트롤러

  • 컨트롤러를 도입하면서 모든 요청은 컨트롤러를 먼저 지나가야한다.
    간력하게 보면 다음과 같다.
  • 서비스로직 DB 조회 등 더 필요한게 있지만 현재 예제에서는 뷰만 분리하는 개념을 위주로 본다.

 

 

 

기본문법

@WebServlet(name = "servlet pattern", urlPatterns = "url path")

  •  서블릿 어노테이션 이다.
  • name
      - 서블릿 이름정의
  • uslPatterns
     - 어떤 요청을 처리할 것인지 url 패턴 선언

RequestDispatcher dispatcher = req.getRequestDispatcher("path");

dispatcher.forward(req,resp)

  • dispatcher 를 가져온뒤 어떤 패스로 넘길지 선언한다.
  • forward 를 통해 해당 JSP 에 req 와 resp를 넘긴다.
  • 참고사항: redirect 가 아니라 foward 방식이다.
    - redirect: 웹서버에 응답을 한뒤 다시 돌아갈 url 을 요청한다.
    - foward: 서버 내부에서 일어나는 호출이기 때문에 클라이언트가 인지하지 못한다.

 

 

회원폼을 호출하는 controller(servlet) class

  • /servlet-mvc/members/new-form 요청이 들어오면 해당 컨트롤러에서 처리한다.
  • 그리고 "/WEB-INF/views/name-form.jsp" 로 request 와 response 를 넘긴다.
@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 viewPath = "/WEB-INF/views/name-form.jsp";
        
        // 컨트롤러에서 뷰로 이동하기 위해 사용
        RequestDispatcher dispatcher = req.getRequestDispatcher(viewPath);

        // jsp 를 찾아서 req, rsp을 넘겨준다.
        // 다른 서블릿이나 JSP로 이동할 수 있는 기능이다.
        // 리다이렉트가 아니다.
        // 서버안에서 내부적으로 호출이 발생한다.
        dispatcher.forward(req,resp);
    }
}

 

 

 

회원 저장 jsp

  • action 에 save 라고되어 있는데 이것은 상대경로이다.
  • 상대경로: 현재 URL이 속한 계층 경로 + save가 호출된다
    - 현재경로: /servlet-mvc/members/
    - 상대경로 호출시: /servlet-mvc/members/save
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
 <title>Title</title>
</head>
<body>
<%--save 는 상대경로이다. --%>
<form action="save" method="post">
     username: <input type="text" name="username" />
     age: <input type="text" name="age" />
 <button type="submit">전송</button>
</form>
</body>
</html>

 

 

 

회원저장 controller(servlet) class

  • req.setAttribute("member",member);
     - setAttribute 로 key 와 value 형식으로 데이터를 모델에 저장 할 수 있다.
     - 그렇게 되면 foward 할때 모델도 같이 넘겨준다.
@WebServlet(name = "mvcMemberSaveServlet", urlPatterns = "/servlet-mvc/members/save")
public class MvcMemberSaveServlet extends HttpServlet {
    private MemberRepository memberRepository = MemberRepository.getInstance();

    @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);
    }
}

 

 

 

저장된 회원을 출력하는 jsp

  • 앞서 넘겨준 모델을 사용하여 화면에 뿌려주었다.
  • 참고사항: request, response가 없는건 굳이 선언을 해주지 않아도 jsp가 알아서 지원한다.
  • 그렇기 때문에 그냥 사용할수 있다.
  • 또한 모델도 따로 선언없이 앞에서 setAttribute 로 넘겨준 모델을 그냥 사용하면된다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
 <title>Title</title>
</head>
<body>

<%-- 코드 개선전
<ul>
    <li> id=<%=((Member)request.getAttribute("member")).getId()%> </li>
    <li> username=<%=((Member)request.getAttribute("member")).getUsername()%> </li>
    <li> age=<%=((Member)request.getAttribute("member")).getAge()%> </li>
</ul>
 --%>

 <%-- 코드 개선후 프로퍼티 접근법 자돟으로 get set 이 동작한다.--%>
 <ul>
     <li> id=${member.id} </li>
     <li> username=${member.username}  </li>
     <li> age=${member.age} </li>
 </ul>

<a href="/index.html">메인</a>
</body>
</html>

 

 

 

MVC 의 한계점

  • 일단 뷰와 컨트롤러를 분리하였다.
  • 그렇기 때문에 각자의 역할에 집중할수 있게 되었다.
  • 하지만 다음과 같은 한계 점과 단점이 있다.

 

foward 중복

아래 코드를 항상 호출해야된다.

RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);

 

 

미사용 코드 존재

request, response를 사용할때도 있고 사용하지 않는 경우도 있다.

HttpServletRequest request, HttpServletResponse response

 

 

 

공통처리가 어렵다.

  • 컨트롤러에서 공통으로 처리해야될 문제들이 반드시 있는데 
  • 현재는 공통으로 처리하기가 쉽지않다.
  • 그렇기 때문에 다음에는 프론트 컨트롤러를 이용하여 공통으로 처리될 부분이나 미리 처리해야될 부분을 
  • 담당하는 컨트롤러를 만들어 본다.

 

 

 

 

 

참고

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/lecture/71186?tab=curriculum 

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 학습 페이지

지식을 나누면 반드시 나에게 돌아옵니다. 인프런을 통해 나의 지식에 가치를 부여하세요....

www.inflearn.com

 

728x90
반응형

댓글