【问题标题】:How to consume a spring data rest service with java?如何使用 java 使用 spring 数据休息服务?
【发布时间】:2017-07-03 02:21:10
【问题描述】:

我有以下 spring boot + data Rest 存储库:

    @RepositoryRestResource(collectionResourceRel = "dto", path = "produtos")
    public interface ProdutoRepository extends CrudRepository<Produto, Integer> {
        @Query("SELECT p FROM Produto p where descricao LIKE CONCAT(UPPER(:like),'%')")
        List<Produto> findByLike(@Param("like") String like);
    }

我还有一个 java 客户端可以访问这个方法(这是我的例子):

    String url = "http://localhost:8080/produtos/search/findByLike?like={like}";
    RestTemplate t = new RestTemplate();
    ProdutoDto resp = t.getForObject(url, ProdutoDto.class, txtLoc.getText());

ProdutoDto(这不是完全必要的):

public class ProdutoDto extends HalDto<Produto> {}

暂停:

public class HalDto<T extends ResourceSupport> extends ResourceSupport {
    @JsonProperty("_embedded")
    private EmbeddedDto<T> embedded;

    public EmbeddedDto<T> getEmbedded() {
        return embedded;
    }

    public void setEmbedded(EmbeddedDto<T> embedded) {
        this.embedded = embedded;
    }
}

EmbeddedDto:

public class EmbeddedDto<T> {
    @JsonProperty("dto")
    private List<T> dtoList;

    public List<T> getDtoList()
    {
        return dtoList;
    }

    public void setDto(List<T> dtoList) {
        this.dtoList = dtoList;
    }
}

这些类是必要的(我认为),因为 Spring Data 以 HAL (https://en.wikipedia.org/wiki/Hypertext_Application_Language) 格式返回数据。

注意:Produto 必须扩展 ResourceSupport。

注意事项:所有 collectionResourceRel 必须命名为“dto”,并且仅适用于集合(可能会调整)。

这是正确的做法吗?

我在 Google 上四处搜索,发现了很多做服务器端的例子,但几乎没有关于构建客户端的例子。

谢谢。

【问题讨论】:

  • 这是正确的做法吗?:运行代码时会发生什么?它做你想让它做的事吗?那应该回答你的问题。
  • 它有效,但我不确定它是否正确(知道“正确”是相对的)。我们将使用 Spring Boot + 数据进行大量编码,因此正确执行非常重要。
  • 你想出正确的方法了吗?我在编写单元测试时面临同样的问题。 @JBNizet 我认为这里的问题是 Spring 是否已经提供了一个通用抽象类,我们可以简单地扩展它并让 Spring - 再次 - 做它的魔术。
  • 不幸的是,没有。我只是禁用了它并编写了我自己的数据 api。

标签: spring rest spring-data


【解决方案1】:

这是我发现的一个似乎效果很好的解决方案。

首先,设置您的 RestTemplate 以便它需要 JSON/HAL 并知道如何处理它:

@Bean
public RestTemplate restTemplate() {

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new Jackson2HalModule());
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        MappingJackson2HttpMessageConverter messageConverter =
                    new MappingJackson2HttpMessageConverter();
        messageConverter.setObjectMapper(objectMapper);
        messageConverter.setSupportedMediaTypes(Arrays.asList(MediaTypes.HAL_JSON, MediaType.APPLICATION_JSON_UTF8));
        return new RestTemplate(Arrays.asList(messageConverter));

}

然后您可以使用RestTemplateexchange 方法指定您希望结果为ResponseEntity&lt;PagedResources&lt;Producto&gt;&gt;

ResponseEntity<PagedResources<Producto>> resultResponse = restTemplate.exchange(uri, HttpMethod.GET, HttpEntity.EMPTY, new ParameterizedTypeReference<PagedResources<Producto>>(){});

if(resultResponse.getStatusCode() == HttpStatus.OK){
    Collection<Producto> results = resultResponse.getBody().getContent();
    log.info("{} results obtained", results.size());
}

您可以通过调用上面定义的restTemplate() 方法来实例化restTemplate,也可以注入(自动装配)它。

【讨论】:

    猜你喜欢
    • 2021-04-19
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多