2 回答

TA貢獻1876條經驗 獲得超5個贊
您可以為類定義自定義反序列化程序(作為問題中的第二個想法),并在內部使用自己的自定義:ObjectMapper
public class DataMapperJsonDeserializer extends JsonDeserializer<DataMapper> {
private static final ObjectMapper objectMapper = new ObjectMapper();
private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");
static {
SimpleModule module = new SimpleModule();
module.addDeserializer(BigInteger.class, new CustomBigIntegerJsonDeserializer());
module.addDeserializer(BigDecimal.class, new CustomBigDecimalJsonDeserializer());
module.addDeserializer(Boolean.class, new CustomBooleanJsonDeserializer());
module.addDeserializer(String.class, new CustomStringJsonDeserializer());
objectMapper.registerModule(module);
objectMapper.addMixIn(DataMapper.class, DefaultJsonDeserializer.class);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setDateFormat(simpleDateFormat);
}
@Override
public DataMapper deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
return objectMapper.readValue(jsonParser, DataMapper.class);
}
@JsonDeserialize
private interface DefaultJsonDeserializer {
// Reset default json deserializer
}
}
請注意使用 Jackson 混合注釋(接口)從類中動態刪除自定義反序列化程序,從而避免堆棧溢出錯誤,否則由于 而會引發。DefaultJsonDeserializerPOJOobjectMapper.readValue(jsonParser, DataMapper.class)
然后,只需注釋類:POJO
@JsonDeserialize(using = DataMapperJsonDeserializer.class)
public class DataMapper implements Serializable {
// It is not necessary to annotate each field with custom deserializers.
}
您甚至可以將其他類添加為 的字段,并且每種類型的自定義反序列化程序將自動應用于其字段,而無需注釋。POJODataMapper

TA貢獻1725條經驗 獲得超8個贊
您可以嘗試將簡單模塊
與上下文序列化程序接口一
起使用。第一個可用于包裝默認的去細節,第二個用于檢查類型配置 - 檢查注釋。
讓我們從注釋開始:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface ForceCustomDeserializer {
}
我假設您只有一個給定類型的自定義實現,但如果它不是真正的,請擴展上面的注釋并提供一些額外的信息,這些信息允許使用適當的去字符。例如,下面我們可以看到兩個自定義的去序列化器,它們額外記錄一些信息并運行默認的反序列化。使用基礎去細節,因為如果您有一些額外的配置,我們不會松動它。
class CustomBoolDeserializer extends StdScalarDeserializer<Boolean> implements ContextualDeserializer {
private NumberDeserializers.BooleanDeserializer base;
public CustomBoolDeserializer(NumberDeserializers.BooleanDeserializer base) {
super(Boolean.class);
this.base = base;
}
@Override
public Boolean deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
System.out.println("Custom BooleanDeserializer ....");
return base.deserialize(p, ctxt);
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) {
Class<?> parent = property.getMember().getDeclaringClass();
ForceCustomDeserializer annotation = parent.getAnnotation(ForceCustomDeserializer.class);
return annotation == null ? base : this;
}
}
class CustomStringDeserializer extends StringDeserializer implements ContextualDeserializer {
private final StringDeserializer base;
public CustomStringDeserializer(StringDeserializer base) {
this.base = base;
}
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
System.out.println("Custom StringDeserializer ....");
return base.deserialize(p, ctxt);
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) {
Class<?> parent = property.getMember().getDeclaringClass();
ForceCustomDeserializer annotation = parent.getAnnotation(ForceCustomDeserializer.class);
return annotation == null ? base : this;
}
}
我們可以測試上面的自定義實現,如下所示:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.deser.std.NumberDeserializers;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.deser.std.StringDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
SimpleModule forcedCustomModule = new SimpleModule();
forcedCustomModule.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
if (deserializer instanceof StringDeserializer) {
// wrap with yours or return new deserializer
return new CustomStringDeserializer((StringDeserializer) deserializer);
}
if (deserializer instanceof NumberDeserializers.BooleanDeserializer) {
// wrap with yours or return new deserializer
return new CustomBoolDeserializer((NumberDeserializers.BooleanDeserializer) deserializer);
}
// override for other types
return deserializer;
}
});
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(forcedCustomModule);
System.out.println(mapper.readValue(jsonFile, Pojo.class));
}
}
@ForceCustomDeserializer
class Pojo {
private String name;
private boolean bool;
// getters, setters, toString
}
以上示例為以下有效負載:JSON
{
"name": "Jackson",
"bool": true
}
指紋:
Custom StringDeserializer ....
Custom BooleanDeserializer ....
Pojo{name='Jackson', bool=true}
添加回答
舉報