我已经创建了基于引用的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平台的自定义@RequestCondition功能
用法
范例1:
@Controller@SubdomainMapping(value = "subdomain", tld = ".mydomain.com")class MyController1 { // Code here will be executed only on address match: // subdomain.mydomain.com}范例2:
@Controllerclass MyController2 { @RequestMapping("/index.html") @SubdomainMapping("www") public function index_www(Map<Object, String> map){ // on www.domain.com // where ".domain.com" is defined in SubdomainMapping.java } @RequestMapping("/index.html") @SubdomainMapping("custom") public function index_custom(Map<Object, String> 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 { String[] value() default {}; 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<SubdomainRequestCondition> { private final Set<String> subdomains; private final String tld; public SubdomainRequestCondition(String tld, String... subdomains) { this(tld, Arrays.asList(subdomains)); } public SubdomainRequestCondition(String tld, Collection<String> subdomains) { this.subdomains = Collections.unmodifiableSet(new HashSet<String>( subdomains)); this.tld = tld; } @Override public SubdomainRequestCondition combine(SubdomainRequestCondition other) { Set<String> allRoles = new linkedHashSet<String>(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元素
- 你必须注册自定义
MappingHandler bean
,指向此自定义实现SubdomainRequestMappingHandlerMapping类。 - 你必须将其订单设置为低于默认订单,
RequestMappingHandlerMapping
或
替换已注册的RequestMappingHandlerMapping
订单(可能在order = 0上)
有关实现此解决方案的更多说明,请参见相关的github项目。



