小编典典
我已经创建了基于引用的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:
@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;
}
}
安装方式
你必须注册自定义MappingHandler bean,指向此自定义实现SubdomainRequestMappingHandlerMapping类。
你必须将其订单设置为低于默认订单,RequestMappingHandlerMapping
或
替换已注册的RequestMappingHandlerMapping订单(可能在order = 0上)
有关实现此解决方案的更多说明,请参见相关的github项目。
2020-04-18