Daniel Pop
Daniel Pop

Reputation: 551

neither @RequestBody nor @RequestParam work

I want to make a PUT call in spring.

this is my controller code:

@RequestMapping(value = "/magic", method = RequestMethod.PUT)
    TodoDTO magic(@RequestBody String id){
        return service.magic(id);
    }

because i want to pass a id string in the call.

the problem is, i receive this

{
  "timestamp": 1486644310464,
  "status": 500,
  "error": "Internal Server Error",
  "exception": "java.lang.NullPointerException",
  "message": "{\n\t\"id\":\"589c5e322abb5f28631ef2cc\"\n}",
  "path": "/api/todo/magic"
}

if i change the code like this:

@RequestMapping(value = "/magic", method = RequestMethod.PUT)
    TodoDTO magic(@RequestParam(value = "id") String id){
        return service.magic(id);
    }

i receive

{
  "timestamp": 1486644539977,
  "status": 400,
  "error": "Bad Request",
  "exception": "org.springframework.web.bind.MissingServletRequestParameterException",
  "message": "Required String parameter 'id' is not present",
  "path": "/api/todo/magic"
}

i make the same call, a PUT at link http://localhost:8080/api/todo/magic with the body

{
    "id":"589c5e322abb5f28631ef2cc"
}

which is the id of one object in my db.

my question is, how can i achieve my goal? if i pass the param in the link, like api/todo/magic/589c5e322abb5f28631ef2cc, with @PathVariable, it works

Upvotes: 1

Views: 918

Answers (3)

Alan Hay
Alan Hay

Reputation: 23246

While creating a wrapper class as suggested in the other answers will work, I think it may be possible to avoid this overhead and simply use a Map.

@RequestMapping(value = "/magic", method = RequestMethod.PUT)
    TodoDTO magic(@RequestBody Map<String, String> data){
        return service.magic(data.get("id");
}

Upvotes: 0

Slava Semushin
Slava Semushin

Reputation: 15214

When you're using @RequestBody String id it expects just a string:

"589c5e322abb5f28631ef2cc"

If you want to send an object with id field like

{
    "id":"589c5e322abb5f28631ef2cc"
}

you should create a class with id field and modify method's signature to get this class instead of String.

Upvotes: 2

Vaibs
Vaibs

Reputation: 1606

Create your own custom class like below

Class Request
{
private String id;
//getter and setter
}

And change method to

@RequestMapping(value = "/magic", method = RequestMethod.PUT)
    TodoDTO magic(@RequestBody Request request){
        return service.magic(request.getId());
    }

You can take id in url also and use @Pathvariable in method signature

@RequestMapping(value = "/magic/{id}", method = RequestMethod.PUT)
        TodoDTO magic(@PathVariable String id){
            return service.magic(request.getId());
        }

Upvotes: 5

Related Questions