ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java – Spring Data REST – 自v.2.5.7起,PUT请求无法正常工作

2019-10-05 21:03:59  阅读:260  来源: 互联网

标签:java spring-boot rest spring-data-rest put


从版本2.5.7开始,Spring Data REST没有正确执行PUT请求来更新具有相关资源的资源.与按预期工作的PATCH请求不同!

例如,Person与Addres有多对一关联.如果我们使用SDR v.2.5.6(Spring Boot v.1.4.3)执行PUT请求,那么一切正常.但是如果我们切换到2.5.7版(即Spring Boot v.1.4.4),那么我们会收到一个错误:

Can not construct instance of Address: no String-argument constructor/factory method to deserialize from String value

其他类型的关联也会发生同样的情况,例如一对多(单向和双向) – 请参阅我的example application代码和测试.

从1.4.4开始,Spring Boot的所有版本都存在此问题,包括最新的稳定1.5.6版本,以及最新的2.0.0-SNAPSHOT版本!

要解决这种情况,我们可以切换到SDR v.2.5.6(Spring Boot v.1.4.3).

我准备了一个Postman系列请求,以帮助您解决问题:SDR PUT Issue

更新2017-08-14

我发现如何避免错误无法构造Address的实例:没有String-argument构造函数/工厂方法从String值反序列化.

由于我在这个项目中使用Lombok,
有必要告诉Lombok禁止使用@ConstructorProperties注释
generated constructors.
所以我在’lombok.config’文件中设置了lombok.anyConstructor.suppressConstructorProperties = true,错误消失了.

不幸的是,发现了一个新问题 – PUT请求根本不更新关联的对象!

以下示例说明了这一点.当我们尝试通过将地址从地址/ 1(初始值)更改为地址/ 2来更新Person时,它保持不变:地址/ 1!除了上一个问题之外,这个问题出现在自1.4.4以来的所有版本的Spring Boot中(SDR – 来自v.2.5.7).

我调试了我的项目,发现问题的原因隐藏在DomainObjectReader#mergeForPut方法中(参见its source) – 它永远不会用新的资源替换相关资源.

在我在Spring JIRA发布此问题之前,如果您的项目中存在此问题,请在此处报告,您对此有何看法.

你可以得到我的测试here并在你的项目中检查它 – 测试是’独立的’并且不依赖于其他类/模块(我希望只排除H2).

@Entity
public class Person {

    private String name;

    @ManyToOne
    private Address address;

    // other stuff
}

@Entity    
public class Address {

    private String street;

    // other stuff
}

试图更新人:

PUT http://localhost:8080/api/persons/1
{
    "name": "person1u",
    "address": "http://localhost:8080/api/addresses/2"
}

得到正确答案:

{
    "name": "person1u",
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/persons/1"
        },
        "person": {
            "href": "http://localhost:8080/api/persons/1"
        },
        "address": {
            "href": "http://localhost:8080/api/persons/1/address"
        }
    }
}

然后检查“新的”人员地址 – 地址未更新:

GET http://localhost:8080/api/persons/1/address
{
    "street": "address1",
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/addresses/1"
        },
        "address": {
            "href": "http://localhost:8080/api/addresses/1"
        }
    }
}

更新2017-08-24

感谢Scott C. answer,结果发现SDR有一个错误,在两张票中有描述:DATAREST-1001DATAREST-1012.

解决方法:

看起来问题有already been reported as a bug: – 请验证.尽我所知,这是您在上面报告的问题.

注意,我正在修改我以前的答案是这个错误报告.

标签:java,spring-boot,rest,spring-data-rest,put
来源: https://codeday.me/bug/20191005/1857604.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有