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
'Java' 카테고리의 다른 글
Spring DispatcherServlet 소개 (0) | 2021.04.20 |
---|---|
Spring MVC의 ViewResolver 사용방법(예제) (0) | 2021.04.20 |
Spring MVC 콘텐츠 협상 (0) | 2021.04.19 |
Spring @RequestMapping 새로운 바로 가기 어노테이션 (0) | 2021.04.19 |
Spring MVC 사용자 지정 유효성 검사 (0) | 2021.04.19 |