Bryan
Bryan

Reputation: 95

How to properly manage PathVariables with spring

I'm hoping this isn't too simple of a question. I'm new to the java web services world and cant seem to get access to my PathVariables in my controller. I'm using STS and it's not complaining that my syntax is wrong.

So more important than the correct answer, I'd really like to know why this isn't working.

Here's some example code that I cant get to work:

@RestController
public class TestController {

    @RequestMapping("/example")
    public String doAThing(
        @PathVariable String test
    ) throws MessagingException {
        return "Your variable is " + test;
    }
}

If I run a curl against it like so:

curl http://localhost:8080/example?test=foo

I receive the following response:

{"timestamp":1452414817725,"status":500,"error":"Internal Server Error","exception":"org.springframework.web.bind.MissingPathVariableException","message":"Missing URI template variable 'test' for method parameter of type String","path":"/example"}

I know that I have everything else wired up correctly, other controllers work.

I feel like I must be missing some fundamental principal here.

Thanks in advance.

Upvotes: 3

Views: 23573

Answers (5)

Sourabh Rai
Sourabh Rai

Reputation: 1

If you want to use @PathVariables only , you should update your @RequestMapping("/example) to @RequestMapping("/example/{test}")

Upvotes: 0

Ahmed Tawila
Ahmed Tawila

Reputation: 1038

The solution for me was:

@RestController
@RequestMapping("/products")
@EnableTransactionManagement
public class ProductController {
    @RequestMapping(method = RequestMethod.POST)
    public Product save(@RequestBody Product product) {
        Product result = productService.save(product);
        return result;
    }
}

Upvotes: 0

Ralph
Ralph

Reputation: 120781

Spring support different ways how to map stuff from the url to method parameters: request parameters and path variables

  • Request Parameters are taken from url-query parameters (and request body, for example in http-POST requests). The annotation to mark the java method parameter that should take its value from a request parameter is @RequestParam

  • Path Variables (somtimes called path templates) are parts of the url-path. The annotation to mark the java method parameter that should take its value from a request parameter is @PathVariable

Have a look at this answer of mine, for an example an links to the Spring Reference.

So what your problem is: you want to read a Request Parameter (from the url-query part), but used the annotation for the Path Variables. So you have to use @RequestParam instead of @PathVariable:

@RestController
public class TestController {

    @RequestMapping("/example")
    public String doAThing(@RequestParam("test") String test) throws MessagingException {
        return "Your variable is " + test;
    }
}

Upvotes: 5

prem kumar
prem kumar

Reputation: 5877

If you are using path variable, then it has to be part of the URI. As you have not mentioned in the URI but used in the method arguments, spring tries to find out and assign this value from the path URI. But this path variable is not there in the path URI , therefore throwing MissingPathVariableException.

This should work.

@RestController
public class TestController {

@RequestMapping("/example/{test}")
public String doAThing(
    @PathVariable String test
) throws MessagingException {
    return "Your variable is " + test;
}
}

And your curl request would be like

curl http://localhost:8080/example/foo
//here the foo can be replace with other string values

Upvotes: 5

horatius
horatius

Reputation: 814

The reason why it's not working is that there are two ways to pass parameters to a REST API implementation using RestController. One is the PathVariable, the other is RequestParam. Both of them need names to be specified in the RequestMapping annotation.

Check out this excellent resource that explains RequestMapping in detail

Try this for your solution.

@RequestMapping("/example/{test}", method= RequestMethod.GET)
public String doAThing(
    @PathVariable("test") String test
) throws MessagingException {
    return "Your variable is " + test;
}

Upvotes: 2

Related Questions