Before going into details, I know there has been lots of conversations and related questions on Stackoverflow. All of them kind of help me in different ways so I thought I p
curl -i -H "Content-Type: application/json" -X POST -d '{"id":100,"username":"JohnBlog","name":"John","lastName":"Blog","email":"JohnBlog@user.com"}' http://localhost:8080/[YOURWEBAPP]/api/user/add
Here I explore different errors you might come across after you have made a curl call and what might have possibly gone wrong.
HTTP/1.1 404 Not Found
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 949
Date: Tue, 04 Jun 2013 02:59:35 GMT
This implies that the REST API does not exist in the URL you have provide.
Root cause:After you have made sure that everything is done perfectly right and nothing is wrong with your Configuration nor you URL: - Run a maven clean. - Undeploy your web app or simply delete it. - Redeploy the web app - Make sure to use only one version of Spring in your maven/gradle
HTTP/1.1 400 Bad Request
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 968
Date: Tue, 04 Jun 2013 03:08:05 GMT
Connection: close
The only reason behind this is that fact that your request is not formatted correctly. If you checkout the detailed curl response you should be able to see "The request sent by the client was syntactically incorrect.".
Root cause:Either your JSON format is not right or you are missing a mandatory parameter for the JAVA object.
Actions:Make sure you provide the JSON object in correct format and with the right number of parameters. Nullable properties are not mandatory but you do have to provide data for all NotNullable properties. It is VERY important to remember that Spring is using Java reflection to turn yours JSON file into Java objects, what does this mean? it means that variable and method names are CasE SensItiVe. If your JSON file is sending the variable "userName", than your matching variable in your Java object MUST also be named "userName". If you have getters and setters, they also have to follow the same rule. getUserName and setUserName to match our previous example.
HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=utf-8
Content-Length: 1051
Date: Wed, 24 Aug 2011 08:50:17 GMT
Root cause:
The Json media type is not supported by your web service. This could be due to your annotation not specifying the media type or you not specifying the media type in Curl post command.
Actions:Check your message convertor is set up correctly and make sure the web service annotation matches the example above. If these were fine, make sure you specify the content-type in your Curl post request.
The json media type is not supported by your web service.
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Tue, 04 Jun 2013 03:06:16 GMT
Congrats the user is actually send to your server side REST API.
For further details on how to set up your spring checkout the spring mvc guide.
This FAQ was not possible if it wasn't for all the people who provided the following posts and questions (this list will expand if I come across useful related posts/questions):
Should be good to notice that a bean class can NOT be handled if it has 2 or more setter for one field without @JsonIgnore
on optional ones. Spring/Jackson throw HttpMediaTypeNotSupportedException
and http status 415 Unsupported Media Type.
Example :
@JsonGetter
public String getStatus() {
return this.status;
}
@JsonSetter
public void setStatus(String status) {
this.status = status;
}
@JsonIgnore
public void setStatus(StatusEnum status) {
if (status == null) {
throw new NullPointerException();
}
this.status = status.toString();
}
Update :
We also have to specify @JsonGetter
and @JsonSetter
in this case, not to have issues when used as return type.
Just tested it with Spring 3.2.2 and Jackson 2.2. It works fine as parameter (@RequestBody
) and/or as return type (@ResponseBody
).
Update 2 :
If @JsonGetter
and @JsonSetter
are specified, @JsonIgnore
seems not to be required.