Java Jackson:POJO由JSON对象、字符串数组或字符串定义
我希望能够使用Jackson将几种JSON格式解析为相同的以下对象:Java Jackson:POJO由JSON对象、字符串数组或字符串定义,java,json,jackson,Java,Json,Jackson,我希望能够使用Jackson将几种JSON格式解析为相同的以下对象: public类SpeechAction扩展了动作{ 公共字符串[]speechText; } 知道我的父类是: 公共集体诉讼{ 公共字符串onCompletedEvent; } 我希望能够支持的格式(为了便于编写,因为它将由人而不是机器编写一段时间)是: 1。简单字符串: { “讲话”: } 2。字符串数组: { “讲话”:[ , , … ] } 3。嵌套的简单字符串: { “讲话”:{ “演讲稿”:, “onCo
public类SpeechAction扩展了动作{
公共字符串[]speechText;
}
知道我的父类是:
公共集体诉讼{
公共字符串onCompletedEvent;
}
我希望能够支持的格式(为了便于编写,因为它将由人而不是机器编写一段时间)是:
1。简单字符串:
{
“讲话”:
}
2。字符串数组:
{
“讲话”:[
,
,
…
]
}
3。嵌套的简单字符串:
{
“讲话”:{
“演讲稿”:,
“onCompletedEvent”:
}
}
4。嵌套字符串数组:
{
“讲话”:{
“演讲稿”:[
,
,
…
],
“onCompletedEvent”:
}
}
使用以下代码成功解析格式1、3和4:
public类SpeechAction扩展了动作{
@JsonFormat(with=JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
@JsonProperty(“speechText”)
公共字符串[]speechText;
公开演讲{
speechText=新字符串[]{”“};
}
公开演讲(字符串…文本){
speechText=文本;
}
公众演讲(字符串文本){
speechText=新字符串[]{text};
}
}
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.WRAPPER\u对象)
@JsonSubTypes({@JsonSubTypes.Type(value=SpeechAction.class,name=“speech”)})
公共集体诉讼{
@JsonProperty(“onCompletedEvent”)
公共字符串onCompletedEvent;
}
但我还没能解决格式2的问题。我在尝试分析时遇到以下异常:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.nerus.app.actions.SpeechAction` out of START_ARRAY token
at [Source: (String)"{
"speech": [
"Hello there!",
"Hey you!"
]
}
"; line: 2, column: 11]
通过使用@JsonCreator注释,我能够支持格式1和格式2,但3和4立即丢失
我探索了自定义反序列化器方法,但为了不想失去注释的优势,我没有看到如何以一种不会对父类的“onCompletedEvent”属性重复的方式来完成它(因为我有大量从Action继承的类)
谢谢你的任何线索 Jackson API为您提供了一个名为JsonNode的通用对象,它可以解析任何类型的JSON流,除非您收到有效的JSON输入。因此,您可以总是将JSON模式4看作是常见的JSON,因为它涵盖了所有的场景。 我坚信这是一个设计缺陷。鉴于这种情况,我想从三个方面来处理这个问题
ObjectMapper
映射它们ObjectMapper
将输入JSON映射到JsonNode
,并找到所有必需的字段。(这是处理JSON最简单的方法。)public class JsonTest {
public static void main(String[] args) throws JsonProcessingException, IOException {
String jsoninpt = "{\r\n" +
" \"speech\": \"speech text\"\r\n" +
"}";
String jsoninpt1 = "{\r\n" +
" \"speech\": [\r\n" +
" \"speech text1\",\r\n" +
" \"speech text2\"\r\n" +
" ]\r\n" +
"}";
String jsonInpt2 = "{\r\n" +
" \"speech\": {\r\n" +
" \"speechText\": <speech_text>,\r\n" +
" \"onCompletedEvent\":<EVENT_NAME>\r\n" +
" }\r\n" +
"}";
String jsonInput3 = "{\r\n" +
" \"speech\": {\r\n" +
" \"speechText\":[\r\n" +
" <variant1>, \r\n" +
" <variant2>, \r\n" +
" …\r\n" +
" ],\r\n" +
" \"onCompletedEvent\":<EVENT_NAME>\r\n" +
" }\r\n" +
"}";
jsonParser(jsoninpt);
}
public static void jsonParser(String jsoninput) throws IOException {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonInputNode = mapper.readTree(jsoninput);
System.out.println(mapper.writeValueAsString(jsonInputNode));
if(jsonInputNode.has("speech")) {
JsonNode value = jsonInputNode.get("speech");
if(value.isTextual()) {
String speechText = value.asText();
System.out.println(speechText);
}else if(value.isArray() || value.isObject()) {
Iterator<Entry<String, JsonNode>> speechObjects = value.fields();
while(speechObjects.hasNext()) {
Entry<String,JsonNode> speechObject = speechObjects.next();
String key = speechObject.getKey();
JsonNode node = speechObject.getValue();
}
}
}
}
}
公共类JsonTest{
公共静态void main(字符串[]args)抛出JsonProcessingException、IOException{
字符串jsoninpt=“{\r\n”+
“\”语音\“:\”语音文本\“\r\n”+
"}";
字符串jsoninpt1=“{\r\n”+
“\“speech\”:[\r\n”+
“\”语音文本1\”,\r\n“+
“\”语音文本2\“\r\n”+
“]\r\n”+
"}";
字符串jsonInpt2=“{\r\n”+
“\”语音\“:{\r\n”+
“\”speechText\“:,\r\n“+
“\”onCompletedEvent\”:\r\n“+
“}\r\n”+
"}";
字符串jsonInput3=“{\r\n”+
“\”语音\“:{\r\n”+
“\“speechText\”:[\r\n”+
“,\r\n”+
“,\r\n”+
“…\r\n”+
“],\r\n”+
“\”onCompletedEvent\”:\r\n“+
“}\r\n”+
"}";
jsonParser(jsoninpt);
}
公共静态void jsonParser(字符串jsoninput)引发IOException{
ObjectMapper mapper=新的ObjectMapper();
JsonNode jsonInputNode=mapper.readTree(jsoninput);
System.out.println(mapper.writeValueAsString(jsonInputNode));
if(jsonInputNode.has(“speech”)){
JsonNode value=jsonInputNode.get(“语音”);
if(value.isTextual()){
String speechText=value.asText();
System.out.println(speechText);
}else if(value.isArray()| | value.isObject()){
迭代器speechObjects=value.fields();
while(speechObjects.hasNext()){
条目speechObject=speechObjects.next();
String key=speechObject.getKey();
JsonNode节点=speechObject.getValue();
}
}
}
}
}
为什么不对所有JSON输入类型使用通用JSON格式“4”?您好@Phani Kumar Yadavilli,谢谢您的评论!我之所以考虑支持几种格式(完整格式4中较短的格式),是因为在可预见的未来,这些JSON将由人手工编写,而不是自动生成。在那种情况下,打字越简单越好。