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

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

by Poorm 푸름 2023. 11. 9.

* 스프링 입문은 Window로 스프링 MVC 1편은 Mac으로 진행합니다  

 *  진도 : 섹션4 - (1) ~ (2) 
 *          : 자바 클래스명,         : 코드,         : 단축키

 

 

1. 프론트 컨트롤러

 

  • 기존의 컨트롤러
https://velog.io/@luvjoyyy

 

  • 공통 로직을 하나로 묶은 프론트 컨트롤러
    https://velog.io/@luvjoyyy

 

- FrontController 패턴 

  1. 프론트 컨트롤러 서블릿 하나로 클라이언트의 요청을 받기
    (프론트 컨트롤러를 제외한 나머지 컨트롤러는 서블릿을 사용하지 않아도 됨)
  2. 프론트 컨트롤러가 요청에 맞는 컨트롤러를 찾아서 호출

 

 

 

2. 프론트 컨트롤러_구현 1단계 (매핑정보, 컨트롤러 호출)

1) 인터페이스를 만들자!
 [ src - java - hello.servlet - web - frontcontroller .v1 - ControllerV1 ]

 

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

 

 

 2) 회원 등록 컨트롤러
 [ src - java - hello .servlet - web - frontcontroller .v1 - controller - MemberFormControllerV1 ]

public class MemberFormControllerV1 implements ControllerV1 {
    @Override
    public void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String viewPath ="/WEB-INF/views/new-form.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request,response);
    }
}

 

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

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

    • extends 와 implement 의 차이

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

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

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

    • viewPath에 JSP 경로 넣기
    • request.getRequestDispatcher (option + command + v)
    • dispatcher.forward() : 다른 서블릿이나 JSP로 이동할 수 있는 기능(서버 내부에서 호출)

 

 3) 회원 저장 컨트롤러
[ src - java - hello .servlet - web - frontcontroller .v1 - controller - MemberSaveControllerV1 ]

public class MemberSaveControllerV1 implements ControllerV1 {
    private MemberRepository memberRepository = MemberRepository.getInstance();
    @Override
    public void 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);
        
        String viewPath = "/WEB-INF/views/save-result.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);

    }
}

 

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

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

    • extends 와 implement 의 차이

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

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

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

    • 리포지토리 가져오기 private MemberRepository.getInstance
    • form data 값 읽어오기request.getParameter()
    • Member 객체 생성
    • 모델에 데이터 담기request.setAttribute()
    • viewPath에 JSP 경로 넣기
    • request.getRequestDispatcher (option + command + v)
    • dispatcher.forward() : 다른 서블릿이나 JSP로 이동할 수 있는 기능(서버 내부에서 호출)

 

 4) 회원 목록 컨트롤러
 [ src - java - hello .servlet - web - frontcontroller .v1 - controller - MemberListControllerV1 ]

public class MemberListControllerV1 implements ControllerV1 {

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

        request.setAttribute("members", members);

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

 

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

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

    • extends 와 implement 의 차이

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

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

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

    • 리포지토리 가져오기 private MemberRepository.getInstance
    • 데이터 조회 memberRepository.findAll() (option + command + v)
    • 모델에 데이터 담기request.setAttribute()
    • viewPath에 JSP 경로 넣기
    • request.getRequestDispatcher (option + command + v)
    • dispatcher.forward() : 다른 서블릿이나 JSP로 이동할 수 있는 기능(서버 내부에서 호출)

 

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

  @WebServlet(name = "frontControllerServletV1", urlPatterns = "/front-
  controller/v1/*")
  public class FrontControllerServletV1 extends HttpServlet {
  
     @Override
     protected void service(HttpServletRequest request, HttpServletResponse response)

 

  • 프론트 컨트롤러는 꼭 서블릿으로 작성한다!

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

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

 

  • key = url, value = ControllerV1
  • 매핑 정보 담을 공간 = controllerMap

    public FrontControllerServiceV1() {
        controllerMap.put("/front-controller/v1/members/new-form", new MemberFormControllerV1());
        controllerMap.put("/front-controller/v1/members/save", new MemberSaveControllerV1());
        controllerMap.put("/front-controller/v1/members", new MemberListControllerV1());
    }

 

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

 

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

        System.out.println("FrontControllerServletV1.service");

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

        controller.process(request, response);
    }
}

 

  • URI 주소 가져오기 request.getRequestURI (option + command + v)
  • 에서 URI 찾아 컨트롤러 반환 controllerMap.get(requestURI)(option + command + v)
  • 예외처리는 404 출력 SC_NOT_FOUND

  • 조회가 됐다면 인터페이스 호출 controller.process()

 

<실행과정>

 

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

  2.  request.getRequestURI경로를 가져온다
  3. controllerMap에서 가져온 경로와 연결된 value 값(객체 인스턴스) 찾기
  4. 찾은 값을 인터페이스인 ControllerV1 를 통해 반환

  5. controller 없으면 예외처리

  6. 있으면 Override 된 메서드 호출

 

더보기

   (예시)

 

  1. URL = http://localhost:8080/front-controller/v1/members/new-form 라면
  2. 해당 URI와 연결된 value = new MemberFormCOntrollerV1 을 맵에서 확인
  3. ControllerV1 인터페이스를 통해 Override된 MemberFormCOntrollerV1 클래스 호출

 

 

 

 

 

 

 

 

 

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

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

 

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

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

www.inflearn.com