Spring POST method - accept and return JSON in REST controller
How to accept and return JSON from Spring controller with http post?
Current code that doesn't work:
xxxxxxxxxx
value = "/get-user-data", method = RequestMethod.POST) (
How to make this work?
@RequestMapping example
To make this POST request work, we need to add:
- consumes = MediaType.APPLICATION_JSON_VALUE
- produces = MediaType.APPLICATION_JSON_VALUE
- @ResponseBody
xxxxxxxxxx
path = "/spring-examples/get-user-data", (
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public UserResponse getUserRequestMapping( UserRequest userRequest) {
// our logic
}
Important - don't forget to add @ResponseBody, as very often people forget to add this annotation is it causes 404 error from Spring Controller (HTTP Status 404 – Not Found).
Using String in consumes and produces
We can use simple String in consumes = "application/json" and produces = "application/json".
Alternative solution insted of using MediaType.APPLICATION_JSON_VALUE we can just use String, example:
xxxxxxxxxx
path = "/spring-examples/get-user-data", (
method = RequestMethod.POST,
consumes = "application/json",
produces = "application/json")
public UserResponse getUserRequestMapping( UserRequest userRequest) {
// our logic
}
consumes and produces is just simple String with value "application/json",
org.springframework.http.MediaType
internally looks like this:
xxxxxxxxxx
public class MediaType extends MimeType implements Serializable {
public static final String APPLICATION_JSON_VALUE = "application/json";
}
Full working spring controller
To setup this example we have 4 parts:
- RequestMappingController class
- jquery_ajax_post_json.html
- UserRequest class
- UserResponse class
1. RequestMappingController class
xxxxxxxxxx
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
public class RequestMappingController {
path = "/question-hash-PpOEv1/get-user-data-1", (
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public UserResponse getUserRequestMapping( UserRequest userRequest) {
System.out.println("# From spring boot controller - User request:");
System.out.println(userRequest.toString());
return new UserResponse("Emy", 27);
}
}
2. jquery_ajax_post_json.html
Here we have jQuery ajax request with this controller running on our test server.
xxxxxxxxxx
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
</head>
<body>
<script>
$(document).ready(function () {
var jsonRequest = {
id: 123,
hashId: 'some-hash'
};
$.ajax({
type: 'POST',
url: '/question-hash-PpOEv1/get-user-data-1',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify(jsonRequest),
success: function (response) {
console.log(JSON.stringify(response));
},
error: function (error) {
console.log(JSON.stringify(error));
}
});
});
</script>
</body>
</html>
3. UserRequest class
xxxxxxxxxx
public class UserRequest {
private long userId;
private String userHash;
public UserRequest() {
}
public UserRequest(long userId, String userHash) {
this.userId = userId;
this.userHash = userHash;
}
public long getUserId() {
return userId;
}
public void setUserId(long userId) {
this.userId = userId;
}
public String getUserHash() {
return userHash;
}
public void setUserHash(String userHash) {
this.userHash = userHash;
}
public String toString() {
return "UserRequest{" +
"userId=" + userId +
", userHash='" + userHash + '\'' +
'}';
}
}
4. UserResponse class
xxxxxxxxxx
public class UserResponse {
private String username;
private int userAge;
public UserResponse() {
}
public UserResponse(String username, int userAge) {
this.username = username;
this.userAge = userAge;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getUserAge() {
return userAge;
}
public void setUserAge(int userAge) {
this.userAge = userAge;
}
public String toString() {
return "UserResponse{" +
"username='" + username + '\'' +
", userAge=" + userAge +
'}';
}
}
Alternative solution to using @RequestMapping is using @PostMapping annotation.
Example:
xxxxxxxxxx
path = "/get-user-data", (
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public UserResponse getUserPostMapping( UserRequest userRequest) {
// our logic
}
The difference is that we don't need to add:
xxxxxxxxxx
method = RequestMethod.POST