繁体   English   中英

Spring MVC @RequestMapping继承

[英]Spring MVC @RequestMapping Inheritance

来自Struts2我习惯在超类(或者package-info.java )上声明@Namespace注释,继承类随后将获取其祖先的@Namespace注释中的值,并将其添加到请求路径中行动。 我现在尝试使用@RequestMapping注释在Spring MVC中执行类似的操作,如下所示(为简洁起见,代码已修剪):

package au.test

@RequestMapping(value = "/")
public abstract class AbstractController {
    ...
}

au.test.user

@RequestMapping(value = "/user")
public abstract class AbstractUserController extends AbstractController {

    @RequestMapping(value = "/dashboard")   
    public String dashboard() {
        ....
    }
}

au.test.user.twitter

@RequestMapping(value = "/twitter")
public abstract class AbstractTwitterController extends AbstractUserController {
    ...
}

public abstract class TwitterController extends AbstractTwitterController {

    @RequestMapping(value = "/updateStatus")    
    public String updateStatus() {
        ....
    }
}
  • /按预期工作
  • /user/dashboard按预期工作
  • 但是,当我希望/user/twitter/updateStatus工作时它没有并检查日志我可以看到一个类似于的日志条目:

org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - 映射的URL路径[/ tweeter / updateStatus]到处理程序'twitterController'上

是否有一个我可以启用的设置,它将扫描超类的@RequestMapping注释并构造正确的路径?

另外我认为在package-info.java中定义@RequestMapping包是非法的吗?

以下基本上成为/tweeter/updateStatus而不是/user/tweeter/updateStatus

public abstract class TwitterController extends AbstractTwitterController {

    @RequestMapping(value = "/updateStatus")    
    public String updateStatus() {
        ....
    }
}

这是预期的行为,因为您已经覆盖了您在AbstractControllerAbstractUserController声明的原始@RequestMapping

实际上,当您声明AbstractUserController时,它还会覆盖AbstractController@RequestMapping 它只是给你一个幻觉,即来自AbstractController的/已被继承。

“我是否可以启用一个设置来扫描超类以获取@RequestMapping注释并构建正确的路径?” 从来没听说过。

根据在启动修改@RequestMappings中解释的技术,是的,可以以您想要的方式从超类构造URL模式。

实质上,您必须继承RequestMappingHandlerMapping (很可能,它将是您的HandlerMapping实现,但请先检查)并覆盖受保护的getMappingForMethod方法。 一旦这变得可行,您就可以完全控制URL模式生成。

从您给出的示例中可以看出确切的合并策略并不完全清楚,例如,如果超类AbstractTwitterController还使用自己的@RequestMapping实现updateStatus()方法,您希望获得什么路径,或者您希望如何连接URL模式层次结构,自上而下或自下而上,(我假设前者在下面),但是,希望以下代码片段能给你一些想法:

    private static class PathTweakingRequestMappingHandlerMapping extends RequestMappingHandlerMapping {

                @Override
                protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
                    RequestMappingInfo methodMapping = super.getMappingForMethod(method, handlerType);
                    if (methodMapping == null)
                        return null;
                    List<String> superclassUrlPatterns = new ArrayList<String>();
                    boolean springPath = false;
                    for (Class<?> clazz = handlerType; clazz != Object.class; clazz = clazz.getSuperclass())
                        if (clazz.isAnnotationPresent(RequestMapping.class))
                            if (springPath)
                                superclassUrlPatterns.add(clazz.getAnnotation(RequestMapping.class).value()[0]);// TODO handle other elements in the array if necessary
                            else
                                springPath = true;
                    if (!superclassUrlPatterns.isEmpty()) {
                        RequestMappingInfo superclassRequestMappingInfo = new RequestMappingInfo("",
                                new PatternsRequestCondition(String.join("", superclassUrlPatterns)), null, null, null, null, null, null);// TODO implement specific method, consumes, produces, etc depending on your merging policies
                        return superclassRequestMappingInfo.combine(methodMapping);
                    } else
                        return methodMapping;
                }
    }

另一个好问题是如何拦截RequestMappingHandlerMapping的实例化。 在因特网中,存在许多用于各种配置策略的各种示例。 但是,使用JavaConfig,请记住,如果在@Configuration集中提供WebMvcConfigurationSupport ,那么@EnableWebMvc (显式或隐式)将停止工作。 我最终得到了以下内容:

@Configuration
public class WebConfig extends DelegatingWebMvcConfiguration{

    @Configuration
    public static class UnconditionalWebMvcAutoConfiguration extends WebMvcAutoConfiguration {//forces @EnableWebMvc 
    }

    @Override
    protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
        return new PathTweakingRequestMappingHandlerMapping();
    }

    @Bean
    @Primary
    @Override
    public RequestMappingHandlerMapping requestMappingHandlerMapping() { 
        return super.requestMappingHandlerMapping();
    }

}

但是想了解更好的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM