20

として、サブドメインマッピングを取り上げます。

この記事:同じアプリケーションのGoogle App Engineで複数のドメインとサブドメインを管理する には、フィルターでサブドメインを解決し、変数を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を許可する」)。

正しいですか?誰かがこの機能を実現するためのヒントを提供できますか?


アイデア1
元のjiraスレッドで提案されているように、独自の実装を作成することですRequestCondition

githubで利用可能なこのソリューションを使用するプロジェクトがあります:https ://github.com/rstoyanchev/spring-mvc-31-demo/

および関連するSOの質問:Springmvc3.1にカスタムRequestConditionを追加する

たぶん@Subdomain("www")、タイプとメソッドの両方のようにマッピングすることは、可能な解決策ですか?


forum.springsource.comの同じ質問へのリンク

4

2 に答える 2

33

参照されているspring-mvc-31-demoに基づいてソリューションを作成しました

このソリューションは、現時点では単一のRequestConditionのみをマップするために使用できます。通知する2つの問題を作成しました。これは変更する必要があります:https:
//github.com/rstoyanchev/spring-mvc-31-demo/issues/5
https://jira.springsource.org/browse/SPR-9350

このソリューションは、Spring3.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<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
    }
}

3つのファイルが必要です

  • 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<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要素
<mvc:annotation-driven/>で使用することはできません。説明についてはJIRAhttps://jira.springsource.org/browse/SPR-9344を参照してください。

  • SubdomainRequestMappingHandlerMappingこのカスタム実装クラスをポイントして、カスタムMappingHandlerBeanを登録する必要があります
  • 順序をデフォルトより低く設定するかRequestMappingHandlerMapping

    登録済みのものを置き換える必要がありますRequestMappingHandlerMapping(おそらくorder = 0)

このソリューションの実装に関するより広範な説明については、関連するgithubプロジェクトを参照してください。

于 2012-04-26T15:40:41.923 に答える
1

それは正しいですが、それは複雑すぎるでしょう。Hostヘッダーに特定のサブドメインが含まれているかどうかを確認することをお勧めします。

ただし、これは実際には1回または2回以上必要ではないため、メソッド本体で手動で行うこともできます。あなたが本当に多くの場所でそれを必要とするならば、それは奇妙な要件でしょう。

于 2012-04-25T10:00:58.163 に答える