在Spring Rest数据上创建具有RestTemplate的对象之间的关联(HATEOAS)

我正在努力通过RestTemplate在
Spring Data Rest API上操作对象(它们是JPA实体).

我有一个树形结构,其中流派有父母和其他类型的孩子(这是itunes genre tree)

创建一个对象很好:

URI selfLink = restTemplate.postForLocation(api+"/genre", genre, Collections.emptyMap());

与它建立关联并不是那么容易.如果我尝试PUT这样的父协会:

headers.setContentType(new MediaType("text", "uri-list"));
...
restTemplate.put(selfLink.toString()+"/parent", entity, parentGenreURI );

我在客户端遇到500内部服务器错误,但在REST API端吞下了实际错误,并且日志中没有任何内容.

如果我尝试使用父亲的uri来修补URI本身,如下所示:

headers.setContentType(MediaType.APPLICATION_JSON);
...
Map map = ImmutableMap.of("parent", parentGenreLink);
restTemplate.exchange(selfLink.toString()+"/parent", HttpMethod.PATCH, entity, String.class, map);

我在客户端和服务器上收到400 Bad Request错误

org.springframework.http.converter.HttpMessageNotReadableException:
Could not read an object of type class Genre
from the request!; nested exception is
org.springframework.http.converter.HttpMessageNotReadableException:
Could not read payload!; nested exception is
com.fasterxml.jackson.databind.JsonMappingException: No content to map
due to end-of-input

这让我觉得这是正确的做法,但我只是做错了.

有人可以提供一些指导吗?我见过的每个例子都使用curl,这对我没那么帮助:)

在SO上有一些类似的回答问题,但是大多数问题都指向不再存在的文档,或者有这样的简单对象,所有内容都被转储到地图中.

最佳答案 查看您发布的少量代码以及您收到的错误我认为您以错误的方式调用了您的服务.

我在这里以第二个调用为例,但由于我认为你在两个调用中都犯了同样的错误,所以第一个错误的解决方案应该是类似的.

如果我们查看您正在调用的RestTemplate.exchange的文档,我们可以看到它需要以下参数:

>要呼叫的URL
>使用方法
> HttpEntity作为请求发送
>响应的类
>要在URL中替换的参数值

在我认为你出错的地方是参数3和5.在我看来你正试图发送JSON有效载荷

{
  "parent": "someGenre"
}

但是你实际上在做的是告诉模板用parentGenreLink的值替换URL中字符串{parent}(URL参数占位符)的任何出现.

您可能想要做的是将地图设置为HttpEntity上的正文,而不是传递任何URL参数:

// Create the body
Map map = ImmutableMap.of("parent", parentGenreLink);

// Create the headers
Headers headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

// Create the HTTP Entity
HttpEntity<?> entity = new HttpEntity<>(map, headers);

// Make the call without any URL parameters
restTemplate.exchange(selfLink.toString()+"/parent", HttpMethod.PATCH, entity, String.class);

请注意,要使其工作,您必须有一个消息转换器能够(de)序列化模板上设置的JSON:

RestTemplate restTemplate = new RestTemplate();

List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(new MappingJacksonHttpMessageConverter());
restTemplate.setMessageConverters(messageConverters);
点赞