Elim的博客

用来记录一些原创性的总结


Elim

通过包名创建JAXBContext

之前介绍的都是通过直接指定相关的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