Browse Source

BEST_MATCHING_HANDLER_ATTRIBUTE for spring-webmvc

Issue: SPR-17518
pull/2023/head
Rossen Stoyanchev 6 years ago
parent
commit
a55ca56e34
  1. 9
      spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerMapping.java
  2. 1
      spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
  3. 1
      spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java
  4. 9
      spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java
  5. 10
      spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMappingTests.java

9
spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerMapping.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -55,6 +55,13 @@ import org.springframework.lang.Nullable;
*/ */
public interface HandlerMapping { public interface HandlerMapping {
/**
* Name of the {@link HttpServletRequest} attribute that contains the mapped
* handler for the best matching pattern.
* @since 5.1.3
*/
String BEST_MATCHING_HANDLER_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingHandler";
/** /**
* Name of the {@link HttpServletRequest} attribute that contains the path * Name of the {@link HttpServletRequest} attribute that contains the path
* within the handler mapping, in case of a pattern match, or the full * within the handler mapping, in case of a pattern match, or the full

1
spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java

@ -414,6 +414,7 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}"); "Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
} }
} }
request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.handlerMethod);
handleMatch(bestMatch.mapping, lookupPath, request); handleMatch(bestMatch.mapping, lookupPath, request);
return bestMatch.handlerMethod; return bestMatch.handlerMethod;
} }

1
spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java

@ -411,6 +411,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping i
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
exposePathWithinMapping(this.bestMatchingPattern, this.pathWithinMapping, request); exposePathWithinMapping(this.bestMatchingPattern, this.pathWithinMapping, request);
request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, handler);
request.setAttribute(INTROSPECT_TYPE_LEVEL_MAPPING, supportsTypeLevelMappings()); request.setAttribute(INTROSPECT_TYPE_LEVEL_MAPPING, supportsTypeLevelMappings());
return true; return true;
} }

9
spring-webmvc/src/test/java/org/springframework/web/servlet/handler/HandlerMethodMappingTests.java

@ -36,6 +36,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.support.StaticWebApplicationContext; import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.util.UrlPathHelper; import org.springframework.web.util.UrlPathHelper;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -81,8 +82,10 @@ public class HandlerMethodMappingTests {
String key = "foo"; String key = "foo";
this.mapping.registerMapping(key, this.handler, this.method1); this.mapping.registerMapping(key, this.handler, this.method1);
HandlerMethod result = this.mapping.getHandlerInternal(new MockHttpServletRequest("GET", key)); MockHttpServletRequest request = new MockHttpServletRequest("GET", key);
HandlerMethod result = this.mapping.getHandlerInternal(request);
assertEquals(method1, result.getMethod()); assertEquals(method1, result.getMethod());
assertEquals(result, request.getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE));
} }
@Test @Test
@ -90,8 +93,10 @@ public class HandlerMethodMappingTests {
this.mapping.registerMapping("/fo*", this.handler, this.method1); this.mapping.registerMapping("/fo*", this.handler, this.method1);
this.mapping.registerMapping("/f*", this.handler, this.method2); this.mapping.registerMapping("/f*", this.handler, this.method2);
HandlerMethod result = this.mapping.getHandlerInternal(new MockHttpServletRequest("GET", "/foo")); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
HandlerMethod result = this.mapping.getHandlerInternal(request);
assertEquals(method1, result.getMethod()); assertEquals(method1, result.getMethod());
assertEquals(result, request.getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE));
} }
@Test(expected = IllegalStateException.class) @Test(expected = IllegalStateException.class)

10
spring-webmvc/src/test/java/org/springframework/web/servlet/handler/SimpleUrlHandlerMappingTests.java

@ -42,17 +42,17 @@ public class SimpleUrlHandlerMappingTests {
@Test @Test
@SuppressWarnings("resource") @SuppressWarnings("resource")
public void handlerBeanNotFound() throws Exception { public void handlerBeanNotFound() {
MockServletContext sc = new MockServletContext(""); MockServletContext sc = new MockServletContext("");
XmlWebApplicationContext root = new XmlWebApplicationContext(); XmlWebApplicationContext root = new XmlWebApplicationContext();
root.setServletContext(sc); root.setServletContext(sc);
root.setConfigLocations(new String[] {"/org/springframework/web/servlet/handler/map1.xml"}); root.setConfigLocations("/org/springframework/web/servlet/handler/map1.xml");
root.refresh(); root.refresh();
XmlWebApplicationContext wac = new XmlWebApplicationContext(); XmlWebApplicationContext wac = new XmlWebApplicationContext();
wac.setParent(root); wac.setParent(root);
wac.setServletContext(sc); wac.setServletContext(sc);
wac.setNamespace("map2err"); wac.setNamespace("map2err");
wac.setConfigLocations(new String[] {"/org/springframework/web/servlet/handler/map2err.xml"}); wac.setConfigLocations("/org/springframework/web/servlet/handler/map2err.xml");
try { try {
wac.refresh(); wac.refresh();
fail("Should have thrown NoSuchBeanDefinitionException"); fail("Should have thrown NoSuchBeanDefinitionException");
@ -95,7 +95,7 @@ public class SimpleUrlHandlerMappingTests {
MockServletContext sc = new MockServletContext(""); MockServletContext sc = new MockServletContext("");
XmlWebApplicationContext wac = new XmlWebApplicationContext(); XmlWebApplicationContext wac = new XmlWebApplicationContext();
wac.setServletContext(sc); wac.setServletContext(sc);
wac.setConfigLocations(new String[] {"/org/springframework/web/servlet/handler/map2.xml"}); wac.setConfigLocations("/org/springframework/web/servlet/handler/map2.xml");
wac.refresh(); wac.refresh();
Object bean = wac.getBean("mainController"); Object bean = wac.getBean("mainController");
Object otherBean = wac.getBean("otherController"); Object otherBean = wac.getBean("otherController");
@ -106,11 +106,13 @@ public class SimpleUrlHandlerMappingTests {
HandlerExecutionChain hec = getHandler(hm, req); HandlerExecutionChain hec = getHandler(hm, req);
assertTrue("Handler is correct bean", hec != null && hec.getHandler() == bean); assertTrue("Handler is correct bean", hec != null && hec.getHandler() == bean);
assertEquals("/welcome.html", req.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)); assertEquals("/welcome.html", req.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE));
assertEquals(bean, req.getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE));
req = new MockHttpServletRequest("GET", "/welcome.x"); req = new MockHttpServletRequest("GET", "/welcome.x");
hec = getHandler(hm, req); hec = getHandler(hm, req);
assertTrue("Handler is correct bean", hec != null && hec.getHandler() == otherBean); assertTrue("Handler is correct bean", hec != null && hec.getHandler() == otherBean);
assertEquals("welcome.x", req.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)); assertEquals("welcome.x", req.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE));
assertEquals(otherBean, req.getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE));
req = new MockHttpServletRequest("GET", "/welcome/"); req = new MockHttpServletRequest("GET", "/welcome/");
hec = getHandler(hm, req); hec = getHandler(hm, req);

Loading…
Cancel
Save