简体   繁体   English

Ajax请求Spring REST api 415错误

[英]Ajax request to Spring REST api 415 error

I have a problem with my Spring Rest controller. 我的Spring Rest控制器有问题。 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. 我试图从我的客户端( angularJS )发布( PUT )数据到我的服务器( Spring ),但每次我尝试发送一些东西时,我得到415 Media not supported错误。

With Maven I have added jackson-core (2.6.3) and jackson-databind (2.6.3) to my Spring API. 使用Maven,我在我的Spring API中添加了jackson-core (2.6.3)jackson-databind (2.6.3) I am also using @EnableWebMvc to automatically add the Jackson message converter to Spring. 我也使用@EnableWebMvc自动将Jackson消息转换器添加到Spring。 In my Spring controller I am using @RestController for access to the REST methods of Spring. 在我的Spring控制器中,我使用@RestController来访问Spring的REST方法。


My REST API controller: 我的REST API控制器:

@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) 我的RippleUser模型 (部分)

@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. 在这个模型中,我有所有必要的getter和setter。


My AngularJS client: 我的AngularJS客户端:

 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} 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. 对于这个方法,我还将@JsonRootName(value = "user")到我的RippleUser模型中。

I have also tried without the user attribute (also removed it from my model): 我也试过没有user属性(也从我的模型中删除它):

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. AngularJS HTTP方法(PUT,POST,DELETE,GET等)检查参数中的类型并自动设置正确的标头。


Chrome Postman Chrome Postman

Just to make sure I have also tried this method in the Chrome Postman plugin 只是为了确保我在Chrome Postman插件中也尝试过这种方法

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

Method: PUT 方法: PUT

Headers: Content-Type: application/json 标题: 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: 当我将@ResponseBody从RippleUser更改为String时,我可以在RestController中接收信息:

@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. 我的问题的答案如下。

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. Spring抛出了不支持415媒体的错误,因为它无法用帖子填写所有必填字段。

My solution was to add a class especially used by Spring to convert data to and from while sending and receiving. 我的解决方案是添加一个特别是由Spring用来在发送和接收时转换数据的类。 The benefit of this extra class is that I can manage the data the API sends and receives. 这个额外类的好处是我可以管理API发送和接收的数据。


UserLocation 用户位置

Adding the following class to my project did the trick (with getters and setters): 将以下类添加到我的项目中就可以了(使用getter和setter):

public class UserLocation {

    private Float latitude;

    private Float longitude;

    private Date lastActive;
}

This class contains all the necessary data for my PUT request. 该类包含我的PUT请求的所有必要数据。 Spring automatically fills in all the fields. Spring会自动填充所有字段。


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 希望这有助于任何人

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM