在JAVA中使用空格名解析YAML

时间:2016-12-08 17:43:24

标签: java jackson yaml

YAML

innings:
  - 1st innings:
      team: Australia
      runs:500
  - 2nd innings:
      team: Australia
      runs:501

JAVA代码:

import java.io.File;
import java.util.List;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

/**
 * Hello world!
 *
 */
public class App {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
        try {
            Innings user = mapper.readValue(new File("a.txt"), Innings.class);
            System.out.println(ReflectionToStringBuilder.toString(user,ToStringStyle.MULTI_LINE_STYLE));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Innings {
    public List<Inning> innings;    
}
class Inning{
    public int runs;
    public String team;
}

错误迹:     com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段&#34;第一局&#34; (类Inning),未标记为可忽略(2个已知属性:,&#34;运行&#34;,&#34;团队&#34;])      在[来源:a.txt; line:3,column:7](通过参考链:局[&#34;局和#34;] - &gt;局内线[&#34;第一局&#34;])

注意:如果杰克逊在这里没有帮助,请建议其他解析器。

2 个答案:

答案 0 :(得分:0)

我对YAMLFactory并不是很熟悉,但如果我修改你的POJO:

class innings {
  public inning[] innings;
}
class inning {
  @JsonProperty("1st innings")
  public inning_deep first;

  @JsonProperty("2nd innings")
  public inning_deep second;
}
class inning_deep{
  public int runs;
  public String team;
}

它好像可以反序列化,但显然这对你来说可能还不够。如果这是JSON,我会用数组替换两个inning_deep属性,它会正常工作。我认为这是YAMLFactory中的限制,可能您需要编写自定义反序列化程序。

您可以通过打开问题here获得更多帮助。 请重新考虑课程命名以尊重naming conventions

注意:通常我不会尝试发布不完整的答案,但看起来并不像其他人知道如何修复它。

答案 1 :(得分:0)

使用自定义反序列化程序。谢谢大家。

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

public class InningsParse {
    public static void main(String[] args) {
        ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
        SimpleModule module = new SimpleModule();
        module.addDeserializer(Inning.class, new InningDeserializer());
        mapper.registerModule(module);
        try {
            Innings user = mapper.readValue(new File("a.txt"), Innings.class);
            System.out.println(ReflectionToStringBuilder.toString(user,ToStringStyle.MULTI_LINE_STYLE));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class Innings {
    public List<Inning> innings;
}
class Inning{
    public int runs;
    public String team;
}
class InningDeserializer extends StdDeserializer<Inning> { 

    public InningDeserializer() { 
        this(null); 
    } 

    public InningDeserializer(Class<?> vc) { 
        super(vc); 
    }

    @Override
    public Inning deserialize(JsonParser jp, DeserializationContext ctxt) 
      throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        String nodeS = node.toString();
        nodeS = nodeS.substring(nodeS.indexOf(':')+1, nodeS.toString().lastIndexOf('}'));
        System.out.println(nodeS);
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(nodeS,Inning.class);
    }
}