1. 소개

이 기사에서는 Spring MVC의 핵심 개념인 컨트롤러에 초점을 맞출 것입니다.

2. 개요

한 걸음 뒤로 물러나 일반적인 Spring Model View Controller 아키텍처 에서 Front Controller 의 개념을 살펴보는 것으로 시작하겠습니다 .

매우 높은 수준에서 우리가 보고 있는 주요 책임은 다음과 같습니다.

  • 수신 요청 가로채기
  • 요청의 페이로드를 데이터의 내부 구조로 변환
  • 추가 처리를 위해 데이터를 모델 로 보냅니다.
  • 모델 에서 처리된 데이터를 가져 오고 렌더링을 위해 해당 데이터를 보기 로 이동합니다.

다음은 Spring MVC 의 상위 수준 흐름에 대한 빠른 다이어그램입니다 .

SpringMVC

보시다시피 DispatcherServlet 은 아키텍처에서 Front Controller 역할을 합니다 .

다이어그램은 일반적인 MVC 컨트롤러와 RESTful 컨트롤러 모두에 적용할 수 있습니다. 약간의 차이가 있습니다(아래 설명 참조).

전통적인 접근 방식에서 MVC 응용 프로그램은 서비스 지향이 아니므 로 컨트롤러 에서 받은 데이터를 기반으로 최종 뷰를 렌더링하는 View Resolver 가 있습니다 .

RESTful 애플리케이션은 서비스 지향적이고 원시 데이터(일반적으로 JSON/XML)를 반환하도록 설계되었습니다. 이러한 애플리케이션은 뷰 렌더링을 수행하지 않기 때문에 뷰 확인자가 없습니다 . 컨트롤러 일반적으로 HTTP 응답을 통해 직접 데이터를 보낼 것으로 예상됩니다.

MVC0 스타일 컨트롤러부터 시작하겠습니다.

3. 메이븐 의존성

Spring MVC 로 작업할 수 있으려면 먼저 Maven 의존성을 처리해야 합니다.

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.0.6.RELEASE</version>
<dependency>

최신 버전의 라이브러리를 얻으려면 Maven Central에서 spring-webmvc를 살펴보십시오 .

4. 프로젝트 웹 구성

이제 컨트롤러 자체를 살펴보기 전에 먼저 간단한 웹 프로젝트를 설정하고 빠른 서블릿 구성을 수행해야 합니다.

먼저 web.xml 을 사용하지 않고 초기화 프로그램을 사용 하여 DispatcherServlet 을 설정 하는 방법을 살펴보겠습니다 .

public class StudentControllerConfig implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext sc) throws ServletException {
        AnnotationConfigWebApplicationContext root = 
          new AnnotationConfigWebApplicationContext();
        root.register(WebConfig.class);

        root.refresh();
        root.setServletContext(sc);

        sc.addListener(new ContextLoaderListener(root));

        DispatcherServlet dv = 
          new DispatcherServlet(new GenericWebApplicationContext());

        ServletRegistration.Dynamic appServlet = sc.addServlet("test-mvc", dv);
        appServlet.setLoadOnStartup(1);
        appServlet.addMapping("/test/*");
    }
}

XML 없이 설정하려면 클래스 경로에 servlet-api 3.1.0이 있어야 합니다.

web.xml 은 다음 과 같습니다.

<servlet>
    <servlet-name>test-mvc</servlet-name>
    <servlet-class>
      org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/test-mvc.xml</param-value>
    </init-param>
</servlet>

여기 에서 Spring 컨텍스트를 로드하는 데 사용되는 XML 파일 을 가리키는 contextConfigLocation 속성 을 설정하고 있습니다. 속성이 없으면 Spring은 {servlet_name}-servlet.xml 이라는 파일을 검색합니다 .

우리의 경우 servlet_nametest-mvc 이므로 이 예제에서 DispatcherServlet 은 test-mvc-servlet.xml 이라는 파일을 검색합니다 .

마지막으로 DispatcherServlet 을 설정 하고 특정 URL 에 매핑하여 여기에서 Front Controller 기반 시스템 을 완성해 보겠습니다.

<servlet-mapping>
    <servlet-name>test-mvc</servlet-name>
    <url-pattern>/test/*</url-pattern>
</servlet-mapping>

따라서 이 경우 DispatcherServlet 은 /test/* 패턴 내의 모든 요청을 가로챕 니다.

5. 스프링 MVC 웹 구성

이제 Spring Config 를 사용하여 Dispatcher Servlet 을 설정 하는 방법을 살펴보겠습니다 .

@Configuration
@EnableWebMvc
@ComponentScan(basePackages= {
  "com.baeldung.controller.controller",
  "com.baeldung.controller.config" }) 
public class WebConfig implements WebMvcConfigurer {
    
    @Override
    public void configureDefaultServletHandling(
      DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
 
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver bean = 
          new InternalResourceViewResolver();
        bean.setPrefix("/WEB-INF/");
        bean.setSuffix(".jsp");
        return bean;
    }
}

이제 XML 을 사용하여 Dispatcher Servlet 을 설정하는 방법을 살펴보겠습니다 . DispatcherServlet XML 파일스냅샷 – DispatcherServlet 이 사용자 정의 컨트롤러 및 기타 Spring 엔터티 를 로드하는 데 사용 하는 XML 파일 은 다음과 같습니다.

<context:component-scan base-package="com.baledung.controller" />
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/WEB-INF/</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

이 간단한 구성을 기반으로 프레임워크는 물론 클래스 경로에서 찾을 모든 컨트롤러 빈을 초기화합니다.

뷰 렌더링을 담당하는 View Resolver도 정의하고 있다는 점에 유의 하십시오. 여기서는 Spring의 InternalResourceViewResolver 를 사용할 것입니다. 이는 보기의 이름이 확인 될 것으로 예상합니다. 즉, 접두어와 접미어(둘 다 XML 구성 에 정의됨)를 사용하여 해당 페이지를 찾는 것을 의미합니다 .

예를 들어 컨트롤러 가 " welcome" 이라는 보기 를 반환하면 보기 확인 자는 WEB-INF 폴더 에서 "welcome.jsp" 라는 페이지를 확인하려고 시도 합니다.

6. MVC 컨트롤러

이제 마지막으로 MVC 스타일 컨트롤러를 구현해 보겠습니다.

모델 맵뷰 객체 를 포함하는 ModelAndView 객체를 반환하는 방법에 주목하십시오 . 둘 다 데이터 렌더링을 위해 View Resolver 에서 사용됩니다.

@Controller
@RequestMapping(value = "/test")
public class TestController {

    @GetMapping
    public ModelAndView getTestData() {
        ModelAndView mv = new ModelAndView();
        mv.setViewName("welcome");
        mv.getModel().put("data", "Welcome home man");

        return mv;
    }
}

그래서 우리는 여기서 정확히 무엇을 설정 했습니까?

먼저 TestController 라는 컨트롤러를 만들고 "/test" 경로 에 매핑했습니다 . 클래스에서 우리는 ModelAndView 객체 를 반환하고 GET 요청에 매핑되는 메서드를 생성했습니다. 따라서 “ test ” 로 끝나는 모든 URL 호출 은 DispatcherServlet 에 의해 TestControllergetTestData 메서드 로 라우팅됩니다 .

물론 좋은 측정을 위해 일부 모델 데이터와 함께 ModelAndView 개체를 반환하고 있습니다.

뷰 개체의 이름은 " welcome "으로 설정되어 있습니다. 위에서 설명한 것처럼 View Resolver 는 WEB-INF 폴더에서 " welcome.jsp "라는 페이지를 검색합니다 .

아래에서 예제 GET 작업 의 결과를 볼 수 있습니다 .

result_final

URL"test" 로 끝납니다 . URL 의 패턴 "/test/test "입니다.

첫 번째 "/test" 는 Servlet에서 가져오고 두 번째는 컨트롤러 매핑에서 가져옵니다.

7. REST에 대한 더 많은 스프링 의존성

이제 RESTful 컨트롤러를 살펴보겠습니다. 물론 시작하기에 좋은 곳은 필요한 추가 Maven 의존성입니다.

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.0.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.0.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.5</version>
    </dependency>
</dependencies>

이러한 의존성의 최신 버전은 jackson-core , spring-webmvcspring-web 링크를 참조하십시오 .

여기서 Jackson 은 물론 필수는 아니지만 JSON 지원을 활성화하는 좋은 방법임에는 틀림없습니다. 해당 지원에 대해 자세히 알아 보려면 여기에서 메시지 변환기 문서를 살펴보십시오 .

8. REST 컨트롤러

Spring RESTful 애플리케이션 의 설정은 View Resolver모델 맵 이 없다는 유일한 차이점을 제외 하면 MVC 애플리케이션의 설정과 동일합니다.

API는 일반적으로 원시 데이터(일반적으로 XMLJSON 표현)를 클라이언트에 다시 반환하므로 DispatcherServlet 은 뷰 확인자를 우회 하고 HTTP Response body에서 바로 데이터를 반환합니다 .

간단한 RESTful 컨트롤러 구현을 살펴보겠습니다.

@Controller
public class RestController {

    @GetMapping(value = "/student/{studentId}")
    public @ResponseBody Student getTestData(@PathVariable Integer studentId) {
        Student student = new Student();
        student.setName("Peter");
        student.setId(studentId);

        return student;
    }
}

메소드의 @ResponseBody 어노테이션에 주목하십시오. Spring이 뷰 리졸버 를 우회 하고 본질적으로 HTTP 응답의 본문에 직접 출력을 작성하도록 지시합니다 .

출력의 빠른 스냅샷이 아래에 표시됩니다.

7월 16일

위의 출력은 학생 ID1 인 API에 GET 요청을 보낸 결과입니다 .

여기서 한 가지 간단한 참고 사항은 @RequestMapping 어노테이션은 잠재력 을 최대한 활용하기 위해 실제로 탐색해야 하는 핵심 어노테이션 중 하나라는 것입니다.

9. 스프링 부트와 @RestController 어노테이션

Spring Boot 의 @RestController 어노테이션은 기본적으로 항상 @ResponseBody를 정의하지 않아도 되는 빠른 지름길 입니다 .

다음은 이 새 어노테이션을 사용하는 이전 예제 컨트롤러입니다.

@RestController
public class RestAnnotatedController {
    @GetMapping(value = "/annotated/student/{studentId}")
    public Student getData(@PathVariable Integer studentId) {
        Student student = new Student();
        student.setName("Peter");
        student.setId(studentId);

        return student;
    }
}

10. 결론

이 사용방법(예제)에서는 일반적인 MVC 애플리케이션과 RESTful API의 관점에서 Spring에서 컨트롤러를 사용하는 기본 사항을 살펴봅니다.

물론 기사의 모든 코드는 GitHub에서 사용할 수 있습니다 .

REST footer banner