RepositoryRestMvcConfiguration 的 ObjectMapper 与 Spring Boot 默认的 ObjectMapper?
Posted
技术标签:
【中文标题】RepositoryRestMvcConfiguration 的 ObjectMapper 与 Spring Boot 默认的 ObjectMapper?【英文标题】:RepositoryRestMvcConfiguration's ObjectMapper vs. Spring Boot default ObjectMapper? 【发布时间】:2017-05-01 11:14:07 【问题描述】:我正在使用 RepositoryRestMvcConfiguration
来微调其余存储库的行为:
@Configuration
public class WebConfig extends RepositoryRestMvcConfiguration
@Override
protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config)
config.setReturnBodyOnCreate(true);
缺点是扩展类引入了它自己的 ObjectMapper bean,导致here 中描述的冲突。推荐的解决方法是使用扩展类将 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 Boot 默认相同的行为的正确方法是什么?
【问题讨论】:
【参考方案1】:RepositoryRestMvcConfiguration
创建两个 objectMapper 对象。
-
objectMapper 供内部框架使用。
halObjectMapper 负责渲染集合
Resources
和Links。
您可以尝试通过使用限定符自动装配 objectMapper 来实现所需的结果:
@Qualifier('_halObjectMapper')
编辑:用于渲染关联/嵌套属性
默认情况下,Spring data-rest 不会呈现关联(reference),因为它们在 HATEOAS 规范下可用(您的 json 的 _link
部分)。
如果您想呈现关联,您只需要使用 Projections。
这个Person有几个属性:id是主键,firstName和lastName是数据属性,address是指向另一个域对象的链接
@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"
默认情况下,Spring Data REST 将导出这个域对象,包括它的所有属性。 firstName 和 lastName 将作为它们的纯数据对象导出。关于地址属性有两个选项。一种选择是也为地址定义一个存储库。
还有另一条路线。如果 Address 域对象没有自己的存储库定义,Spring Data REST 将直接在 Person 资源中内联数据字段。
【讨论】:
不幸的是,这没有帮助。 1) objectMapper 也是@Autowired
其他 Spring Boot 代码(例如,org.springframework.boot.actuate.autoconfigure.EndpointMBeanExportAutoConfiguration 中的构造函数) 2) halObjectMapper 可以使用 @Override @Bean @Primary public ObjectMapper objectMapper() return super.halObjectMapper();
设置为默认值,但结果与其他 objectMapper - 嵌套实体不呈现为 JSON
好的,现在我明白你的问题了。
这对于 Spring Data Rest 存储库端点是正确的,但不适用于 ObjectMapper 的独立使用(例如,在控制器中自动装配)。默认的 ObjectMapper(在 RepositoryRestMvcConfiguration
未扩展时可通过自动装配获得)即使没有投影也会按预期呈现嵌套实体。一旦我出于配置目的扩展RepositoryRestMvcConfiguration
,objectMapper/halObjectMapper 在独立模式下使用时不再呈现嵌套实体。
我修复了限定符,它以_开头以上是关于RepositoryRestMvcConfiguration 的 ObjectMapper 与 Spring Boot 默认的 ObjectMapper?的主要内容,如果未能解决你的问题,请参考以下文章