在Spring Data REST + HATEOAS中删除REST上的关联

BKa*_*aun 3 rest spring spring-data-rest spring-hateoas

我想知道如何通过REST调用删除多对多关联.我能够创建记录并关联它们,但不了解如何删除.

我有一个Spring Boot项目,我使用REST和HATEOAS来传递服务和控制器并直接公开我的存储库.

我有一个用户模型/域类

@Entity
@Table(name = "usr")
public class User implements Serializable {

private static final long serialVersionUID = 1L;

@Version
private long version = 0;

@Id
@GeneratedValue(generator="optimized-sequence")
private Long id;

@Column(nullable = false, unique = true, length = 500)
@Size(max = 500)
private String userName;

@Column(nullable = false, length = 500)
@Size(max = 500)
private String firstName;

@Column(nullable = false, length = 500)
@Size(max = 500)
private String lastName;

@ManyToMany(    fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable( name="user_role",
            joinColumns={ @JoinColumn(  name = "user_id", 
                                        nullable = false
                                    ) 
                        }, 
            inverseJoinColumns={ @JoinColumn(   name="role_id", 
                                                nullable=false
                                            ) 
                                }
)
private Set<Role> roles = new HashSet<Role>(0);

...Getters/Setters Below...
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我有一个角色成员,与Role类是多对多关联,其代码如下:

@Entity
public class Role {

@Id
@GeneratedValue(generator="optimized-sequence")
private Long id;

@Column(nullable = false)
private String name;

@Column(nullable = false)
private String description;

...Getters/Setters Below...
Run Code Online (Sandbox Code Playgroud)

我的存储库看起来像这样:

UserRepository

public interface UserRepository extends 
        JpaRepository<User, Long>, JpaSpecificationExecutor<User> {

    List<User> findByUserName(String username);

}
Run Code Online (Sandbox Code Playgroud)

RoleRepository

public interface RoleRepository 
        extends JpaRepository<Role, Long> {

}
Run Code Online (Sandbox Code Playgroud)

现在,一切都很好.当我从浏览器访问项目根目录时,我获得了JSON + HAL格式的存储库索引/目录.精彩.

(注意我从下面的测试中删除了http://部分,因为StackOverflow将其计入我的链接配额)

我,使用WizTools REST Client,HTTP.POST到角色(localhost:8080/resttest/roles)存储库并创建一个新角色.成功,角色ID#4已创建.

然后我POST到User存储库创建一个User(localhost:8080/resttest/users).成功,创建用户ID#7.

然后我PUT到用户存储库以创建与角色的关联:

PUT localhost:8080/resttest/users/7/roles
Content-type: uri-list
Body: localhost:8080/resttest/roles/4
Run Code Online (Sandbox Code Playgroud)

大!协会做了.用户9现在与角色4相关联.

现在我不能为我的生活弄清楚如何删除这种关联.

我正在使用与上面相同的命令发送HTTP DELETE而不是PUT.

DELETE localhost:8080/resttest/users/7/roles
Content-type: uri-list
Body: localhost:8080/resttest/roles/4
Run Code Online (Sandbox Code Playgroud)

我回来了:HTTP/1.1 405方法不允许

{
    "timestamp":1424827169981,
    "status":405,
    "error":"Method Not  Allowed",
    "exception": "org.springframework.web.HttpRequestMethodNotSupportedException",
    "message":"Request method 'POST' not supported"
}
Run Code Online (Sandbox Code Playgroud)

Ant*_*gon 9

虽然创建PUT具有剩余元素的请求可以解决问题DELETE,但是删除关联资源是一个可接受的命令,并且在大多数情况下更容易使用.

至于你的例子,这应该工作:

DELETE localhost:8080/resttest/users/7/roles/4
Run Code Online (Sandbox Code Playgroud)

另外,在创建关联时,应该在有效负载中包含URI.您不应该在正文中写入整个URL,这应该足够了:

PUT localhost:8080/resttest/users/7/roles
Content-type: uri-list
Body: /roles/4
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

  • 这很不方便,因为所有其他请求(put,post,get)都依赖于链接而不是ID.要执行删除代码,需要编写以从对象_link中提取id. (3认同)

a b*_*ver 2

来自文档:

删除

...

405 不允许方法 - 如果关联是非可选的

PUT意味着您更换整个roles套装。因此,要删除单个链接,请删除PUT所有剩余的链接。如果您只有一个链接并想删除它,您将得到PUT一个空集合:

PUT localhost:8080/resttest/users/7/roles
Content-type: uri-list
Body:
Run Code Online (Sandbox Code Playgroud)

顺便说一句:您不会发送带有DELETE请求的正文。这没有道理。

编辑

另请参阅Spring HATEOAS 开发人员的回答。