【问题标题】:Modifying @RequestMappings on startup启动时修改@RequestMappings
【发布时间】: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;
    }
}

【问题讨论】:

  • 问题在于我使用的是&lt;mvc:annotation-driven /&gt;,它还注册了默认的RequestMappingHandlerMapping,所以那里发生了冲突。

标签: spring spring-mvc


【解决方案1】:

您可以通过实现HandlerMapping 接口或扩展AbstractUrlHandlerMapping 来动态添加requestMappings。

这个想法是创建自己的自定义处理程序映射,而不是使用默认实现,例如 SimpleUrlHandlerMapping,DefaultAnnotationHandlerMapping

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多