我正在尝试基于我的对象类pojo创建json。对于某些字段,我希望使用customserializer,因为我希望根据需要创建字段。因此,我创建了 CustomSerializer.class
.
这个 CustomSerializer
将由我的中的两个不同字段调用 POJO
我想根据打电话的领域来处理不同的事情。为其中一个领域( extensions
)我想要一个 fieldName
以及其他领域( withoutExtensions
)我不希望有这样的机会 fieldname
在我的json中。
我面临的问题是 CustomSerializer
被称为然后我得到同样的 fieldname
对于我无法区分的两个调用,哪个字段当前正在调用 CustomSerializer
.
以下代码示例将更清楚地说明我面临的问题: Customer
用于序列化json的pojo类:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@NoArgsConstructor
public class Customer {
private String isA;
private String name;
@JsonSerialize(using = CustomSerializer.class)
private Map<String, Object> extensions = new HashMap<>();
private Map<String, Object> withoutExtensions = new HashMap<>();
@JsonAnyGetter
@JsonSerialize(using = CustomSerializer.class)
public Map<String, Object> getWithoutExtensions() {
return withoutExtensions;
}
}
下面是我的 CustomSerializer
在创建json期间,将由2个字段(扩展和withoutextensions)调用:
public class CustomSerializer extends JsonSerializer<Map<String, Object>> {
@Override
public void serialize(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) {
//I would like to create the outer object for "Extensions" but do not want to create outer object for "WithoutExtensions"
System.out.println(gen.getOutputContext().getCurrentName());
//In my case for both "Extensions" and "WithoutExtensions" i get the "currentName" as "Extensions" how can I ensure which field is calling this sealizer at
// present
}
}
下面是我的 Main
类,该类将创建json:
public class Main {
public static void main(String[] args) throws JsonProcessingException {
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
final Customer customer = new Customer();
customer.setName("Jackson");
Map<String, Object> extensions = new HashMap<>();
extensions.put("WithObject", "With");
customer.setExtensions(extensions);
Map<String, Object> withoutExtensions = new HashMap<>();
extensions.put("WithoutObject", "Without");
customer.setWithoutExtensions(withoutExtensions);
final String eventAsJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(customer);
System.out.println(eventAsJson);
}
}
正如我运行应用程序时所看到的 CustomSerializer
将打印 extensions
在这两种情况下。我认为应该打印出来 extensions
只有一次,在下一种情况下,它应该提供 withoutExtensions
或空字符串。
我只是想知道这是否是Jackson方面的一个错误,或者是否有任何解决办法,我可以尝试区分哪个领域正在给我的客户打电话 CustomSerializer
.
任何帮助都将不胜感激。谢谢
2条答案
按热度按时间wfypjpf41#
a。创建两个Map序列化器,其中一个创建外部对象,另一个不创建
赞成的意见:
易于实现
易于测试
一个类只做一件事
Map
不创建外部对象的serialiser可以由custom替换Map
serialiser(如果可能)欺骗:
如果他们需要共享状态,可能会有问题。
可能是重复的代码
b。实现contextualserializer接口
赞成的意见:
可以为每个字段单独配置
如果需要,可以共享状态。用户控制创建了多少示例。
欺骗:
做不止一件事
很容易过于复杂
示例:
需要双精度的jackson序列化程序,并且需要在运行时指定精度
用于自定义值序列化的jackson自定义注解
使用jackson反序列化为字符串或对象
jackson-将对象的内部列表反序列化为更高级别的列表
5ssjco0h2#
基于@michal的响应,我修改了代码,它对两种场景都有效。发布完整的代码示例,因为它可能对将来的人有所帮助:
Customer.class
补充道@Extensions
在必填字段上:@NoArgsConstructor
public class CustomSerializer extends JsonSerializer<Map<String, Object>> implements ContextualSerializer {
}
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface Extensions {
String extension();
}