RepositoryRestMvcConfiguration 的 ObjectMapper 与 Spring 引导默认 ObjectMapper?

RepositoryRestMvcConfiguration's ObjectMapper vs. Spring Boot default ObjectMapper?

我正在使用 RepositoryRestMvcConfiguration 微调其余存储库行为:

@Configuration
public class WebConfig extends RepositoryRestMvcConfiguration {
    @Override
    protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
      config.setReturnBodyOnCreate(true);
}

缺点是扩展 class 引入了它自己的 ObjectMapper bean,导致描述的冲突 here。推荐的解决方法是使用扩展 class 将 ObjectMapper bean 标记为 @Primary,但是来自 RepositoryRestMvcConfiguration 的 bean 在序列化嵌套实体时具有不同的行为。

让我们假设以下实体:

@Entity class Parent {
    @Id Long id;
    @OneToMany @JsonManagedReference List<Child> children;
    // usual getters and setters for fields...
}

@Entity class Child {
    @Id Long id;
    @ManyToOne @JsonBackReference Parent parent;
    @ManyToOne @JsonBackReference School school;
    public getSchooldId() { return school.getId(); }
    // usual getters and setters for fields...
}

@Entity class School {
    @Id Long id;
    @OneToMany @JsonManagedReference List<Child> children;
    // usual getters and setters for fields...
} 

使用默认 Spring Boot ObjectMapper 给出预期结果(渲染嵌套实体):

{"id": 1, "children":[{"id":2, "schoolId":7},{"id":3, "schooldId":8}]}

但是 RepositoryRestMvcConfiguration 中的 ObjectMapper 会忽略子实体:

{"id": 1}

配置 RepositoryRestMvcConfiguration ObjectMapper 以实现与 Spring 引导默认设置相同的行为的正确方法是什么?

RepositoryRestMvcConfiguration 创建两个 objectMapper 对象。

  1. 供内部框架使用的 objectMapper。
  2. halObjectMapper 负责渲染集合Resources和Links.

您可以尝试通过使用限定符自动装配 objectMapper 来获得所需的结果:

@Qualifier('_halObjectMapper')

编辑:用于呈现 associations/nested 属性

Spring data-rest 默认不呈现关联(reference),因为它们在 HATEOAS 规范下可用(json 的 _link 部分) . 如果你想呈现关联,你只需要使用 Projections.

This Person has several attributes:id is the primary key, firstName and lastName are data attributes,address is a link to another domain object

@Entity
public class Person {

  @Id @GeneratedValue
  private Long id;
  private String firstName, lastName;

  @OneToOne
  private Address address;
  …
}

将被渲染:

   {
  "firstName" : "Frodo",
  "lastName" : "Baggins",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons/1"
    },
    "address" : {
      "href" : "http://localhost:8080/persons/1/address"
    }
    }
    }

By default, Spring Data REST will export this domain object including all of its attributes. firstName and lastName will be exported as the plain data objects that they are. There are two options regarding the address attribute. One option is to also define a repository for Address.

There is another route. If the Address domain object does not have it’s own repository definition, Spring Data REST will inline the data fields right inside the Person resource.