我有一个简单的POJO:
public class Entry {
private Integer day;
private String site;
private int[] cpms;
... // getters/setters/constructor
}
我想阅读的日志文件似乎是:
{ "day":"1", "site":"google.com", "cpms":"[1,2,3,4,5,6,7]"}
Jackson根据文档自动将String转换为Integer。但它不适用于现场" cpms"。阅读它的最佳方法是什么? 我知道我可以定义" cpms"在构造函数中作为字符串,然后解析此字符串从中执行数组,如下所示:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
this.cpm = objectMapper.readValue(cpms, int[].class);
但是有没有智能转换?
答案 0 :(得分:2)
此转换也可以使用自定义JsonDeserializer
完成。
1)实现专用的反序列化器类,例如:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
public class IntArrayDeserializer extends StdDeserializer<int[]> {
public IntArrayDeserializer() {
super(int[].class);
}
@Override
public int[] deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext) throws IOException {
String arrayAsString = jsonParser.getText();
if (arrayAsString.length() == 2) { // case of empty array "[]"
return new int[0];
}
String[] strIds = arrayAsString.substring(1, arrayAsString.length() - 1).split(",");
return Arrays.stream(strIds).mapToInt(Integer::parseInt).toArray();
}
}
2)在@JsonDeserialize(using = IntArrayDeserializer.class)
字段上添加Entry.cpms
。
3)现在下面的测试应该通过:
@Test
public void deserializeExample() throws IOException {
String json = "{ \"day\":\"1\", \"site\":\"google.com\", \"cpms\":\"[1,2,3,4,5,6,7]\"}";
ObjectMapper mapper = new ObjectMapper();
Entry entry = mapper.readValue(json, Entry.class);
int[] expected = new int[] { 1, 2, 3, 4, 5, 6, 7 };
assertTrue(Arrays.equals(expected, entry.getCpms()));
}
这种方法的优点是,如果有其他字段以相同的方式转换,这个解串器是可重用的,它与Jackson API一致,并且不需要实现临时解决方案。
答案 1 :(得分:2)
据我所知,杰克逊没有任何内置的解决方案。你的数组用引号括起来,所以它是一个字符串。但是,有些方法可能适合您:
定义用@JsonCreator
注释的构造函数,然后解析字符串:
public class Entry {
private Integer day;
private String site;
private int[] cpms;
@JsonCreator
public Entry(@JsonProperty("cpms") String cpms) {
String[] values = cpms.replace("[", "").replace("]", "").split(",");
this.cpms = Arrays.stream(values).mapToInt(Integer::parseInt).toArray();
}
// Getters and setters
}
编写自己的反序列化程序,然后可以在其他bean中重用它:
public class QuotedArrayDeserializer extends JsonDeserializer<int[]> {
@Override
public int[] deserialize(JsonParser jp,
DeserializationContext ctxt) throws IOException {
String rawValue = jp.getValueAsString();
String[] values = rawValue.replace("[", "").replace("]", "").split(",");
return Arrays.stream(values).mapToInt(Integer::parseInt).toArray();
}
}
public class Entry {
private Integer day;
private String site;
@JsonDeserialize(using = QuotedArrayDeserializer.class)
private int[] cpms;
// Getters and setters
}