在Spring Data Rest中使用自定义json序列化程序时输出不同的JSON [英] Different JSON output when using custom json serializer in Spring Data Rest
问题描述
根据 Jackson 序列化程序后。 x / reference / html / representationations-chapter.html#d5e394rel =nofollow noreferrer>官方文档我观察到一种略有不同的json输出格式。
After adding a custom Jackson
serializer based on the official documenation I've observed a slightly different json output format.
此示例基于 spring-restbucks 的分支。
从 RepositoryRestMvcConfiguration
扩展 org.springsource.restbucks.WebConfiguration
并覆盖 configureJacksonObjectMapper
:
@Override
protected void configureJacksonObjectMapper(ObjectMapper objectMapper) {
final SimpleSerializers serializers = new SimpleSerializers();
serializers.addSerializer(Order.class, new OrderSerializer());
objectMapper.registerModule(new SimpleModule("CustomSerializerModule"){
@Override public void setupModule(SetupContext context) {
context.addSerializers(serializers);
}
});
}
创建类 org.springsource.restbucks.order。 OrderSerializer
。为了简洁起见,只需将属性付费
写为JSON。
Create class org.springsource.restbucks.order.OrderSerializer
. For the sake of brevity just write attribute paid
as JSON.
public class OrderSerializer extends JsonSerializer<Order> {
@Override
public void serialize(Order value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeStartObject();
jgen.writeBooleanField("paid", value.isPaid());
jgen.writeEndObject();
}
}
在为 http:// localhost:8080 / orders / 1
看起来像:
{
"location": "TAKE_AWAY",
"status": "PAYMENT_EXPECTED",
"orderedDate": "2014-03-24T15:05:09.988+01:00",
"items": [
{
"name": "Java Chip",
"quantity": 1,
"milk": "SEMI",
"size": "LARGE",
"price": {
"currency": "EUR",
"value": 4.2
}
}
],
"_links": {
...
}
}
为添加OrderSerializer json响应后,http:// localhost:8080 / orders / 1
看起来像
{
"content": {
"paid": false
},
"_links": {
...
}
}
主要的pi npoint是被支付的属性被包装到另一个对象内容中,该内容是 org.springframework.hateoas.Resource 。我期待没有这个属性的回复:
The main pinpoint is that attribute paid is wrapped into another object content which is an attribute of org.springframework.hateoas.Resource. I've expected a response without this attribute:
{
"paid": false,
"_links": {
...
}
}
我查看了杰克逊代码,发现 UnwrappingBeanSerializer 可能是我正在寻找的解决方案。
在查看如何初始化UnwrappingBeanSerializer之后,我认为这个序列化程序并不是为了自定义使用而进行子类化。
I've looked into Jackson code and found that UnwrappingBeanSerializer might be the solution I'm looking for. After looking at how to initialize UnwrappingBeanSerializer I think that this serializer is not meant to be subclassed for custom use.
我想知道使用自定义序列化程序时这种偏离的json格式是正常行为还是Spring Data Rest中的错误。任何形式的帮助都表示赞赏。
I would like to know whether this deviating json format when using a custom serializer is a normal behaviour or a bug in Spring Data Rest. Any kind of help is appreciated.
推荐答案
这不是Spring Data Rest的错误它实际上是Jackson的正常行为串行。每当您使用@JsonUnwrapped Annotation(与资源内容字段一起使用)和自定义序列化程序时,Jackson Serializer将显式写入字段名称(在本例中为内容)。有关更多详细信息,请查看UnwrappingBeanPropertyWriter。无论如何,你使用UnwrappingBeanSerializer一直在正确的轨道上,但设置与通常的Serializer注册略有不同。以下示例应解决您的问题:
This is not a bug of Spring Data Rest it is actually the normal behaviour of the Jackson Serializer. Whenever you use the @JsonUnwrapped Annotation (as the Resource content field does) together with a custom Serializer the Jackson Serializer will explicitly write the field name (in this case content). Have a look at the UnwrappingBeanPropertyWriter for more details. Anyhow you have been on the right track using the UnwrappingBeanSerializer but the setup is slightly different then the usual Serializer registration. The following example should fix your problem:
@Override
protected void configureJacksonObjectMapper(ObjectMapper objectMapper) {
mapper.registerModule(new Module() {
@Override
public String getModuleName() {
return "my.module";
}
@Override
public Version version() {
return Version.unknownVersion();
}
@Override
public void setupModule(SetupContext context) {
context.addBeanSerializerModifier(new BeanSerializerModifier() {
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
if(beanDesc.getBeanClass().equals(Order.class)) {
return new UnwrappingOrderSerializer((BeanSerializerBase) serializer, NameTransformer.NOP);
}
return serializer;
}
});
}
});
}
public class UnwrappingOrderSerializer extends UnwrappingBeanSerializer {
public UnwrappingBarSerializer(BeanSerializerBase src, NameTransformer transformer) {
super(src, transformer);
}
@Override
public JsonSerializer<Object> unwrappingSerializer(NameTransformer transformer) {
return new UnwrappingOrderSerializer(this, transformer);
}
@Override
protected void serializeFields(Object bean, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
Order order = (Order) bean;
jgen.writeStringField("paid", order.isPaid();
}
@Override
public boolean isUnwrappingSerializer() {
return true;
}
}
这篇关于在Spring Data Rest中使用自定义json序列化程序时输出不同的JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!