我有这个JSON来反序列化:
{
"first-name": "Alpha",
"last-name": "Beta",
"gender": "m"
}
我想将其序列化为两种不同的格式:
[A]
{
"first-name": "Alpha",
"last-name": "Beta",
"gender": "m"
}
[B]
{
"firstName": "Alpha",
"lastName": "Beta",
"gender": "m"
}
我能够将其序列化为1种格式:仅[A]或仅[B]。这是我将其序列化为[B]的代码:
public String firstName;
public String lastName;
public String gender;
@JsonProperty("firstName")
public String getFirstNameCC() {
return firstName;
}
@JsonProperty("first-name")
public void setFirstNameD(String firstName) {
this.firstName = firstName;
}
@JsonProperty("lastName")
public String getLastNameCC() {
return lastName;
}
@JsonProperty("last-name")
public void setLastNameD(String lastName) {
this.lastName = lastName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
我在这里阅读了JsonView
http://www.baeldung.com/jackson-json-view-annotation(第5节。自定义JSON视图')但它只更改了其值。我想更改字段名称作为上面的例子。任何人都可以对此有所了解吗?
答案 0 :(得分:5)
我不确定我完全理解你的问题,但是我能理解你可以做这样的事情来实现不同的序列化。
创建自定义注释以包含所有可能的不同序列化选项:
@JsonSerialize(using = CustomJsonPropertySerializer.class)
public class Bar {
@CustomJsonProperty.List({
@CustomJsonProperty(propertyName = "first-name", format = "A"),
@CustomJsonProperty(propertyName = "firstName", format = "B")
})
private String firstName;
@CustomJsonProperty.List({
@CustomJsonProperty(propertyName = "last-name", format = "A"),
@CustomJsonProperty(propertyName = "lastName", format = "B")
})
private String lastName;
@CustomJsonProperty.List({
@CustomJsonProperty(propertyName = "gender-x", format = "A"),
@CustomJsonProperty(propertyName = "gender", format = "B")
})
private String gender;
@JsonIgnore
private String format;
//getters & setters
}
相应地注释您的课程:
public class CustomJsonPropertySerializer extends JsonSerializer<Bar> {
@Override
public void serialize(Bar bar, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
jsonGenerator.writeStartObject();
Field[] fields = bar.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object value = null;
try {
value = field.get(bar);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (field.isAnnotationPresent(CustomJsonProperty.List.class)) {
CustomJsonProperty[] properties = field.getAnnotation(CustomJsonProperty.List.class).value();
CustomJsonProperty chosenProperty = null;
for (CustomJsonProperty c : properties) {
if (c.format().equalsIgnoreCase(bar.getFormat())) {
chosenProperty = c;
break;
}
}
if (chosenProperty == null) {
//invalid format given, use first format then
chosenProperty = properties[0];
}
jsonGenerator.writeStringField(chosenProperty.propertyName(), value.toString());
}
}
jsonGenerator.writeEndObject();
}
}
创建自定义序列化程序以解释新注释:
public static void main(String[] args) throws IOException {
Bar bar1 = new Bar("first", "last", "m", "A");
Bar bar2 = new Bar("first", "last", "m", "B");
ObjectMapper mapper = new ObjectMapper();
String json1 = mapper.writeValueAsString(bar1);
String json2 = mapper.writeValueAsString(bar2);
System.out.println(json1);
System.out.println(json2);
}
现在,您可以根据属性名称的不同格式序列化对象:
{"first-name":"first","last-name":"last","gender-x":"m"}
{"firstName":"first","lastName":"last","gender":"m"}
输出:
abstract String getFormat();
当然上面的序列化程序仅适用于Bar对象,但是可以使用超类上的builder.RegisterGeneric(typeof(RequestHandler<>))
.Named("requestHandler", typeof(IRequestHandler,<>));
继承并更改自定义序列化程序以接受超类类型而不是Bar来轻松解决。
也许有一种比创建自己的东西更简单的方法,但我不知道。如果有什么不清楚我可以告诉我,我可以再详细说明一下。
答案 1 :(得分:0)
有一种更简单的方法可以执行此操作-创建一个使用“ addMixin”功能的对象映射器。
要序列化的类:
Class YouWantToSerializeMe {
public String firstName;
public String lastName;
public String gender;
@JsonProperty("firstName")
public String getFirstNameCC() {
return firstName;
}
@JsonProperty("lastName")
public String getLastNameCC() {
return lastName;
}
}
现在,要同时使用内置字段名称和自定义字段名称进行序列化,您可以执行以下操作:
Class DoTheSerializing {
String serializeNormally(YouWantToSerializeMe me) {
ObjectMapper objectMapper = new ObjectMapper();
ObjectWriter objectWriter = objectMapper.writer();
return objectWriter(me)
}
String serializeWithMixin(YouWantToSerializeMe me) {
ObjectMapper objectMapper = new ObjectMapper();
ObjectWriter objectWriter = objectMapper
.addMixIn(YouWantToSerializeMe.class, MyMixin.class)
.writer();
return objectWriter(me)
}
interface MyMixin {
@JsonProperty("first-name")
public String getFirstNameCC();
@JsonProperty("last-name")
public String getLastNameCC();
}
}
这在类中使用嵌入式接口来使内容保持非常本地化。您可以对此进行很多优化,例如创建静态ObjectMapper以及加载/卸载mixin。
使用界面作为“模板”来控制映射功能确实非常强大。您可以在字段级别和类级别添加内容。