gpt4 book ai didi

java - 如何实现@RequestMapping 自定义属性

转载 作者:IT老高 更新时间:2023-10-28 13:50:46 25 4
gpt4 key购买 nike

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

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

那么映射将如下所示:

@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 protected 方法
(如 JIRA 所述:“Allow custom request mapping conditions SPR-7812”)。

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


想法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

最佳答案

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

This solution can be used to map only single RequestCondition as of now. I've created two Issues to notify, this should be changed:
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<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
}
}

我们需要三个文件

  • 子域映射.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;
}

}

安装

IMPORTANT: So far, it is not possible to use this solution with XML element
<mvc:annotation-driven />, see JIRA https://jira.springsource.org/browse/SPR-9344 for explanation

  • 你要注册自定义 MappingHandler bean,指向这个自定义实现 SubdomainRequestMappingHandlerMapping
  • 你必须将它的顺序设置为低于默认的RequestMappingHandlerMapping

    替换注册的RequestMappingHandlerMapping(可能在order=0上)

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

关于java - 如何实现@RequestMapping 自定义属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10312177/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com