Spring REST:HttpServletRequest 的注入导致不明确的映射异常
Spring REST: Injection of HttpServletRequest results in ambiguous mapping exceptions
将 HttpServletRequest 或 HttpServletResponse 注入到 @RestController 中的 @RequestMapping 方法中 class 导致异常(至少在启用 @SpringBootTest 注释的测试中):
@RequestMapping(value = '/doc/{collection}/{id}/{attr}/', method = RequestMethod.POST)
void updateAttr(
@PathVariable(value = 'collection', required = true) String collection,
@PathVariable(value = 'id', required = true) String uuid,
@PathVariable(value = 'attr', required = true) String attr,
@RequestParam(value = 'async', required = false) Boolean async = false,
@RequestParamJSON(value = 'detail', required = false) Detail customDetailJSON,
HttpServletRequest request
) {
错误:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'apiController' method
public void ControllerClass.updateAttr(java.lang.String,java.lang.String,java.lang.String,java.lang.Boolean,cassdoc.Detail,javax.servlet.http.HttpServletRequest)
to {[/doc/{collection}/{id}/{attr}/],methods=[POST]}: There is already 'controllerClass' bean method
public void ControllerClass.updateAttr(java.lang.String,java.lang.String,java.lang.String,cassdoc.Detail,javax.servlet.http.HttpServletRequest) mapped.
这是 spring 中的错误吗?我做错了吗?我几乎确定地追踪到 HttpServletRequest 注入,而不是 @RequestParamJSON(自动反序列化 json 的 http 参数的自定义注释)通过消除过程并注意到没有 HttpRequest 或 HttpResponse 注入的其他方法方法参数按预期工作。
编辑:版本:
compile group: 'org.springframework', name: 'spring-web', version: '4.3.8.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-configuration-processor', version: '1.5.3.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: '1.5.3.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.3.RELEASE'
哦,我认为这不重要,但我使用的是 groovy 而不是 java。
你照顾好了吗
ServletInputStream being lost after reading once
问题。
我相信我知道答案。我认为这是因为我正在使用 groovy 并在参数中使用了一些默认值。
我相信这会让 groovy 自动创建多个具有相同注释映射的方法签名。
然后在启动时不透明地破坏请求映射并产生冲突。
在上面的示例中,async = false 默认设置是导致错误的原因
将 HttpServletRequest 或 HttpServletResponse 注入到 @RestController 中的 @RequestMapping 方法中 class 导致异常(至少在启用 @SpringBootTest 注释的测试中):
@RequestMapping(value = '/doc/{collection}/{id}/{attr}/', method = RequestMethod.POST)
void updateAttr(
@PathVariable(value = 'collection', required = true) String collection,
@PathVariable(value = 'id', required = true) String uuid,
@PathVariable(value = 'attr', required = true) String attr,
@RequestParam(value = 'async', required = false) Boolean async = false,
@RequestParamJSON(value = 'detail', required = false) Detail customDetailJSON,
HttpServletRequest request
) {
错误:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'apiController' method
public void ControllerClass.updateAttr(java.lang.String,java.lang.String,java.lang.String,java.lang.Boolean,cassdoc.Detail,javax.servlet.http.HttpServletRequest)
to {[/doc/{collection}/{id}/{attr}/],methods=[POST]}: There is already 'controllerClass' bean method
public void ControllerClass.updateAttr(java.lang.String,java.lang.String,java.lang.String,cassdoc.Detail,javax.servlet.http.HttpServletRequest) mapped.
这是 spring 中的错误吗?我做错了吗?我几乎确定地追踪到 HttpServletRequest 注入,而不是 @RequestParamJSON(自动反序列化 json 的 http 参数的自定义注释)通过消除过程并注意到没有 HttpRequest 或 HttpResponse 注入的其他方法方法参数按预期工作。
编辑:版本:
compile group: 'org.springframework', name: 'spring-web', version: '4.3.8.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-configuration-processor', version: '1.5.3.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: '1.5.3.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.3.RELEASE'
哦,我认为这不重要,但我使用的是 groovy 而不是 java。
你照顾好了吗
ServletInputStream being lost after reading once
问题。
我相信我知道答案。我认为这是因为我正在使用 groovy 并在参数中使用了一些默认值。
我相信这会让 groovy 自动创建多个具有相同注释映射的方法签名。
然后在启动时不透明地破坏请求映射并产生冲突。
在上面的示例中,async = false 默认设置是导致错误的原因