java xml jaxb_Java XML操作之JAXB命名空间及命名空间前缀处理

命名空间前缀处理

相信大名鼎鼎的ns2,nsXX让很多人非常头疼类似下面这样的

69c5a8ac3fa60e0848d784a6dd461da6.png<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

11

A1

22

B2

69c5a8ac3fa60e0848d784a6dd461da6.png

69c5a8ac3fa60e0848d784a6dd461da6.png@XmlSchema( xmlns = { @XmlNs(namespaceURI = "http://www.lzrabbit.cn", prefix = "rabbit"), @XmlNs(namespaceURI = "http://www.cnblogs.com", prefix = "blog")})packagecn.lzrabbit;importjavax.xml.bind.annotation.XmlSchema;import javax.xml.bind.annotation.XmlNs;

69c5a8ac3fa60e0848d784a6dd461da6.png

ClassA如下

cdec0645add3fc3c328197dda5c76203.png

81178cc93a2a3bb5048d90d76e7ec935.png

packagecn.lzrabbit;import javax.xml.bind.annotation.*;

@XmlRootElement(namespace="http://www.lzrabbit.cn")

@XmlAccessorType(XmlAccessType.FIELD)public classClassA {private intclassAId;

@XmlElement(name="ClassAName")privateString classAName;privateClassB classB;public intgetClassAId() {returnclassAId;

}public void setClassAId(intclassAId) {this.classAId =classAId;

}publicString getClassAName() {returnclassAName;

}public voidsetClassAName(String classAName) {this.classAName =classAName;

}publicClassB getClassB() {returnclassB;

}public voidsetClassB(ClassB classB) {this.classB =classB;

}

}View Code

序列化结果如下,可以看到已经按照我们所预期的修改了命名空间前缀,[email protected]ootElement(namespace="http://www.lzrabbit.cn")注解时指定的namespace必须和package-info.java定义的前缀一致,否则还是会生成nsXX这样的前缀

69c5a8ac3fa60e0848d784a6dd461da6.png<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

11

A1

22

B2

69c5a8ac3fa60e0848d784a6dd461da6.png

注意事项

1.若jdk版本为1.6的需要需要添加jaxb-core-2.2.7.jar和jaxb-impl-2.2.7.jar两个包的引用,否则即便设置了package-info的XmlSchema注解的xmlns注释也不能生效,若为jdk

1.7的无需添加

2.使用XmlSchema定义的前缀会对整个包生效,无法实现对每个实体类的单独前缀定义,很不灵活,故此不推荐使用此方式

解决方法二(推荐):

同方法一若jdk版本为1.6需要添加jaxb-core-2.2.7.jar和jaxb-impl-2.2.7.jar两个包的引用,不过方法二不需要添加package-info当然也就不需要定义XmlSchema

思路就是实现NamespacePrefixMapper抽象类,并重写getPreferredPrefix方法,看到方法名应该都明白了,对就是在序列化的时候重写获取命名空间前缀方法,为了简洁这里使用类匿名内部类实现的

69c5a8ac3fa60e0848d784a6dd461da6.pngmarshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", newNamespacePrefixMapper() {

@Overridepublic String getPreferredPrefix(String namespaceUri, String suggestion, booleanrequirePrefix) {if (namespaceUri.equals("http://www.lzrabbit.cn")) return "abc";returnsuggestion;

}

});

69c5a8ac3fa60e0848d784a6dd461da6.png

如上所示,在序列化时判断namespaceUri也就是我们定义的命名空间,然后返回我们自定义的前缀,其中的suggestion参数就是默认的前缀,有兴趣的话打印下就会发现suggestion就是ns2之类的前缀,把要自定义前缀的命名空间都在这里判断下就可以完全控制自定义前缀了,相对方法一来说可以实现对每个实体类的命名空间前缀控制,采用方法二后的序列化结果:

69c5a8ac3fa60e0848d784a6dd461da6.png<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

11

A1

22

B2

69c5a8ac3fa60e0848d784a6dd461da6.png

采用方法二后的序列化方法

cdec0645add3fc3c328197dda5c76203.png

81178cc93a2a3bb5048d90d76e7ec935.png

packagecn.lzrabbit;importjava.io.StringReader;importjava.io.StringWriter;import javax.xml.bind.*;importcom.sun.xml.bind.marshaller.NamespacePrefixMapper;importcom.sun.xml.bind.v2.WellKnownNamespace;public classXmlUtil {public staticString toXML(Object obj) {try{

JAXBContext context=JAXBContext.newInstance(obj.getClass());

Marshaller marshaller=context.createMarshaller();

marshaller.setProperty(Marshaller.JAXB_ENCODING,"UTF-8");// //编码格式

marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);//是否格式化生成的xml串

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false);//是否省略xm头声明信息

marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", newNamespacePrefixMapper() {

@Overridepublic String getPreferredPrefix(String namespaceUri, String suggestion, booleanrequirePrefix) {if (namespaceUri.equals("http://www.lzrabbit.cn")) return "abc";if (namespaceUri.contains("http://www.cnblogs.com")) return "blog";returnsuggestion;

}

});

StringWriter writer= newStringWriter();

marshaller.marshal(obj, writer);returnwriter.toString();

}catch(Exception e) {throw newRuntimeException(e);

}

}

@SuppressWarnings("unchecked")public static T fromXML(String xml, ClassvalueType) {try{

JAXBContext context=JAXBContext.newInstance(valueType);

Unmarshaller unmarshaller=context.createUnmarshaller();return (T) unmarshaller.unmarshal(newStringReader(xml));

}catch(Exception e) {throw newRuntimeException(e.getMessage());

}

}

}View Code

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页