用来记录一些原创性的总结
之前介绍的都是通过直接指定相关的Class作为入参的形式创建JAXBContext,如下所示:
JAXBContext jaxbContext = JAXBContext.newInstance(Response.class, Person.class);
另一种创建JAXBContext的方式是指定需要用到的Class所在的包名称,如下所示:
JAXBContext jaxbContext = JAXBContext.newInstance("com.elim.jaxb");
但是这时候并不是指定的包中所有的Class都会用来创建JAXBContext。按照JAXB的规范,我们需要在对应的包中创建一个jaxb.index文件,然后在其中指定创建JAXBContext时需要用到的Class,每个Class名称占一行,只需要写Class名称即可,如我们在创建JAXBContext时需要用到Response和Person类,我们就可以中jaxb.index文件中如下定义:
Response
Person
然后后续就可以用对应的JAXBContext来进行相应的Marshal和UnMarshal操作了。通过指定包名称创建JAXBContext的方式可以把程序中各种可能的场景中需要使用到的Class都初始化到一个JAXBContext中,这样可以保证这个JAXBContext可以在各种可能的场景下都能满足需求,JAXBContext的初始化是非常耗CPU的,重用JAXBContext有助于提升性能。另一方面我们如果中某一时刻调整使用的Class时可以不用修改源码,直接修改jaxb.index文件中定义的Class即可,这可比修改源码要简单的多。
为了保证文章的完整性,以下给出一个基于包名称初始化JAXBContext的完整示例。
@Test
public void testPerson() throws Exception {
Person person = new Person();
person.setId(1);
person.setName("张三");
Response response = this.newResponse(person);
JAXBContext jaxbContext = JAXBContext.newInstance("com.elim.jaxb");
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(response, System.out);
}
private Response newResponse(Data realData) {
Response response = new Response();
response.setReturnCode(100);
response.setMessage("AAAA");
ResultData resultData = new ResultData();
resultData.setRealData(realData);
response.setResultData(resultData);
return response;
}
@XmlRootElement
public class Response {
private int returnCode;
private String message;
@XmlElement(name = "data")
private ResultData resultData;
//省略get/set
}
public class ResultData {
@XmlElementRef
private Data realData;
//省略get/set
}
public class Data {
}
@XmlRootElement(name="dept")
public class Person extends Data {
@XmlAttribute
private Integer id;
private String name;
//省略get/set
}
Response
Person