[데브코스] Spring MVC 2

Updated: Categories:

W5D3 Part1 - MVC Form 처리 / WebApplicationContext 에 대해 알아보자!

Form 처리

POST

  • @PostMapping 어노테이션을 달아 요청을 받을 수 있음
  • 메소드 작성시 파라미터로 form에서 넘어오는 데이터를 받는다
    • 이 데이터를 감싸는 Wrapper 클래스를 설정할 수 있으며, 이것이 DTO이다
    • DTO로 Record 클래스를 사용할 수 있다.
@PostMapping(URL)
public 메소드(DTO dto){
    // Request를 받고 변수에 저장해주는 record -> DTO
    dto.데이터
    return 목적view;
}

GET

  • @GetMapping 어노테이션으로 요청을 받는다
  • get 요청 URL에 데이터를 담아 보낼수가 있다.
  • 이 경우 메소드에서 파라미터를 받기 전 @PathVariable로 데이터를 매핑해준다.
@GetMapping(".../{데이터}")
public 메소드(@PathVariable("데이터") 변수){
    ...
    return 목적view;
}


WebApplicationContext

  • WebApplicationContext vs ApplicationContext : Servlet Context에 접근 가능한지 차이
    • 톰캣이 Servlet Context
  • 프로젝트 규모가 큰 Monolithic 아키텍처에서는 App Context를 분리해서 사용했음
  • Servlet과 App Context 간의 구조를 보고 코드에 적용해보자

Servlet 구조

image

image

image

image

  • Servlet에서 사용하는 App Context와, 프로젝트 전체에서 사용하는 App Context는 분리한다.
    • 요청에 필요한 App Context만을 load하기 위해서
    • Root App Context : 서비스 로직과 관련된 Bean들을 정의. (부모)
    • Servlet App Context : 서블릿과 관련된 Bean을 정의. (자식)
  • 요즘 프로젝트 규모가 작은 MSA 방식에서는 root App Context만 정의하기도 함


Config Class 작성

  • 우선 App Context Config 파일을 Root와 Servlet으로 분리해야함
Servlet Config
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = 패키지경로,
        includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, 
        value = [포함할 컨트롤러].class),
        useDefaultFilters = false
)
static class ServletConfig implements WebMvcConfigurer, ApplicationContextAware {
    ...
}
Root Config
@Configuration
@ComponentScan(basePackages = 패키지경로,
        excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, 
        value = [제외할 컨트롤러].class)
)
static class RootConfig {
    ...
}

App Context 분리해서 등록하기

  • 설명은 주석으로!!
@Override
public void onStartup(ServletContext servletContext) {
    logger.info("Starting Server ...");
    // root App Context 객체 등록
    var rootApplicationContext = new AnnotationConfigWebApplicationContext();
    rootApplicationContext.register(RootConfig.class);
    var loaderListener = new ContextLoaderListener(rootApplicationContext);
    servletContext.addListener(loaderListener);

    // Servlet App Context 등록
    var applicationContext = new AnnotationConfigWebApplicationContext();
    applicationContext.register(ServletConfig.class);
    // 등록된 Servlet App Context로 dispatcherServlet 객체 생성
    var dispatcherServlet = new DispatcherServlet(applicationContext);
    // dispatcherServlet에 이름 지어주고 Servlet으로 등록 -> 도메인에 따라 여러개를 등록 가능
    var servletRegistration = servletContext.addServlet("test", dispatcherServlet);
    servletRegistration.addMapping("/");
    // -1 일경우 servlet context는 로드되지 않다가, api 요청이 왔을때 비로소 켜진다
    servletRegistration.setLoadOnStartup(-1);   
}