그날그날메모

Spring Handler 매핑 사용방법(예제)

Java

Spring Handler 매핑 사용방법(예제)

그날그날메모 2021. 4. 20. 01:26

1. 소개

Spring MVC에서 DispatcherServlet들어오는 모든 HTTP 요청을 수신하고 처리하는 프런트 컨트롤러 역할을 합니다.

간단히 말해서 핸들러 매핑의 도움으로 요청을 관련 구성 요소에 전달하여 처리가 발생 합니다 .

HandlerMapping 은 요청과 핸들러 객체 간의 매핑을 정의하는 인터페이스입니다 . Spring MVC 프레임 워크는 몇 가지 기성 구현을 제공하지만 인터페이스는 개발자가 사용자 정의 매핑 전략을 제공하기 위해 구현할 수 있습니다.

이 기사에서는 Spring MVC에서 제공하는 BeanNameUrlHandlerMapping , SimpleUrlHandlerMapping , ControllerClassNameHandlerMapping , 구성 및 차이점에 대해 설명합니다.

2. BeanNameUrlHandlerMapping

BeanNameUrlHandlerMapping 은 기본 HandlerMapping 구현입니다. BeanNameUrlHandlerMapping 은 요청 URL을 동일한 이름을 가진 빈에 매핑합니다.

이 특정 매핑은 직접 이름 일치 및 "*"패턴을 사용한 패턴 일치를 지원합니다.

예를 들어, 수신 URL "/ foo""/ foo" 라는 빈에 매핑됩니다 . 패턴 매핑의 예는 "/ foo2 /" 또는 "/ fooOne /" 과 같이 이름이 "/ foo"로 시작하는 빈 "/ foo *"대한 요청을 매핑하는 것입니다 .

여기에서이 예제를 구성하고 “/ beanNameUrl”에 대한 요청을 처리하는 Bean 컨트롤러를 등록 해 보겠습니다 .

@Configuration
public class BeanNameUrlHandlerMappingConfig {
    @Bean
    BeanNameUrlHandlerMapping beanNameUrlHandlerMapping() {
        return new BeanNameUrlHandlerMapping();
    }

    @Bean("/beanNameUrl")
    public WelcomeController welcome() {
        return new WelcomeController();
    }
}

이것은 위의 Java 기반 구성에 해당하는 XML입니다.

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<bean name="/beanNameUrl" class="com.baeldung.WelcomeController" />

이 두 구성 모두에서 Spring MVC에서 제공하는 BeanNameUrlHandlerMapping에 대한 Bean을 정의 할 필요가 없다는 점에 유의하는 것이 중요합니다 . 이 빈 정의를 제거해도 문제가 발생하지 않으며 요청은 등록 된 핸들러 빈에 계속 매핑됩니다.

이제 "/ beanNameUrl"에 대한 모든 요청 DispatcherServlet의해 " WelcomeController " 로 전달됩니다 . WelcomeController 는 " welcome " 이라는 뷰 이름을 반환합니다 .

다음 코드는이 구성을 테스트하고 올바른보기 이름이 반환되는지 확인합니다.

public class BeanNameMappingConfigTest {
    // ...

    @Test
    public void whenBeanNameMapping_thenMappedOK() {
        mockMvc.perform(get("/beanNameUrl"))
          .andExpect(status().isOk())
          .andExpect(view().name("welcome"));
    }
}

3. SimpleUrlHandlerMapping

다음으로 SimpleUrlHandlerMapping 은 가장 유연한 HandlerMapping 구현입니다. 빈 인스턴스와 URL 사이 또는 빈 이름과 URL 사이의 직접적이고 선언적인 매핑을 허용합니다.

"/ simpleUrlWelcome""/ * / simpleUrlWelcome"요청"welcome" 빈에 매핑 해 보겠습니다 .

@Configuration
public class SimpleUrlHandlerMappingConfig {

    @Bean
    public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
        SimpleUrlHandlerMapping simpleUrlHandlerMapping
          = new SimpleUrlHandlerMapping();
        
        Map<String, Object> urlMap = new HashMap<>();
        urlMap.put("/simpleUrlWelcome", welcome());
        simpleUrlHandlerMapping.setUrlMap(urlMap);
        
        return simpleUrlHandlerMapping;
    }

    @Bean
    public WelcomeController welcome() {
        return new WelcomeController();
    }
}

또는 이에 상응하는 XML 구성은 다음과 같습니다.

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <value>
            /simpleUrlWelcome=welcome
            /*/simpleUrlWelcome=welcome
        </value>
    </property>
</bean>
<bean id="welcome" class="com.baeldung.WelcomeController" />

XML 구성에서 "<value>" 태그 간의 매핑은 java.util.Properties 클래스에서 허용하는 형식으로 수행 되어야하며 구문은 path = Handler_Bean_Name을 따라야합니다 .

URL은 일반적으로 선행 슬래시가 있어야하지만 경로가 하나로 시작하지 않으면 Spring MVC가 자동으로 추가합니다.

XML에서 위의 예를 구성하는 다른 방법 "value" 대신 "props" 속성 을 사용하는 것입니다 . 소품 의 List이 "소품" 각을 정의 매핑 태그 "키" 매핑 된 URL에이라와 태그의 값이 빈의 이름입니다.

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="/simpleUrlWelcome">welcome</prop>
            <prop key="/*/simpleUrlWelcome">welcome</prop>
        </props>
    </property>
</bean>

다음 테스트 케이스는 "/ simpleUrlWelcome "에 대한 요청이 "welcome" 이라는 뷰 이름을 반환하는 " WelcomeController"에 의해 처리 되는지 확인합니다 .

public class SimpleUrlMappingConfigTest {
    // ...

    @Test
    public void whenSimpleUrlMapping_thenMappedOK() {
        mockMvc.perform(get("/simpleUrlWelcome"))
          .andExpect(status().isOk())
          .andExpect(view().name("welcome"));
    }
}

4. ControllerClassNameHandlerMapping (Spring 5에서 제거됨)

ControllerClassNameHandlerMapping은 등록 된 컨트롤러 Bean (또는 어노테이션 컨트롤러에 URL을 매핑 @Controller의 가, 나, 같은 이름의 시작 어노테이션).

특히 단일 요청 유형을 처리하는 간단한 컨트롤러 구현의 경우 많은 시나리오에서 더 편리 할 수 ​​있습니다. Spring MVC에서 사용하는 규칙은 클래스 이름을 사용하고 "Controller" 접미사를 제거한 다음 이름을 소문자로 변경하고 선행 "/" 가있는 매핑으로 반환하는 것 입니다.

예를 들어 "WelcomeController""/ welcome *" , 즉 "welcome"으로 시작하는 모든 URL에 대한 매핑으로 반환됩니다 .

ControllerClassNameHandlerMapping을 구성 해 보겠습니다 .

@Configuration
public class ControllerClassNameHandlerMappingConfig {

    @Bean
    public ControllerClassNameHandlerMapping controllerClassNameHandlerMapping() {
        return new ControllerClassNameHandlerMapping();
    }

    @Bean
    public WelcomeController welcome() {
        return new WelcomeController();
    }
}

참고 ControllerClassNameHandlerMapping가 되어 Spring 4.3에서 사용되지 않는 어노테이션 중심의 핸들러 방법에 찬성.

또 다른 중요한 참고 사항은 컨트롤러 이름이 항상 소문자로 반환된다는 것입니다 ( "Controller"접미사 제외). 우리가 "라는 컨트롤러가 그렇다면 WelcomeBaeldungController을 "만 요청을 처리 할 "/ welcomebaeldung" 가 아니라에 "/ welcomeBaeldung" .

아래의 Java 구성 및 XML 구성에서 ControllerClassNameHandlerMapping Bean 을 정의 하고 요청을 처리하는 데 사용할 컨트롤러에 대한 Bean을 등록합니다. 또한 "WelcomeController" 유형의 빈을 등록 하고 해당 빈은 "/ welcome"로 시작하는 모든 요청을 처리합니다 .

이에 상응하는 XML 구성은 다음과 같습니다.

<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
<bean class="com.baeldung.WelcomeController" />

위의 구성을 사용하는 경우 "/ welcome "에 대한 요청 은 " WelcomeController "에 의해 처리됩니다 .

다음 코드는 "/ welcometest " 와 같은 "/ welcome *"에 대한 요청이 " welcome " 이라는 뷰 이름을 반환하는 "WelcomeController"에 의해 처리되도록합니다 .

public class ControllerClassNameHandlerMappingTest {
    // ...

    @Test
    public void whenControllerClassNameMapping_thenMappedOK() {
        mockMvc.perform(get("/welcometest"))
          .andExpect(status().isOk())
          .andExpect(view().name("welcome"));
    }
}

5. 우선 순위 구성

Spring MVC 프레임 워크는 동시에 하나 이상의 HandlerMapping 인터페이스 구현을 허용 합니다.

구성을 만들고 서로 다른 매핑을 사용하고 서로 다른보기 이름을 반환하는 URL "/ welcome"에 매핑 된 두 컨트롤러를 등록하겠습니다.

@Configuration
public class HandlerMappingDefaultConfig {

    @Bean("/welcome")
    public BeanNameHandlerMappingController beanNameHandlerMapping() {
        return new BeanNameHandlerMappingController();
    }

    @Bean
    public WelcomeController welcome() {
        return new WelcomeController();
    }
}

명시 적 핸들러 매퍼가 등록되지 않은 경우 기본 BeanNameHandlerMapping 이 사용됩니다. 테스트를 통해이 동작을 주장 해 보겠습니다.

@Test
public void whenConfiguringPriorities_thenMappedOK() {
    mockMvc.perform(get("/welcome"))
      .andExpect(status().isOk())
      .andExpect(view().name("bean-name-handler-mapping"));
}

다른 핸들러 매퍼를 명시 적으로 등록하면 기본 매퍼가 재정의됩니다. 그러나 두 개의 매퍼가 명시 적으로 등록 될 때 어떤 일이 발생하는지 보는 것은 흥미 롭습니다.

@Configuration
public class HandlerMappingPrioritiesConfig {

    @Bean
    BeanNameUrlHandlerMapping beanNameUrlHandlerMapping() {
        BeanNameUrlHandlerMapping beanNameUrlHandlerMapping 
          = new BeanNameUrlHandlerMapping();
        return beanNameUrlHandlerMapping;
    }

    @Bean
    public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
        SimpleUrlHandlerMapping simpleUrlHandlerMapping
          = new SimpleUrlHandlerMapping();
        Map<String, Object> urlMap = new HashMap<>();
        urlMap.put("/welcome", simpleUrlMapping());
        simpleUrlHandlerMapping.setUrlMap(urlMap);
        return simpleUrlHandlerMapping;
    }

    @Bean
    public SimpleUrlMappingController simpleUrlMapping() {
        return new SimpleUrlMappingController();
    }

    @Bean("/welcome")
    public BeanNameHandlerMappingController beanNameHandlerMapping() {
        return new BeanNameHandlerMappingController();
    }
}

사용되는 매핑을 제어 하기 위해 setOrder (int order) 메서드를 사용하여 우선 순위를 설정 합니다. 이 메서드는 값이 낮을수록 우선 순위가 높은 하나의 int 매개 변수를 사용합니다.

XML 구성에서 "order" 라는 속성을 사용하여 우선 순위를 구성 할 수 있습니다 .

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
    <property name="order" value="2" />
</bean>

다음 beanNameUrlHandlerMapping.setOrder (1)simpleUrlHandlerMapping.setOrder (0) 를 통해 핸들러 매핑 빈 주문 속성을 추가해 보겠습니다 . order 속성 값이 낮을 수록 우선 순위가 높습니다. 테스트를 통해 새로운 동작을 주장 해 보겠습니다.

@Test
public void whenConfiguringPriorities_thenMappedOK() {
    mockMvc.perform(get("/welcome"))
      .andExpect(status().isOk())
      .andExpect(view().name("simple-url-handler-mapping"));
}

위의 구성을 테스트 할 때 "/ welcome"에 대한 요청 SimpleUrlHandlerController 를 호출하고 simple-url-handler-mapping 뷰를 반환 하는 SimpleUrlHandlerMapping 빈에 의해 처리된다는 것을 알있습니다. order 속성 의 값을 적절히 조정 하여 BeanNameHandlerMapping 이 우선 하도록 쉽게 구성 할 수 있습니다 .

6. 결론

이 기사에서는 프레임 워크의 다양한 구현을 탐색하여 Spring MVC 프레임 워크에서 URL 매핑을 처리하는 방법에 대해 설명했습니다.

이 기사와 함께 제공되는 코드 는 GitHub 에서 찾을 수 있습니다 .

참고
  • https://docs.spring.io/spring-framework/docs/current/reference/html
  • https://www.baeldung.com/spring-handler-mappings