4

I have a problem with my Spring Rest controller. I am trying to post (PUT) data from my client (angularJS) to my server (Spring), but every time I try to send something I get a 415 Media not supported error.

With Maven I have added jackson-core (2.6.3) and jackson-databind (2.6.3) to my Spring API. I am also using @EnableWebMvc to automatically add the Jackson message converter to Spring. In my Spring controller I am using @RestController for access to the REST methods of Spring.


My REST API controller:

@RequestMapping(value = "/location/update/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE) public RippleUser updateUserLocation(@PathVariable("id") Integer id, @RequestBody RippleUser user) { return user; } 

I have tried differend types of consumes:

  • MediaType.APPLICATION_JSON_VALUE
  • "application/json"
  • Without consumes
  • And so on

My RippleUser model (partially)

@Entity @Table(name = "user") @JsonRootName(value = "user") public class RippleUser implements Serializable { @NotNull @Column(name = "active", nullable = false) private boolean activeUser; @Column(name = "latitude", nullable = true) private Float lattitude; @Column(name = "longitude", nullable = true) private Float longitude; @Temporal(TemporalType.TIMESTAMP) @Column(name = "lastActive", nullable = true) @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy HH:mm:ss") private Date timestamp; } 

In this model I have all the necessary getters and setters.


My AngularJS client:

 httpService.updateInBackend = function (url, data, callback, errorCallback) { http.put(url, data) .then(function successCallback(response) { callback(response.data); }, function errorCallback(response) { errorCallback(response); }); }; 

The URL: http://server:port/app/location/update/{id}

The data:

params: { { "user": { "latitude": 52.899370, "longitude": 5.804548, "timestamp": 1449052628407 } } }; 

For this method I also added @JsonRootName(value = "user") to my RippleUser model.

I have also tried without the user attribute (also removed it from my model):

params: { { "latitude": 52.899370, "longitude": 5.804548, "timestamp": 1449052628407 } }; 

The AngularJS HTTP method (PUT, POST, DELETE, GET, and so on) checks what type is in the parameters and automatically sets the right headers.


Chrome Postman

Just to make sure I have also tried this method in the Chrome Postman plugin

The URL: http://server:port/app/location/update/2

Method: PUT

Headers: Content-Type: application/json

Body:

{ "latitude": 52.899370, "longitude": 5.804548, "timestamp": 1449052628407 } 

The error this gives is:

HTTP Status 415 The server refused this request because the request entity is in a format not supported by the requested resource for the requested method. 

Update

I can receive information in my RestController when I change my @ResponseBody from RippleUser to String:

@RequestMapping(value = "/location/update/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE) public RippleUser updateUserLocation(@PathVariable("id") Integer id, @RequestBody String user) { return user; } 

I also tried sending an empty user object, but that results in the same error message

Answer to my problem is below.

2
  • So you method has a type of RippleUser, and you are returning a String? Commented Dec 3, 2015 at 13:48
  • @Jason Z, that was just to test if I could get trough the method. I got a Json string back, so the method works. The code was just for testing purposes Commented Dec 4, 2015 at 7:16

1 Answer 1

2

The problem with this code is a bit different than I expected. The 415 media not supported error is thrown by Spring, because it could not fill in all the required fields with the post.

My solution was to add a class especially used by Spring to convert data to and from while sending and receiving. The benefit of this extra class is that I can manage the data the API sends and receives.


UserLocation

Adding the following class to my project did the trick (with getters and setters):

public class UserLocation { private Float latitude; private Float longitude; private Date lastActive; } 

This class contains all the necessary data for my PUT request. Spring automatically fills in all the fields.


Controller

To make this work I also had to modify my controller. The new code is as follows:

@RequestMapping(value = "/location/update/{id}", method = RequestMethod.PUT) public UserLocation updateUserLocation(@PathVariable("id") Integer id, @RequestBody UserLocation location) { //Find user by ID //Add location to user //Update the user return //the new user } 

Hope this helps anyone

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.