Comment mettre en œuvre les propriétés personnalisées de @RequestMapping

exemple, prendre cartographie des sous-domaines.

Cet article: gestion de plusieurs domaines et sous-domaines sur Google App Engine pour la même Application recommande de résoudre le sous-domaine sur Filter et d'assigner la variable aux en-têtes ServletRequest.

le mappage ressemblera à ceci:

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

si nous voulons créer une propriété custom @RequestMapping, telle que subdomain, par exemple. pour créer la cartographie comme ceci:

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

nous devrions remplacer @RequestMapping @interface définition et outrepasser RequestMappingHandlerMapping méthodes protégées, avec notre propre implémentation

(comme indiqué sur JIRA:"Autoriser des requêtes personnalisées sur les conditions de mappage SPR-7812").

Est-il de droite? Est-ce que quelqu'un peut fournir un indice, comment réaliser cette fonctionnalité?


idée 1:

Comme suggéré sur le fil original jira, est de créer de la mise en œuvre de RequestCondition

il y a un projet qui utilise cette solution disponible sur github:https://github.com/rstoyanchev/spring-mvc-31-demo/

Et SI question: ajouter des conditions de Request personnalisées au printemps mvc 3.1

peut-être cartographier comme @Subdomain("www") pour le Type et la méthode, est-ce que la solution est possible?


Lien vers la même question sur forum.springsource.com

18
demandé sur Community 2012-04-25 12:38:37

2 réponses

j'ai créé la solution basée sur référencé spring-mvc-31-demo

Cette solution peut être utilisée pour mapperune seule condition request à partir de Maintenant. J'ai créé deux Questions à notifier, ce devrait être changed:

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

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

cette solution utilise des La fonctionnalité @RequestCondition du printemps 3.1.1.LIBÉRER la plate-forme

USAGE

exemple 1:

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

exemple 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
    }
}

Nous avons besoin de trois les fichiers

  • sous-Domainemapping.java
  • SubdomainRequestCondition.java
  • SubdomainRequestMappingHandlerMapping.java

sous-Domainemapping.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;
    }

}

Installation

IMPORTANT: Jusqu'à présent, il n'est pas possible d'utiliser cette solution avec XML element

, voir JIRA https://jira.springsource.org/browse/SPR-9344 explication

  • vous devez enregistrer custom MappingHandler bean, pointant vers cette implémentation custom SubdomainRequestMappingHandlerMapping classe
  • vous devez définir son ordre pour être inférieur à la valeur par défaut RequestMappingHandlerMapping

    OR

    Remplacer le régime enregistré d' RequestMappingHandlerMapping (éventuellement sur commande=0)

pour plus d'explications sur la mise en oeuvre de cette solution, voir le projet GitHub connexe

26
répondu Marek Sebera 2012-04-27 08:36:05

C'est exact, mais ce serait trop compliqué. Vous feriez mieux de vérifier l' Host en-tête, s'il contient un sous-domaine.

mais vous ne devriez pas vraiment avoir besoin de cela plus d'une fois ou deux, donc vous pouvez aussi le faire manuellement dans le corps de la méthode. Si vous en avez vraiment besoin dans de nombreux endroits, il serait étrange exigence.

2
répondu Bozho 2012-04-25 10:00:58