dis*_*ame 5 spring jackson spring-data-jpa spring-data-rest
我想在一次调用中创建另一个资源的子资源.这些资源具有以下@ManyToMany关系:用户和组.
我不首先要创建一个用户,则该组并因为它显示在关系后,用关系在春季数据REST工作 -只是因为我认为不能单独存在,比如一组资源,应该仅当至少一个用户也与该资源相关联时才会创建.为此,我需要像这样的一个端点(这对我不起作用,否则我不会在这里)创建一个组,并在一个事务中设置关联的"种子"用户.
目前,使这项工作的唯一方法是手动"同步"关系,如下所示:
public void setUsers(Set<AppUser> users) {
users.forEach(u -> u.getGroups().add(this));
this.users = users;
}
Run Code Online (Sandbox Code Playgroud)
这将允许我
POST http://localhost:8080/groups
{
"name": "Group X",
"users": ["http://localhost:8080/users/1"]
}
Run Code Online (Sandbox Code Playgroud)
但我的问题是,这对我来说感觉不对 - 它看起来似乎是一种解决方法,而不是实际的Spring方式使这个要求工作.那么......
我目前正在努力使用Spring创建关系资源@RepositoryRestResource.我想创建一个新组并将其与调用用户关联,如下所示:
POST http://localhost:8080/users/1/groups
{
"name": "Group X"
}
Run Code Online (Sandbox Code Playgroud)
但唯一的结果就是回应204 No Content.我不知道为什么.这可能与我的另一个问题(见这里)有关,也可能没有,我试图通过在JSON有效载荷中设置相关资源来实现同样的目标 - 这也不起作用.
服务器端我收到以下错误:
tion$ResourceSupportHttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class org.springframework.hateoas.Resources<java.lang.Object>]]: java.lang.NullPointerException
Run Code Online (Sandbox Code Playgroud)
如果您需要任何特定代码,请告诉我.
我添加exported = false到 @RepositoryRestResource的UserGroupRepository:
@RepositoryRestResource(collectionResourceRel = "groups", path = "groups", exported = false)
public interface UserGroupRepository extends JpaRepository<UserGroup, Long> {
List<UserGroup> findByName(@Param("name") String name);
}
Run Code Online (Sandbox Code Playgroud)
而且我发送:
PATCH http://localhost:8080/users/1
{
"groups": [
{
"name": "Group X"
}
]
}
Run Code Online (Sandbox Code Playgroud)
然而,结果仍然只是204 No Content与ResourceNotFoundException服务器端.
从本质上讲,下面的单元测试应该可行,但我也可以回答为什么这不能正常工作,这也说明了如何正确完成.
@Autowired
private TestRestTemplate template;
private static String USERS_ENDPOINT = "http://localhost:8080/users/";
private static String GROUPS_ENDPOINT = "http://localhost:8080/groups/";
// ..
@Test
@DirtiesContext(classMode = ClassMode.BEFORE_EACH_TEST_METHOD)
public void whenCreateUserGroup() {
// Creates a user
whenCreateAppUser();
ResponseEntity<AppUser> appUserResponse = template.getForEntity(USERS_ENDPOINT + "1/", AppUser.class);
AppUser appUser = appUserResponse.getBody();
UserGroup userGroup = new UserGroup();
userGroup.setName("Test Group");
userGroup.setUsers(Collections.singleton(appUser));
template.postForEntity(GROUPS_ENDPOINT, userGroup, UserGroup.class);
ResponseEntity<UserGroup> userGroupResponse = template.getForEntity(GROUPS_ENDPOINT + "2/", UserGroup.class);
Predicate<String> username = other -> appUser.getUsername().equals(other);
assertNotNull("Response must not be null.", userGroupResponse.getBody());
assertTrue("User was not associated with the group he created.",
userGroupResponse.getBody().getUsers().stream()
.map(AppUser::getUsername).anyMatch(username));
}
Run Code Online (Sandbox Code Playgroud)
但是,行
userGroup.setUsers(Collections.singleton(appUser));
Run Code Online (Sandbox Code Playgroud)
将打破这个测试并返回一个404 Bad Request.
根据SDR参考:
邮政
仅支持集合关联。将新元素添加到集合中。支持的媒体类型:
text/uri-list- 指向要添加到关联的资源的 URI。
所以要添加group尝试user这样做:
POST http://localhost:8080/users/1/groups (with Content-Type:text/uri-list)
http://localhost:8080/groups/1
Run Code Online (Sandbox Code Playgroud)
附加信息。
| 归档时间: |
|
| 查看次数: |
485 次 |
| 最近记录: |