首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何实现@RequestMapping自定义属性

如何实现@RequestMapping自定义属性
EN

Stack Overflow用户
提问于 2012-04-25 16:38:38
回答 2查看 26.1K关注 0票数 20

作为示例,以子域映射为例。

本文:Managing multiple Domain and Sub Domain on Google App Engine for Same Application建议在过滤器上解析子域,并将变量分配给ServletRequest标头。

然后,映射将如下所示:

代码语言:javascript
复制
@RequestMapping(value = "/path", headers="subdomain=www")
 public String subsiteIndexPage(Model model,HttpServletRequest request) { ... }

如果我们想创建自定义的@RequestMapping属性,比如subdomain,例如。要创建如下映射,请执行以下操作:

代码语言:javascript
复制
@RequestMapping(value = "/some/action", subdomain = "www")
public String handlerFunction(){ ... }

我们应该用我们自己的实现覆盖@RequestMapping @interface定义和覆盖RequestMappingHandlerMapping保护的方法

(如JIRA上所述:"Allow custom request mapping conditions SPR-7812")。

是对的吗?有没有人能提供一个提示,如何实现这个功能?

Idea 1

正如在最初的jira线程中所建议的,是创建自己的RequestCondition实现

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

以及相关的SO问题:Adding custom RequestCondition's in Spring mvc 3.1

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

Link to same question on forum.springsource.com

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-26 23:40:42

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

到目前为止,此解决方案只能用于映射单个RequestCondition。我已经创建了两个要通知的问题,应该进行更改:

https://github.com/rstoyanchev/spring-mvc-31-demo/issues/5

https://jira.springsource.org/browse/SPR-9350

此解决方案使用Spring3.1.1.RELEASE platform的自定义@RequestCondition功能

使用

示例1:

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

示例2:

代码语言:javascript
复制
@Controller
class 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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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 (可能在order=0上)

有关实现此解决方案的更多详细说明,请参阅相关的项目

票数 33
EN

Stack Overflow用户

发布于 2012-04-25 18:00:58

这是正确的,但这太复杂了。你最好检查一下Host头,看看它是否包含一个给定的子域。

但是您实际上不应该需要超过一次或两次,因此您也可以在方法体中手动执行此操作。如果你真的需要它在很多地方,这将是一个奇怪的要求。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10312177

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档