【问题标题】:Spring Cloud FeignClient decoding application/hal+json Resource<Object> return typeSpring Cloud FeignClient 解码应用/hal+json Resource<Object> 返回类型
【发布时间】:2015-08-27 15:16:03
【问题描述】:

我正在使用 Spring Cloud、Spring Data JPA、Spring Data Rest 和 Spring Boot 开发一个 REST API。服务器实现根据 HAL 规范等正确生成各种数据项。它生成 HAL+JSON 如下:

{
  "lastModifiedBy" : "unknown",
  "lastModifiedOn" : "2015-06-04T12:19:45.249688",
  "id" : 2,
  "name" : "Item 2",
  "description" : null,
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/pltm/accounts/2"
    },
    "customers" : {
      "href" : "http://localhost:8080/pltm/accounts/2/customers"
    },
    "users" : {
      "href" : "http://localhost:8080/pltm/accounts/2/users"
    },
    "groups" : {
      "href" : "http://localhost:8080/pltm/accounts/2/groups"
    }
  }
}

现在我正在尝试使用 FeignClient Spring Cloud 库来实现客户端。我已经定义了我的客户端接口如下。

@FeignClient("serviceId")
@RequestMapping(value = "/api", consumes = MediaType.APPLICATION_JSON_VALUE)
public interface PltmClient
{
  // Account Requests
  @RequestMapping(method = RequestMethod.GET, value = "/accounts")
  PagedResources<Resource<Account>> getAccounts();

  @RequestMapping(method = RequestMethod.GET, value = "/accounts/{id}")
  Resource<Account> getAccountAsResource(@PathVariable("id") Long id);

  @RequestMapping(method = RequestMethod.GET, value = "/accounts/{id}")
  Account getAccount(@PathVariable("id") Long id);
}

当我调用 getAccout() 方法时,我会从 JSON 文档中获取我的域对象 Account 的详细信息。该对象是一个简单的 POJO。所有字段均已正确填写。

public class Account
{
   private Long id;
   private String name;
   private String description;

   /** Setters/Getters left out for brevity **/
 }

但是当我调用getAccountAsResource() 时,它可以工作,我会返回一个包含数据的Resource 对象。但是,对Resource.getContent() 的调用会返回一个未完全填充的Account 对象。在这种情况下,Account.getId() 为 NULL,这会导致问题。

任何想法为什么会发生这种情况?我的一个想法是Resource 类定义了getId() 方法,这在某种程度上使Jackson ObjectMapper 感到困惑。

更大的问题是整个方法是否可行,或者是否有更好的方法?显然,我可以只使用普通 POJO 作为我的返回类型,但这会丢失客户端的 HAL 信息。

是否有人为 Spring Data REST 服务器端点成功实现了基于 Java 的客户端实现?

【问题讨论】:

    标签: spring-data-rest spring-cloud spring-hateoas


    【解决方案1】:

    Account 没有 id 是 spring-data-rest 的一个特性。您需要在服务器端启用填充 id。

    我还添加了一种不同的方法来返回 id(在 Account 中)

    @JsonProperty("accountId")
    public String getId() {
        return id;
    }
    

    启用标识

    @Configuration
    public class MyConfig extends RepositoryRestMvcConfiguration {
    
        @Override
        protected void configureRepositoryRestConfiguration( RepositoryRestConfiguration config) {
            config.exposeIdsFor(Account.class);
        }
    }
    

    我在这里使用过:https://github.com/spencergibb/myfeed,虽然我相信我使用资源的地方,我使用的是RestTemplate

    【讨论】:

    • 我确实在服务器端启用了 id 字段的发送。这就是上面 JSON 中的“id”字段的来源。所以我看到数据在 JSON 流中离开服务器。问题出在客户端,当试图将 JSON 映射到 Resource&lt;Account&gt; 时,有些东西会变得混乱并且没有映射 id。如果我只是将返回类型设为Account,那么我确实会看到正在填充的 id。
    • 我通过在 json 中有另一个不是 id 的属性(即上面的 accountId)来解决它。
    • 好的,我现在明白你的意思了。我能够为嵌入对象向服务器生成的 JSON 添加另一个属性,在本例中为 Account,并使用对象的 @JsonProperty````` mappings, have that mapped to the id```` 属性。我必须在 JSON 中发送附加值,这有点烦人,因为它使 API 更加混乱。这会被认为是 JSON 对象映射逻辑的错误吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 2020-06-29
    • 1970-01-01
    • 2020-02-23
    • 2019-07-30
    • 2020-12-17
    相关资源
    最近更新 更多