自定义Spring的@Get注解遇映射冲突,如何实现类似@GetMapping?
自定义@Get注解出现Spring映射冲突的解决方法
问题重现
自定义的@Get注解代码如下:
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) @Retention(RetentionPolicy.RUNTIME) @Documented @RequestMapping(method = [RequestMethod.GET]) @ResponseBody annotation class Get(vararg val value: String = []) @RestController class Ctrl { @Get("/test-get") fun testGet(): String { return "test get" } @Get("/test-get2") fun testGet2(): String { return "test get" } } @SpringBootApplication class Server internal class SpringTestHelperTest { @Test fun testTestServer() { runApplication<Server>() var h = Http() println(h.get("/test-get").body) println(h.get("/test-get2").body) } }
运行时抛出映射冲突错误:
Ambiguous mapping. Cannot map 'ctrl' method
ktlibspring.Ctrl#testGet()
to {GET [/]}: There is already 'ctrl' bean method
ktlibspring.Ctrl#testGet2() mapped.
问题原因
Spring内置的@GetMapping能正常工作,核心是它通过@AliasFor注解将自身的value属性与@RequestMapping的value属性做了别名绑定,让Spring可以正确识别指定的路径参数。
而你自定义的@Get注解仅声明了value属性,但未与@RequestMapping的value建立关联,导致Spring无法读取你设置的/test-get、/test-get2路径,最终两个方法都默认映射到根路径/,引发冲突。
正确实现方式
修改@Get注解,使用@AliasFor将自定义的value属性与@RequestMapping的value属性绑定:
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) @Retention(RetentionPolicy.RUNTIME) @Documented @RequestMapping(method = [RequestMethod.GET]) @ResponseBody annotation class Get( @get:AliasFor(annotation = RequestMapping::class) vararg val value: String = [] )
完成修改后,Spring就能正确识别@Get注解指定的路径,两个方法会分别映射到/test-get和/test-get2,不会再出现映射冲突。
内容的提问来源于stack exchange,提问作者chikadance
相关产品推荐
相关产品推荐

