gpt4 book ai didi

java - 使用 Jackson 反序列化 java.utils.logging.Level 类返回 null

转载 作者:太空宇宙 更新时间:2023-11-04 09:11:55 24 4
gpt4 key购买 nike

我正在尝试使用 jackson 和 Lombok 构建器反序列化一个复杂的 bean。我已经解决了许多与其他自定义类型的序列化相关的错误,但我仍然坚持反序列化 Level 对象。序列化以某种方式起作用,但反序列化不起作用,如下所示。

由于 Level 类受到保护,因此我无法创建一个辅助变量来以不同的方式(例如字符串数组)序列化 Level 对象属性,然后在读取序列化的辅助变量后调用 Level 的构造函数,就像反序列化 Pair 类型时所做的那样。

我尝试反序列化的 bean 比下面的要复杂得多,但我能够在更简单、更容易理解的案例研究中重现该问题。

TL;博士

使用 jackson 反序列化 java.util.logging.Level 始终为 null

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;

import java.io.IOException;
import java.util.logging.Level;

public class ReproduceSerializationError {

public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
MyObj obj1 = MyObj.builder()
.level(Level.FINE)
.var1(10.0)
.build();
System.out.println("initial object = " + obj1.toString());

String serializedOj = serializeObj( obj1, objectMapper );
System.out.println("serialized json = " + serializedOj.toString());

MyObj deserialized = deserializeObj(serializedOj, objectMapper);
System.out.println("deserialized object = " + deserialized.toString());
System.out.println("logging level of deserialized object = " + deserialized.loggingLevel);
}

@ToString
@Getter
@JsonTypeInfo(use= JsonTypeInfo.Id.CLASS, property="class")
@JsonDeserialize(builder = MyObj.MyObjBuilder.class)
private static class MyObj{

private final double var1;
private Level level;

@JsonPOJOBuilder(withPrefix = "")
public static class MyObjBuilder {

}

@Builder
public MyObj(Level level, double var1){
this.level = level;
this.var1 = var1;
}
}

public static String serializeObj(MyObj obj1, ObjectMapper objectMapper) {
try {
return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj1);
} catch(JsonProcessingException e) {
throw new RuntimeException( e );
}
}

public static MyObj deserializeObj(String jsonInFile, ObjectMapper objectMapper) throws IOException {
return objectMapper.disable( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).readValue( jsonInFile, MyObj.class);
}
}

上面的代码打印以下内容:

initial object = ReproduceSerializationError.MyObj(var1=10.0, loggingLevel=FINE)
serialized json = {
"class" : "org.targomo.gp2.util.ReproduceSerializationError$MyObj",
"var1" : 10.0,
"loggingLevel" : {
"name" : "FINE",
"resourceBundleName" : "sun.util.logging.resources.logging",
"localizedName" : "FINE"
}
}
deserialized object = ReproduceSerializationError.MyObj(var1=10.0, loggingLevel=null)
logging level of deserialized object = null

如何正确反序列化 MyObjloggingLevel 属性?

最佳答案

您需要为 java.util.logging.Level 类实现自定义序列化器和反序列化器。由于级别是预定义的,我们无法创建它们,因此我们应该使用已经创建和声明的实例。请参阅下面的实现:

class LevelJsonSerializer extends JsonSerializer<Level> {

@Override
public void serialize(Level value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(value.getName());
}
}

class LevelJsonDeserializer extends JsonDeserializer<Level> {

@Override
public Level deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String name = p.getText();

return Level.parse(name);
}
}

您可以像下面这样注册以上类(class):

SimpleModule levelModule = new SimpleModule("LevelModule");
levelModule.addSerializer(Level.class, new LevelJsonSerializer());
levelModule.addDeserializer(Level.class, new LevelJsonDeserializer());

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(levelModule);

关于java - 使用 Jackson 反序列化 java.utils.logging.Level 类返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59578292/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com