diff --git a/extensions/spring/stormpath-spring-webmvc/src/main/java/com/stormpath/spring/config/AbstractStormpathWebMvcConfiguration.java b/extensions/spring/stormpath-spring-webmvc/src/main/java/com/stormpath/spring/config/AbstractStormpathWebMvcConfiguration.java index 3c94b1d635..5d123bbf22 100644 --- a/extensions/spring/stormpath-spring-webmvc/src/main/java/com/stormpath/spring/config/AbstractStormpathWebMvcConfiguration.java +++ b/extensions/spring/stormpath-spring-webmvc/src/main/java/com/stormpath/spring/config/AbstractStormpathWebMvcConfiguration.java @@ -182,12 +182,15 @@ import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; +import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.i18n.CookieLocaleResolver; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; import org.springframework.web.servlet.view.json.MappingJackson2JsonView; @@ -474,6 +477,9 @@ public abstract class AbstractStormpathWebMvcConfiguration { @Autowired //all view resolvers in the spring app context. key: bean name, value: resolver private Map viewResolvers; + @Autowired + private RequestMappingHandlerMapping requestMappingHandlerMapping; + private static class AccessibleResourceHandlerRegistry extends ResourceHandlerRegistry { public AccessibleResourceHandlerRegistry(ApplicationContext applicationContext, ServletContext servletContext) { super(applicationContext, servletContext); @@ -1322,6 +1328,7 @@ private T configure(T c) { private T init(T c) { try { c.init(); + assertUniqueMethodMapping(c); return c; } catch (Exception e) { String msg = "Unable to initialize controller [" + c + "]: " + e.getMessage(); @@ -1563,5 +1570,24 @@ public List stormpathCorsAllowedHeaders() { return java.util.Collections.emptyList(); } + + /** + * Fix for https://github.com/stormpath/stormpath-sdk-java/issues/1164 + * + * @since 1.3.0 + */ + private void assertUniqueMethodMapping(T c) { + Set requestMappingInfoSet = requestMappingHandlerMapping.getHandlerMethods().keySet(); + for (RequestMappingInfo requestMappingInfo : requestMappingInfoSet) { + Set patterns = requestMappingInfo.getPatternsCondition().getPatterns(); + for (String pattern: patterns) { + if (c.getUri() != null && c.getUri().equals(pattern)) { + HandlerMethod handlerMethod = requestMappingHandlerMapping.getHandlerMethods().get(requestMappingInfo); + throw new IllegalStateException("Mapping conflict: Stormpath cannot map '" + c.getUri() + "'. " + + handlerMethod.getBean() + "#" + handlerMethod + " is already mapped to this URI."); + } + } + } + } }