We have a servlet defined in our web.xml
:
<servlet>
<servlet-name>foo</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>foo</servlet-name>
<url-pattern>/foo/*</url-pattern>
</servlet-mapping>
In our controller class, we use both @RequestMapping
and @RestController
.
package com.example.foo;
@RestController("/foo/bar/v1")
public class Baz {
@RequestMapping(value="/bar/v1/abc" /* ... */)
public String doXyz() {
Now, I know the Spring documentation for RequestMapping says
When used at the type level, all method-level mappings inherit this primary mapping, narrowing it for a specific handler method.
In other words, when I define a @RequestMapping("/foo")
on class level, anything I define on the method level would be appended. For the example above, if the path was defined in a @RequestMapping("/foo/bar/v1")
on class level, instead of in the @RestController
, I would thus expect /foo/bar/v1/bar/v1/abc
- or /foo/bar/v1/abc
if the path on the method were relative. Is that understanding of mine correct?
Now, apparently, @RestController("/foo/bar/v1")
has the same effect as @RequestMapping("/foo/bar/v1")
in terms of request path mapping - is that observation correct, too?
If not, why does above code still work? Is the /foo/
part picked up from the web.xml
?
Now, if I leave the code as is, the following test fails:
MvcResult result = mockMvc.perform(
get("/foo/bar/v1")
.accept(MediaType.APPLICATION_JSON_VALUE) //...
My guess is it fails because
- it doesn't read the web.xml, hence doesn't know about the
/foo
prefix - the path in
@RequestMapping("bar/v1")
on the method level doesn't actually narrow down the one in@restController("/foo/bar/v1")
after all.
The error message I get is
javax.servlet.ServletException: No adapter for handler [com.example.foo.Baz@5b800468]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler
This is what the context config looks like that the test loads (besides @WebAppConfiguration
):
<context:annotation-config/>
<mvc:annotation-driven/>
<context:component-scan base-package="com.example.foo" />
How do the annotations and web.xml
really work together, and what do I need to configure to make the test pass?