0

The injection of the HttpServletRequest or HttpServletResponse into a @RequestMapping method in a @RestController class results in exceptions (at least in the @SpringBootTest annotation-enabled test):

@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
) {

error:

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.

Is this a bug in spring? Am I doing it wrong? I have almost-definitively tracked it down to the HttpServletRequest injection, not the @RequestParamJSON (a custom annotation that autodeserializes http params that are json) by process of elimination and noticing that other methods without the HttpRequest or HttpResponse injected into the method params work as expected.

Edit: versions:

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'

Oh, and I don't think it matters, but I am using groovy not java.

  • What is `apiController` – arahant Jun 15 '17 at 19:52
  • I am obfuscating the full code path. This is javaconfig, autowires, no XML at all. If I comment out the @RequestMapping, it works just fine. apiController was the name of the class pre-obfuscation. – Constance Eustace Jun 15 '17 at 20:02
  • can you show url mappings that you have in controller that are similar to /doc/{collection}/{id}/{attr} ? – xyz Jun 15 '17 at 20:03
  • "f I comment out the @RequestMapping, it works just fine" - you have same url mapping . you have mapping similar or exactly to "/doc/{collection}/{id}/{attr}/" – xyz Jun 15 '17 at 20:03
  • SOrry, I misspoke. If I comment out the @RequestParam annotations, it works fine. – Constance Eustace Jun 15 '17 at 20:12
  • just for check , try /doc/ replace with /doctest/. it sprign did't fail with with controller mapping then you have somewhere url duplicate – xyz Jun 15 '17 at 20:42
  • I tried /xxx and /yyy and /zzz, etc etc, making each RequestMapping on my controllers completely unique. That didn't help. – Constance Eustace Jun 15 '17 at 21:03
  • check all the @RequestMapping annotations in your project.. you should be able to figure it out the duplicate one. – Siva Atta Jun 16 '17 at 04:45

2 Answers2

0

Have you taken care of

ServletInputStream being lost after reading once

issue. Http Servlet request lose params from POST body after read it once

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/util/ContentCachingRequestWrapper.html

so-random-dude
  • 15,277
  • 10
  • 68
  • 113
  • Hm, my issue is occurring on the autowiring phase of the spring startup while constructing the ApplicationContext, but maybe spring is trying to do gymnastics with the annotations to avoid issues like this... – Constance Eustace Jun 16 '17 at 03:14
0

I believe I know the answer. I think it is because I am using groovy and used some default values in the parameters.

This I believe makes groovy automatically create several method signatures with the same annotated mapping.

That then opaquely blows up the request mappings with conflicts at startup.

In the above example the async = false defaulting is what is causing the error