【发布时间】:2016-09-17 05:14:34
【问题描述】:
是否可以在启动时更改@RequestMapping 的值?
基本上我想要的是创建一个注释@Api(Api.Version.V1),这意味着应该将请求映射从/api/dogs修改为/api/v1/dogs。我想在类级别(适用于所有)和方法级别(重新使用早期版本的控制器并对其进行修改)都这样做。
我可以把它硬编码进去,但这会留下很多字符串需要处理,而且它不像我想要的那样干净。
那么是否有可能(使用 bpp 或类似的东西)在启动期间更改请求映射?创建 bean 后,我不想/不需要修改它们。
我也一直在研究RequestCondition,但这似乎具有更动态的性质,我不确定在这种情况下它是否会对我有所帮助。
另一个问题,我希望能够用相同的请求映射注释两个类(然后让注释重写它),我很确定这需要在初始上下文加载时完成(所以我们不' t 得到重复的映射等)。
任何正确方向的指针将不胜感激。
编辑:
这几乎可以工作了,我正在使用自定义 RequestMappingHandlerMapping 并覆盖方法 getMappingForMethod,它允许我获取注释(在类型和方法上)并返回修改后的 RequestMappingInfo 并添加了路径.
一个问题仍然存在,即使我删除了所有旧映射并且只返回 /api/v1/dogs 旧映射到 /api/dogs 仍然有效。是否也可以以某种方式删除此映射?
代码在这里,如果有人感兴趣的话。
@Component
public class CustomRequestMappingHandlerMapping
extends RequestMappingHandlerMapping
{
@Override
protected RequestMappingInfo getMappingForMethod( Method method, Class<?> handlerType )
{
RequestMappingInfo info = super.getMappingForMethod( method, handlerType );
ApiVersion methodApiVersion = AnnotationUtils.findAnnotation( method, ApiVersion.class );
ApiVersion typeApiVersion = AnnotationUtils.findAnnotation( handlerType, ApiVersion.class );
if ( typeApiVersion == null )
{
return info;
}
Set<String> oldPatterns = info.getPatternsCondition().getPatterns();
Set<String> patterns = new HashSet<>();
for ( String p : oldPatterns )
{
for ( int v = 0; v < typeApiVersion.value().length; v++ )
{
ApiVersion.Version version = typeApiVersion.value()[v];
if ( !p.startsWith( version.getValue() ) )
{
if ( p.startsWith( "/" ) ) patterns.add( "/" + version.getValue() + p );
else patterns.add( "/" + version.getValue() + "/" + p );
}
else
{
patterns.add( p );
}
}
}
PatternsRequestCondition patternsRequestCondition = new PatternsRequestCondition(
patterns.toArray( new String[]{} ), null, null, true, true, null );
RequestMappingInfo mappingInfo = new RequestMappingInfo(
null, patternsRequestCondition, info.getMethodsCondition(), info.getParamsCondition(), info.getHeadersCondition(), info.getConsumesCondition(),
info.getProducesCondition(), info.getCustomCondition()
);
return mappingInfo;
}
}
【问题讨论】:
-
问题在于我使用的是
<mvc:annotation-driven />,它还注册了默认的RequestMappingHandlerMapping,所以那里发生了冲突。
标签: spring spring-mvc