RESTful servlet URLs - servlet-mapping in web.xml

John Strickler picture John Strickler · Apr 3, 2012 · Viewed 7.7k times · Source

I feel like this is a common problem but nothing I've researched has worked yet...

In my web.xml I have a mapping for all REST calls -

  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>

This works well if the URL is -

GET /rest/people

but fails if it is

GET /rest/people/1

I get a 400 Bad Request error saying The request sent by the client was syntactically incorrect (). I'm not sure it even made it to the Spring servlet to get routed...

How can I wildcard anything that starts with /rest so that it can be handled appropriately?

In other words, I'd like for all of the following to be valid -

GET /rest/people
GET /rest/people/1
GET /rest/people/1/phones
GET /rest/people/1/phones/23

Edit - Controller code as requested

@Controller
@RequestMapping("/people")
public class PeopleController {

    @RequestMapping(method=RequestMethod.GET)
    public @ResponseBody String getPeople() {
        return GsonFactory.getInstance().toJson(LookupDao.getInstance().getPeople());
    }

    @RequestMapping(value="{id}", method=RequestMethod.GET)
    public @ResponseBody String getPerson(@PathVariable String id) {
        return GsonFactory.getInstance().toJson(LookupDao.getInstance().getPerson(id));
    }
}

Answer

@matsev It didn't seem to matter if I had the / there or not.

While I was transposing the variable names for public view I changed a couple things to make it work.

Original

@RequestMapping(value="{id}", method=RequestMethod.GET)
public @ResponseBody String getPerson(@PathVariable String userId) {
    return GsonFactory.getInstance().toJson(LookupDao.getInstance().getPerson(userId));
}

What I posted

@RequestMapping(value="{id}", method=RequestMethod.GET)
public @ResponseBody String getPerson(@PathVariable String id) {
    return GsonFactory.getInstance().toJson(LookupDao.getInstance().getPerson(id));
}

The variable name mismatch did me in... I leave this here as a warning to all... match your variable names!

Answer

matsev picture matsev · Apr 3, 2012

Try add a /before the {id}:

@RequestMapping(value="/{id}", method=RequestMethod.GET)

Without it, the id will be appended directly to the people url, e.g /rest/people1 as opposed to /rest/people/1.