본문 바로가기
Spring/스프링 MVC

[스프링 MVC 1편] 4 - (2) 프론트 컨트롤러 - v2

by Poorm 푸름 2023. 11. 9.

 *  스프링 입문 = window, 스프링 MVC 1편 = Mac 으로 진행합니다

 *  진도 : 섹션4 - (1) ~ (3)

 *          : 자바 클래스명,         : 코드,         : 단축키

 

1. 프론트 컨트롤러_구현 2단계 (뷰 깔끔하게 처리)

 

  • 매번 반복해서 사용했던 뷰 영역 코드를 간편하게 바꿔보자!
더보기

< 뷰 영역 코드 >

 

  String viewPath = "/WEB-INF/views/new-form.jsp";
  RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
  dispatcher.forward(request, response);

 

 

1) My View 클래스 만들자!
 [ src - java - hello.servlet - web - frontcontroller - MyView ]

public class MyView {
    private  String viewPath;

    public MyView(String viewPath) {
        this.viewPath = viewPath;
    }

    public void render(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);
    }
}

 

  • private String viewPath

  • 생성자 만들기
    • command + n - constructor 클릭 - Ok 클릭

  • 렌더링 public void render ~
    • v1 클래스들과 코드는 똑같고 이름만 public void render 로 다를 뿐이다 
      public void process  public void render

  • request.getRequestDispatcher (option + command + v)

  • dispatcher.forward() : 다른 서블릿이나 JSP로 이동할 수 있는 기능(서버 내부에서 호출)

 

2) 인터페이스를 만들자!
 [ src - java - hello.servlet - web - frontcontroller .v2 - ControllerV2 ]
 

  • 서블릿과 비슷한 모양의 MyView를 반환하는 인터페이스
    • 서블릿과 코드는 똑같고(서비스 메서드 부분) 단, 이름만 MyView process로 다를 뿐이다 
      protected void service  MyView process
  • 프론트 컨트롤러는 이 인터페이스를 호출해서 로직의 일관성을 가져갈 수 있다
public interface ControllerV2 {
    MyView process(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException;
}

 

 

 3) 회원 등록 컨트롤러
 [ src - java - hello .servlet - web - frontcontroller .v2 - controller - MemberFormControllerV2 ]

public class MemberFormControllerV2 implements ControllerV2 {
    @Override
    public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        return new MyView("/WEB-INF/views/new-form.jsp");
    }
}

 

  • 상속 implements ControllerV2 ~ @Override (option + enter)

    implements란
     인터페이스 구현했을 때 사용되며 부모 객체에서 변수나 메소드를 선언만 하고 기능적인 구현은 하지 않고 
    자식클래스에서 이때 선언된 메소드를 오버라이딩으로 구현한다
    (다중상속을 하기 위해 implments 사용)

    • extends 와 implement 의 차이
      1. extends
        부모에서 선언 / 정의를 모두하며 자식은 메소드 / 변수를 그대로 사용할 수 있음

      2. implements (interface 구현)
        부모 객체는 선언만 하며 정의(내용)은 자식에서 오버라이딩 (재정의)해서 사용

  • 뷰 영역 수정 return new MyView("// JSP 경로 //") 

    • 또 다른 작성법
      • new MyView("// JSP 경로 //"); (option + command +v) 
      • return myView; (option + command + n)
      • 위 과정 진행하면 한줄로 합쳐진다

 

 4) 회원 저장 컨트롤러
[ src - java - hello .servlet - web - frontcontroller .v2 - controller - MemberSaveControllerV2 ]

public class MemberSaveControllerV2 implements ControllerV2 {

    private MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    public MyView process(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); 
        memberRepository.save(member);

        request.setAttribute("member", member);

        return new MyView("/WEB-INF/views/save-result.jsp");

    }
}

 

  • 상속 implements ControllerV2 ~ @Override (option + enter)

    implements란
     인터페이스 구현했을 때 사용되며 부모 객체에서 변수나 메소드를 선언만 하고 기능적인 구현은 하지 않고 
    자식클래스에서 이때 선언된 메소드를 오버라이딩으로 구현한다
    (다중상속을 하기 위해 implments 사용)

    • extends 와 implement 의 차이
      1. extends
        부모에서 선언 / 정의를 모두하며 자식은 메소드 / 변수를 그대로 사용할 수 있음

      2. implements (interface 구현)
        부모 객체는 선언만 하며 정의(내용)은 자식에서 오버라이딩 (재정의)해서 사용

  • 나머지 코드 (서블릿 방식 때랑 같음)

    • 리포지토리 가져오기 private MemberRepository.getInstance
    • form data 값 읽어오기request.getParameter()
    • Member 객체 생성
    • 모델에 데이터 담기request.setAttribute()

  • 뷰 영역 수정 return new MyView("// JSP 경로 //") 

    • 또 다른 작성법
      • new MyView("// JSP 경로 //"); (option + command +v) 
      • return myView; (option + command + n)
      • 위 과정 진행하면 한줄로 합쳐진다

 

 5) 회원 목록 컨트롤러
 [ src - java - hello .servlet - web - frontcontroller .v2 - controller - MemberListControllerV2 ]

public class MemberListControllerV2 implements ControllerV2 {

    private MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        List<Member> members = memberRepository.findAll();

        request.setAttribute("members", members);

        return new MyView("/WEB-INF/views/members.jsp");
    }
}

 

  • 상속 implements ControllerV2 ~ @Override (option + enter)

    implements란
     인터페이스 구현했을 때 사용되며 부모 객체에서 변수나 메소드를 선언만 하고 기능적인 구현은 하지 않고 
    자식클래스에서 이때 선언된 메소드를 오버라이딩으로 구현한다
    (다중상속을 하기 위해 implments 사용)

    • extends 와 implement 의 차이
      1. extends
        부모에서 선언 / 정의를 모두하며 자식은 메소드 / 변수를 그대로 사용할 수 있음

      2. implements (interface 구현)
        부모 객체는 선언만 하며 정의(내용)은 자식에서 오버라이딩 (재정의)해서 사용

  • 나머지 코드 (서블릿 방식 때랑 같음)

    • 리포지토리 가져오기 private MemberRepository.getInstance
    • 데이터 조회 memberRepository.findAll() (option + command + v)
    • 모델에 데이터 담기request.setAttribute()

  • 뷰 영역 수정 return new MyView("// JSP 경로 //") 

    • 또 다른 작성법
      • new MyView("// JSP 경로 //"); (option + command +v) 
      • return myView; (option + command + n)
      • 위 과정 진행하면 한줄로 합쳐진다

 

 5) 프론트 컨트롤러 만들기!!
[ src - java - hello.servlet - web - frontcontroller. v2 - FrontControllerServletV2 ]

@WebServlet(name = "frontControllerServiceV2", urlPatterns = "/front-controller/v2/*")
public class FrontControllerServiceV2 extends HttpServlet {

    private Map<String, ControllerV2> controllerMap = new HashMap<>();

    public FrontControllerServiceV2() {
        controllerMap.put("/front-controller/v2/members/new-form", new MemberFormControllerV2());
        controllerMap.put("/front-controller/v2/members/save", new MemberSaveControllerV2());
        controllerMap.put("/front-controller/v2/members", new MemberListControllerV2());
    }

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String requestURI = request.getRequestURI();
        ControllerV2 controller = controllerMap.get(requestURI);
        if(controller==null){
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        MyView view = controller.process(request, response);
        view.render(request, response);
    }
}
  • 프론트 컨트롤러는 꼭 서블릿으로 작성한다!

  • 상속 extends HttpServlet
  • 서블릿 생성@WebServlet
    • /* 표시는 해당 위치에 어떤 url 이 들어와도 서블릿 무조건 호출 가능하다는 의미

  • 서비스 생성 protected service

  • 맵 생성 private Map

    • key = url, value = ControllerV2
    • 매핑 정보 담을 공간 = controllerMap
  • 매핑 정보 public FrontControllerServiceV2()

    • command + n 하고 constructor 클릭 → Select None 클릭
    • 매핑정보를 담기!
    • key 값이 요청되면 value를 실행하게끔 설정

  • URI 주소 가져오기 request.getRequestURI (option + command + v)

  • 에서 URI 찾아 컨트롤러 반환 controllerMap.get(requestURI)(option + command + v)

  • 예외처리는 404 출력 SC_NOT_FOUND

  • 조회가 됐다면 인터페이스 호출 MyView.process()
    • ControllerV2
  • 렌더 호출 view.render()
    • MyView 클래스의 rendeer 메서드 호출
    • 더보기
      public void render(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
          RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
          dispatcher.forward(request, response);
      }

  

<실행과정>

  1. URL =http://localhost:8080/front-controller/v2/*실행
    * 자리에 아무거나 넣어도 하위 메서드는 모두 서블릿 호출 가능

  2.  request.getRequestURI 경로를 가져온다

  3. controllerMap에서 가져온 경로와 연결된 value 값(객체 인스턴스) 찾기

  4. 찾은 값을 인터페이스인 ControllerV2 를 통해 반환

  5. controller 없으면 예외처리

  6. 있으면 Override 된 클래스 호출

  7. 연결된 MyView 렌더 실행

 

 

 

 

 

 

 

 

 

[출처] 김영한 강사님 인프런 스프링 mvc1

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard 

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 원

www.inflearn.com