Affects: 5.3.22


According to my understanding of the Spring MVC documentation, annotating a controller method with @RequestMapping(method=X) has a narrowing effect on @RequestMapping applied to the controller class. To quote from the docs:

public abstract RequestMethod[] method The HTTP request methods to map to, narrowing the primary mapping: GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE. Supported at the type level as well as at the method level! When used at the type level, all method-level mappings inherit this HTTP method restriction.

Yet, with Http method, this doesn't seem to be the case - it seems that if both class and method are annotated with @RequestMapping, and both annotations have a method parameter, the method will be used to serve HTTP request of HTTP methods pertaining to the union of the annotations.

For example this passes:

@RestController
@RequestMapping(value = "/multi", method = RequestMethod.POST)
public class MultiAnno {
    @RequestMapping(value = "/rm", method = RequestMethod.PATCH)
    public String getFoo() {
        return "Foo";
    }
}

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MvcConfig.class)
@WebAppConfiguration
@AutoConfigureWebClient
public class MappingsExampleIntegrationTest {

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    @Test
    public void whenMultiRM() throws Exception{
        mockMvc.perform(post("/multi/rm"))
                .andExpect(status().isOk());
        mockMvc.perform(patch("/multi/rm"))
                .andExpect(status().isOk());
        mockMvc.perform(put("/multi/rm"))
                .andExpect(status().is(not(HttpStatus.OK)));
    }
}

Comment From: mdeinum

Isn't that exactly what the javadoc states? It will be the union of both so in this case the URL will be /multi/rm and the supported methods will be POST and PATCH (as each @RequestMapping annotated mapping will inherit the settings from the class, these will be merged together to get what the test shows).

Comment From: urisimchoni

I guess I misread the docs. The Spring documentation states that (1.3.2) @RequestMapping is used "...at the method level to narrow down to a specific endpoint mapping." The Javadocs state the "method" element is used for narrowing the primary mapping. So I understood that the mapping is narrowed once by the type-level annotation, and then further narrowed by the method level annotation. Issue can be closed as far as I'm concerned.