如何实现@RequestMapping自定义属性

例如 ,进行子域映射

本文: 在Google App Engine上为同一应用程序管理多个域和子域建议解析Filter上的子域并将变量分配给ServletRequest头。

然后映射将如下所示:

@RequestMapping(value = "/path", headers="subdomain=www") public String subsiteIndexPage(Model model,HttpServletRequest request) { ... } 

如果我们想创建自定义@RequestMapping属性,例如子域,例如。 创建这样的映射:

 @RequestMapping(value = "/some/action", subdomain = "www") public String handlerFunction(){ ... } 

我们应该覆盖@RequestMapping @interface定义并覆盖RequestMappingHandlerMapping受保护的方法,我们自己的实现
(如JIRA所述:“ 允许自定义请求映射条件SPR-7812 ”)。

这样对吗? 任何人都可以提供一个提示,如何实现这一function?


想法1
正如原始jira线程所建议的那样,就是创建自己的RequestCondition实现

有一个项目在github上使用这个解决方案: https : //github.com/rstoyanchev/spring-mvc-31-demo/

和相关的问题: 在Spring mvc 3.1中添加自定义RequestCondition

也许类型和方法的@Subdomain("www")映射是可能的解决方案吗?


链接到forum.springsource.com上的相同问题

我已经根据引用的spring-mvc-31-demo创建了解决方案

此解决方案可用于仅映射现在的单个RequestCondition。 我创建了两个要通知的问题,应该更改:
https://github.com/rstoyanchev/spring-mvc-31-demo/issues/5
https://jira.springsource.org/browse/SPR-9350

此解决方案使用Spring 3.1.1.RELEASE平台的自定义@RequestConditionfunction

用法

例1:

 @Controller @SubdomainMapping(value = "subdomain", tld = ".mydomain.com") class MyController1 { // Code here will be executed only on address match: // subdomain.mydomain.com } 

例2:

 @Controller class MyController2 { @RequestMapping("/index.html") @SubdomainMapping("www") public function index_www(Map map){ // on www.domain.com // where ".domain.com" is defined in SubdomainMapping.java } @RequestMapping("/index.html") @SubdomainMapping("custom") public function index_custom(Map map){ // on custom.domain.com // where ".domain.com" is defined in SubdomainMapping.java } } 

我们需要三个文件

  • SubdomainMapping.java
  • SubdomainRequestCondition.java
  • SubdomainRequestMappingHandlerMapping.java

SubdomainMapping.java

 import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface SubdomainMapping { /** * This param defines single or multiple subdomain * Where the Method/Type is valid to be called */ String[] value() default {}; /** * This param defines site domain and tld * It's important to put the leading dot * Not an array, so cannot be used for mapping multiple domains/tld */ String tld() default ".custom.tld"; } 

SubdomainRequestCondition.java

 import java.net.URL; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; import javax.servlet.http.HttpServletRequest; import org.springframework.web.servlet.mvc.condition.RequestCondition; public class SubdomainRequestCondition implements RequestCondition { private final Set subdomains; private final String tld; public SubdomainRequestCondition(String tld, String... subdomains) { this(tld, Arrays.asList(subdomains)); } public SubdomainRequestCondition(String tld, Collection subdomains) { this.subdomains = Collections.unmodifiableSet(new HashSet( subdomains)); this.tld = tld; } @Override public SubdomainRequestCondition combine(SubdomainRequestCondition other) { Set allRoles = new LinkedHashSet(this.subdomains); allRoles.addAll(other.subdomains); return new SubdomainRequestCondition(tld, allRoles); } @Override public SubdomainRequestCondition getMatchingCondition( HttpServletRequest request) { try { URL uri = new URL(request.getRequestURL().toString()); String[] parts = uri.getHost().split(this.tld); if (parts.length == 1) { for (String s : this.subdomains) { if (s.equalsIgnoreCase(parts[0])) { return this; } } } } catch (Exception e) { e.printStackTrace(System.err); } return null; } @Override public int compareTo(SubdomainRequestCondition other, HttpServletRequest request) { return org.apache.commons.collections.CollectionUtils.removeAll(other.subdomains, this.subdomains).size(); } } 

SubdomainRequestMappingHandlerMapping.java

 import java.lang.reflect.Method; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.web.servlet.mvc.condition.RequestCondition; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; public class CustomRequestMappingHandlerMapping extends RequestMappingHandlerMapping { @Override protected RequestCondition getCustomTypeCondition(Class handlerType) { SubdomainMapping typeAnnotation = AnnotationUtils.findAnnotation( handlerType, SubdomainMapping.class); return createCondition(typeAnnotation); } @Override protected RequestCondition getCustomMethodCondition(Method method) { SubdomainMapping methodAnnotation = AnnotationUtils.findAnnotation( method, SubdomainMapping.class); return createCondition(methodAnnotation); } private RequestCondition createCondition(SubdomainMapping accessMapping) { return (accessMapping != null) ? new SubdomainRequestCondition( accessMapping.tld(), accessMapping.value()) : null; } } 

安装目录

重要提示:到目前为止,无法将此解决方案与XML元素一起使用
,请参阅JIRA https://jira.springsource.org/browse/SPR-9344以获取解释

  • 你必须注册自定义MappingHandler bean,指向这个自定义实现SubdomainRequestMappingHandlerMapping
  • 您必须将其顺序设置为低于默认的RequestMappingHandlerMapping
    要么
    替换已注册的RequestMappingHandlerMapping (可能在订单= 0)

有关实现此解决方案的更多解释,请参阅相关的github项目

这是正确的,但那太复杂了。 您最好检查Host标头,它是否包含给定的子域。

但是你不应该真的需要这个超过一次或两次,所以你也可以在方法体中手动完成。 如果你真的需要它在很多地方,这将是一个奇怪的要求。