java - Jackson 序列化器 - 访问私有(private)属性

标签 java json spring-boot serialization jackson

我有一个 Spring Boot 2 应用程序,其中包含私有(private)属性和公共(public) getters/setters 的模型。 Jackson 是 2.10.0 版本。

我需要一个自定义序列化程序来输出 JSON 而不扩展一些引用。据我所知,如果该属性是私有(private)的,Jackson 就无法访问它,并且会发生编译错误。除非在它应该起作用的时候有公共(public) setter/getter 。但事实并非如此。

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

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

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

@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

然后我得到一个编译错误。无法访问私有(private)属性(property)。这与我读到的内容相悖。如果存在公共(public) getter,则 Jackson 可以访问私有(private)属性。

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

最佳答案

如果您想实现自定义序列化程序并且同时不公开属性,您可以在 Climate 类中实现 com.fasterxml.jackson.databind.JsonSerialized 接口(interface)直接:

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没有直接关系。而与access modifiers 。当您想使用默认序列化时,Jackson 使用 reflection包含许多功能,可将给定的 POJO 类序列化为 JSON。因此,Jackson 确实可以使用私有(private)字段,但在您的情况下,您想要实现自定义序列化程序,并且您需要自己使用反射才能使其工作。在其他情况下,您可以使用 default 访问修饰符,并将自定义序列化器 ClimateSerializer 和类 Climate 放在同一个包中以使其正常工作。

关于java - Jackson 序列化器 - 访问私有(private)属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59477921/

相关文章:

json - Microsoft GRAPH 查询列出了使用端点/deviceManagement/deviceHealthScripts 检测脚本内容的不熟悉格式

json - 为什么我不能将 Map[String,Any] 序列化为 JSON?

java - 将 OpenTelemetry 跟踪数据从 Spring Boot 应用程序导入 Elastic APM - View 缺少数据

java - 未找到具有 URI 的 HTTP 请求的映射(spring 4.1 注释配置)

java - 框架 setVisible(false) 和 dispose() 无法杀死进程

java - 如何使用Maven项目在JAR中添加测试类

json - 尝试使用 didSelectRowAtIndexPath 更新标签

java - 如何扩展 log4j2 gelf 附加程序 (biz.paluch.logging) 以添加自定义 GelfSender

java 准备好的语句查询返回错误,但如果我打印它并直接在数据库上执行,它就可以工作

java - 理解 Hibernate 中的 @MapsId 注解