来自Struts2我习惯于@Namespace在超类(或package-info.java)上声明注释,继承类随后将获取@Namespace其祖先注释中的值,并将其添加到Action的请求路径中.我现在尝试使用@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() {
....
}
}
Run Code Online (Sandbox Code Playgroud)
/ 按预期工作/user/dashboard 按预期工作/user/twitter/updateStatus工作时它没有并检查日志我可以看到一个类似于的日志条目:org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - 映射的URL路径[/ tweeter/updateStatus]到处理程序'twitterController'上
是否有一个我可以启用的设置,它将扫描超类的@RequestMapping注释并构造正确的路径?
另外我认为@RequestMapping在包装上定义package-info.java是非法的?
chr*_*ris 27
以下基本上变成了/tweeter/updateStatus而不是/user/tweeter/updateStatus
public abstract class TwitterController extends AbstractTwitterController {
@RequestMapping(value = "/updateStatus")
public String updateStatus() {
....
}
}
Run Code Online (Sandbox Code Playgroud)
这是预期的行为,因为你已经覆盖了@RequestMapping你在AbstractController和中声明的原始内容AbstractUserController.
事实上,当你声明AbstractUserController它也覆盖了@RequestMappingfor AbstractController.它只是给你一种幻觉,即来自AbstractController遗传.
"我可以启用@RequestMapping哪个设置来扫描超类的注释并构建正确的路径?" 从来没听说过.
根据在启动时修改@RequestMappings中介绍的技术,可以,可以用您想要的方式从超类构造URL模式。
本质上,您必须将RequestMappingHandlerMapping子类化(很可能是您的HandlerMapping实现,但是请先检查),然后重写受保护的getMappingForMethod方法。一旦这变得可行,就可以完全控制URL模式的生成。
从您给出的示例中,您还不能完全清楚确切的合并策略,例如,如果超类AbstractTwitterController也updateStatus()使用自己的方法实现方法,那么您想要的路径是什么@RequestMapping,或者您想如何在整个层次结构中串联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;
}
}
Run Code Online (Sandbox Code Playgroud)
另一个好问题是如何截获的实例化RequestMappingHandlerMapping。在Internet中,有许多用于各种配置策略的示例。但是,使用JavaConfig时,请记住,如果您WebMvcConfigurationSupport在@Configuration集合中提供,则@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();
}
}
Run Code Online (Sandbox Code Playgroud)
但想了解更好的方法。
| 归档时间: |
|
| 查看次数: |
27655 次 |
| 最近记录: |