Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何实现@RequestMapping自定义属性_Java_Spring_Servlets_Spring Mvc - Fatal编程技术网

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

Java 如何实现@RequestMapping自定义属性,java,spring,servlets,spring-mvc,Java,Spring,Servlets,Spring Mvc,作为示例,以子域映射为例 本文: 建议在筛选器上解析子域并将变量分配给ServletRequest标头 然后映射将如下所示: @RequestMapping(value = "/path", headers="subdomain=www") public String subsiteIndexPage(Model model,HttpServletRequest request) { ... } @RequestMapping(value = "/some/action", subdomai

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

本文: 建议在筛选器上解析子域并将变量分配给ServletRequest标头

然后映射将如下所示:

@RequestMapping(value = "/path", headers="subdomain=www")
 public String subsiteIndexPage(Model model,HttpServletRequest request) { ... }
@RequestMapping(value = "/some/action", subdomain = "www")
public String handlerFunction(){ ... }
如果我们想创建自定义@RequestMapping属性,如subdomain,例如创建如下映射:

@RequestMapping(value = "/path", headers="subdomain=www")
 public String subsiteIndexPage(Model model,HttpServletRequest request) { ... }
@RequestMapping(value = "/some/action", subdomain = "www")
public String handlerFunction(){ ... }
我们应该用自己的实现覆盖
@RequestMapping@interface
定义和覆盖RequestMappingHandlerMapping受保护的方法
(如JIRA所述:)

是这样吗?有谁能提供一个提示,如何实现这个功能


想法1
正如最初的jira线程所建议的,是创建自己的
RequestCondition

github上有一个使用此解决方案的项目:

及有关问题:

也许像
@Subdomain(“www”)
这样的类型和方法映射是可能的解决方案



那是正确的,但那太复杂了。您最好检查
Host
头,看它是否包含给定的子域


但是您实际上不应该不止一次或两次需要它,所以您也可以在方法体中手动执行。如果您在许多地方确实需要它,那么这将是一个奇怪的要求。

我已经根据参考文献创建了解决方案

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

此解决方案使用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<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
    }
}
SubdomainRequestCondition.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";
}
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();
    }

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

}
import java.net.URL;
导入java.util.array;
导入java.util.Collection;
导入java.util.Collections;
导入java.util.HashSet;
导入java.util.LinkedHashSet;
导入java.util.Set;
导入javax.servlet.http.HttpServletRequest;
导入org.springframework.web.servlet.mvc.condition.RequestCondition;
公共类SubdomainRequestCondition实现
请求条件{
私有最终集子域;
专用最终字符串tld;
公共子域RequestCondition(字符串tld、字符串…子域){
这(tld,Arrays.asList(子域));
}
公共子域RequestCondition(字符串tld、集合子域){
this.subdomains=Collections.unmodifiableSet(新哈希集(
子域);
this.tld=tld;
}
@凌驾
公共SubdomainRequestCondition合并(SubdomainRequestCondition其他){
Set allRoles=newlinkedhashset(this.subdomains);
allRoles.addAll(其他.subdomains);
返回新的SubdomainRequestCondition(tld,allRoles);
}
@凌驾
公共子域请求条件getMatchingCondition(
HttpServletRequest(请求){
试一试{
URL uri=新URL(request.getRequestURL().toString());
String[]parts=uri.getHost().split(this.tld);
如果(parts.length==1){
for(字符串s:this.subdomains){
if(s.equalsIgnoreCase(第[0]部分)){
归还这个;
}
}
}
}捕获(例外e){
e、 printStackTrace(System.err);
}
返回null;
}
@凌驾
公共int比较(子域请求条件其他,
HttpServletRequest(请求){
返回org.apache.commons.collections.CollectionUtils.removeAll(other.subdomains,this.subdomains.size();
}
}
子域RequestMappingHandlerMapping.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";
}
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();
    }

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

}
import java.lang.reflect.Method;
导入org.springframework.core.annotation.AnnotationUtils;
导入org.springframework.web.servlet.mvc.condition.RequestCondition;
导入org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
公共类CustomRequestMappingHandlerMapping扩展
RequestMappingHandlerMapping{
@凌驾
受保护的RequestCondition getCustomTypeCondition(类handlerType){
SubdomainMapping typeAnnotation=AnnotationUtils.FindAnotation(
handlerType,SubdomainMapping.class);
返回createCondition(typeAnnotation);
}
@凌驾
受保护的RequestCondition getCustomMethodCondition(方法){
SubdomainMapping methodAnnotation=AnnotationUtils.FindAnotation(
方法,SubdomainMapping.class);
返回createCondition(methodAnnotation);
}
private RequestCondition createCondition(子域映射accessMapping){
返回(accessMapping!=null)?新建子域RequestCondition(
accessMapping.tld(),accessMapping.value()):null;
}
}
安装

重要提示:到目前为止,无法将此解决方案与XML元素一起使用
,请参见JIRA了解解释

  • 您必须注册自定义MappingHandler bean,指向此自定义实现
    SubdomainRequestMappingHandlerMapping
  • 您必须将其顺序设置为低于默认值
    RequestMappingHandlerMapping


    替换已注册的
    RequestMappingHandlerMapping
    (可能按订单=0)

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

odd以何种方式?与许多Url重写规则相比,它可能给了我更好的控制。例如,如果您有一个平台,您需要根据经过身份验证的角色(管理员、经理、用户)区分操作,并且您可以有映射,例如
/admin/*
/manager/*
,等等。。或者您可以使用
admin.domain.tld/*
manager.domain.tld/*
,…请参阅相关建议1。M