1

I'm experiencing a problem where multiple @RequestMappings around a common base path are not working as expected.

I've defined a class level mapping as follows:

@RestController
@RequestMapping( "/we/just/want/to" )
public class DoitController

with the following method mappings

@RequestMapping( path = "/doit", method = RequestMethod.GET )
public ResponseEntity<String> doitUsingQueryParams(
    @RequestParam( name = "abc", required = false ) String abc,
    @RequestParam( name = "def", required = false ) String def,
    HttpServletRequest request ) throws Exception
{
    ...
}

@RequestMapping( path = "/doit/{abc}", method = RequestMethod.GET )
public ResponseEntity<String> doitWithAbc(
        @PathVariable String abc,
        HttpServletRequest request ) throws Exception
{
    ...
}

@RequestMapping( path = "/doit/{abc}/{def}", method = RequestMethod.GET )
public ResponseEntity<String> doitWithAbcAndDef(
        @PathVariable String abc,
        @PathVariable String def,
        HttpServletRequest request ) throws Exception
{
    ...
}

When executing requests having one of the following paths

/we/just/want/to/doit/theabcvalue
/we/just/want/to/doit/theabcvalue/thedefvalue

the request mappings are not found (access log reveals that the request returns a 404). But running requests having path and query strings as follows

/we/just/want/to/doit?abc=theabcvalue 
/we/just/want/to/doit?abc=theabcvalue&def=thedefvalue

are found and map properly to the specified method.

I'm at a loss as to what I've done in correctly and would really appreciate any assistance provided.

Update - Fri Jan 27 16:01:21 UTC 2017

Interestingly, this code only manifests a problem when running as an executable jar on a Unix server. When running in Eclipse on my local Windows 7 laptop, each method executes properly. Here are the specifics of our server:

CentOS release 6.7 (Final)  
Linux <server_name_removed> 2.6.32-573.12.1.el6.x86_64 #1 SMP Tue Dec 15 21:19:08 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

Also note that the request mappings do appear in the log file output:

15:53:04,548 t=1485532384 tn=548000000 pid=2520 h=xx.xx.xx.110 lynx f=org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping l=534 lvl=INFO : Mapped "{[/we/just/want/to/doit],methods=[GET]}" onto public org.springframework.http.ResponseEntity<java.lang.String> com.xxxxxx.lynx.DoitController.doitUsingQueryParams(java.lang.String,java.lang.String,javax.servlet.http.HttpServletRequest) throws java.lang.Exception
15:53:04,548 t=1485532384 tn=548000000 pid=2520 h=xx.xx.xx.110 lynx f=org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping l=534 lvl=INFO : Mapped "{[/we/just/want/to/doit/{abc}],methods=[GET]}" onto public org.springframework.http.ResponseEntity<java.lang.String> com.xxxxxx.lynx.DoitController.doitWithAbc(java.lang.String,javax.servlet.http.HttpServletRequest) throws java.lang.Exception
15:53:04,549 t=1485532384 tn=549000000 pid=2520 h=xx.xx.xx.110 lynx f=org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping l=534 lvl=INFO : Mapped "{[/we/just/want/to/doit/{abc}/{def}],methods=[GET]}" onto public org.springframework.http.ResponseEntity<java.lang.String> com.xxxxxx.lynx.DoitController.doitWithAbcAndDef(java.lang.String,java.lang.String,javax.servlet.http.HttpServletRequest) throws java.lang.Exception
Ken Conway
  • 13
  • 5
  • As a note, you can just use `@GetMapping` in modern Spring, making this a lot simpler, and you should avoid passing in the request object if possible. – chrylis -cautiouslyoptimistic- Jan 26 '17 at 20:51
  • This looks like it *should* work just fine. Please turn up logging for `org.springframework.web` to DEBUG and post the list of mappings that it prints on startup. – chrylis -cautiouslyoptimistic- Jan 26 '17 at 20:52
  • I just tested your implementation. Everything works absolutely fine. 1) Check your context path. 2) Check whether the controller is under the `@ComponentScan` scope at all. – Branislav Lazic Jan 26 '17 at 21:10
  • Remember that you can always use Springs MockMvc to unit test your controller methods. See the accepted answer here for an example http://stackoverflow.com/questions/14563489/how-to-test-a-spring-controller-method-by-using-mockmvc – Michael Peacock Jan 26 '17 at 21:41
  • @chrylis no need to turn up logging to DEBUG to see the mappings, the default level (INFO) is enough http://stackoverflow.com/a/39162126/5873923. But that's the first thing to check indeed. – Marc Tarin Jan 27 '17 at 15:12
  • Thanks for the feedback so far. Please note the update above. @chrylis and Marc. I've inspected the log files and indeed the request mappings do appear in the spring framework log statements. – Ken Conway Jan 27 '17 at 16:09
  • @MarcTarin Thanks for the clarification. I turn it up so reflexively for debugging that I figured it was lower level than that. – chrylis -cautiouslyoptimistic- Jan 27 '17 at 18:11
  • Can you confirm for certain that you're talking *directly* to the embedded Tomcat server? You say "Unix server", and it's not clear what all differences of environment are entailed in "server" (especially if you have something like mod_rewrite in the mix). – chrylis -cautiouslyoptimistic- Jan 27 '17 at 18:12
  • @chrylis - Yes, I can confirm that I'm talking directly to the embedded Tomcat server (No proxy in front of it so no mod_rewrite in this case). – Ken Conway Jan 27 '17 at 19:23

0 Answers0