首页 > 解决方案 > 杰克逊序列化程序 - 访问私有属性

问题描述

我有一个Spring Boot 2带有私有属性和公共 getter/setter 模型的应用程序。杰克逊是2.10.0版本。

我需要一个自定义序列化器来输出JSON而不扩展一些引用。根据我的阅读,如果该属性是私有的,Jackson则无法访问它并且会出现编译错误。除非它应该工作时有公共吸气剂。但事实并非如此。

但是,如果我将模型中的属性设置为公共,则不会出错。

同样,如果我在序列化程序中使用 getter 而不是属性,那么一切都很好。

我误读了这个,并且序列化程序真的将私有视为私有吗?

@JsonSerialize(using = ClimateSerializer.class)
public class Climate {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "climate_gen")
    private long id;

    private float temperature;
    private float humidity;

    .... getters and setters
}

串行器

public class ClimateSerializer extends StdSerializer<Climate> {

    public ClimateSerializer() {
        this(null);
    }

    public ClimateSerializer(Class<Climate> t) {
        super(t);
    }

    @Override
    public void serialize(
      final Climate value, final JsonGenerator jgen, final SerializerProvider provider) 
      throws IOException, JsonProcessingException {

        jgen.writeStartObject();
        jgen.writeNumberField("id", value.getId());
        jgen.writeNumberField("temperature", value.getTemperature());
        jgen.writeNumberField("humidity", value.getHumidity());
        jgen.writeEndObject();
    }
}

这编译。

如果 write*Field 调用被替换为

jgen.writeNumberField("id", value.id);
etc
etc

然后我得到一个编译错误。无法访问私有财产。这与我所读到的背道而驰。Jackson如果有公共吸气剂,则可以访问私有财产。

显然,直接使用 getter 就可以了。有用。但我想知道我读过的各种文档是否有误。

标签: javajsonspring-bootserializationjackson

解决方案


如果要实现自定义序列化器并且不同时公开属性,则可以直接在类中实现com.fasterxml.jackson.databind.JsonSerializable接口:Climate

class Climate implements JsonSerializable {

    private long id;

    private float temperature;
    private float humidity;

    @Override
    public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();
        gen.writeNumberField("id", id);
        gen.writeNumberField("temperature", temperature);
        gen.writeNumberField("humidity", humidity);
        gen.writeEndObject();
    }

    @Override
    public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) {
    }
}

您的问题与Jackson直接无关。而是使用访问修饰符。当您想使用默认序列化时,请Jackson使用包含在许多功能中的反射将给定的POJO类序列化为JSON. 因此,确实Jackson可以使用私有字段,但在您的情况下,您希望实现自定义序列化程序,并且您需要自己使用反射来使其工作。在其他情况下,您可以使用default访问修饰符并将自定义序列化程序ClimateSerializer和类Climate放在同一个包中以使其工作。


推荐阅读