最近负责一个从第三方接口获取数据,并对数据封装的项目,项目中也有用到json格式数据,因此堪虑用Jackson中的jackson-dataformat-xml来解析xml,具体如下:
maven引入jar包
实体类
GradeDomain
public class GradeDomain {
@JacksonXmlProperty(localName = "gradeId",isAttribute = true)
private int gradeId;
@JacksonXmlText
private String gradeName;
......(get和set方法省略)
}
ScoreDomain
public class ScoreDomain {
@JacksonXmlProperty(localName = "scoreName")
@JacksonXmlCData
private String name;
@JacksonXmlProperty(localName = "scoreNumber")
private int score;
......(get和set方法省略)
}
StudentDomain
@JacksonXmlRootElement(localName = "student")
public class StudentDomain {
@JsonIgnore
private String studentName;
@JacksonXmlProperty(localName = "age")
@JacksonXmlCData
private int age;
@JacksonXmlProperty(localName = "grade")
private GradeDomain grade;
@JacksonXmlElementWrapper(localName = "scoreList")
@JacksonXmlProperty(localName = "score")
private List<ScoreDomain> scores;
......(get和set方法省略)
}
XmlMapper配置属性
ObjectMapper xmlMapper = new XmlMapper();
//反序列化时,若实体类没有对应的属性,是否抛出JsonMappingException异常,false忽略掉
xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//序列化是否绕根元素,true,则以类名为根元素
xmlMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
//忽略空属性
xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//XML标签名:使用骆驼命名的属性名,
xmlMapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
//设置转换模式
xmlMapper.enable(MapperFeature.USE_STD_BEAN_NAMING);
main方法中具体的使用
public static void main(String[] agr) throws JsonProcessingException {
ObjectMapper xmlMapper = new XmlMapper();
xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
xmlMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
xmlMapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);
xmlMapper.enable(MapperFeature.USE_STD_BEAN_NAMING);
StudentDomain domain = new StudentDomain();
domain.setStudentName("张三");
domain.setAge(18);
GradeDomain grade = new GradeDomain();
grade.setGradeId(1);
grade.setGradeName("高三");
domain.setGrade(grade);
ScoreDomain score1 = new ScoreDomain();
score1.setName("语文");
score1.setScore(90);
ScoreDomain score2 = new ScoreDomain();
score2.setName("数学");
score2.setScore(98);
ScoreDomain score3 = new ScoreDomain();
score3.setName("英语");
score3.setScore(91);
List<ScoreDomain> scores = Arrays.asList(score1,score2,score3);
domain.setScores(scores);
String xml = xmlMapper.writeValueAsString(domain);
System.out.println(xml);
StudentDomain studentDomain = xmlMapper.readValue(xml,StudentDomain.class);
System.out.println(studentDomain);
}
结果:
实体类转成xml:
xml转成实体类:
注解说明
@JacksonXmlRootElement用于类名,是xml最外层的根节点。注解中有localName属性,该属性如果不设置,那么生成的XML最外面就是Clazz.
@JacksonXmlCData注解是为了生成<![CDATA[text]]>
@JacksonXmlProperty注解通常可以不需要,若不用,生成xml标签名称就是实体类属性名称。但是如果你想要你的xml节点名字,首字母大写。比如例子中的Content,那么必须加这个注解,并且注解的localName填上你想要的节点名字。最重要的是!实体类原来的属性content必须首字母小写!否则会被识别成两个不同的属性。注解的isAttribute,确认是否为节点的属性,如上面“gradeId”。
@JacksonXmlElementWrapper一般用于list,list外层的标签。若不用的话,useWrapping =false
@JacksonXmlText,用实体类属性上,说明该属性是否为简单内容,如果是,那么生成xml时,不会生成对应标签名称
@JsonIgnore,忽略该实体类的属性,该注解是用于实体类转json的,但用于转xml一样有效,具体原因个人推测是XmlMapper是ObjectMapper的子类。
以上都是个人意见,若有错,请大佬指出来,谢谢!