JAXB命名空间及前缀_动力节点Java学院整理
程序员文章站
2024-02-24 15:40:04
本文讲解使用jaxb结合dom4j的xmlfilterimpl过滤器实现序列化和反序列化的完全控制
主要实现以下功能
序列化及反序列化时...
本文讲解使用jaxb结合dom4j的xmlfilterimpl过滤器实现序列化和反序列化的完全控制
主要实现以下功能
- 序列化及反序列化时忽略命名空间
- 序列化时使用
@xmlrootelement(namespace="http://www.lzrabbit.cn")
注解作为类的默认命名空间,彻底消除命名空间前缀 - 序列化时引用类有不同命名空间时也不会生成命名空间前缀,而是在具体的xml节点上添加相应的xmlns声明
- 其它的xml节点命名及命名空间需求
- 同一个包下有多个命名空间
- 自定义命名空间前缀
依赖的jar dom4j
<dependency> <groupid>dom4j</groupid> <artifactid>dom4j</artifactid> <version>1.6.1</version> </dependency>
主要原理就是在序列化和反序列化时通过xmlfilterimpl的匿名实现类实现命名空间及xml节点名称的控制,实现多样化需求,废话不多说直接上代码,有更多个性化需求的看官请自行扩展
package com.bjpowernode.util; import java.io.stringreader; import java.io.stringwriter; import javax.xml.bind.*; import javax.xml.transform.sax.saxsource; import org.dom4j.io.outputformat; import org.dom4j.io.xmlwriter; import org.xml.sax.attributes; import org.xml.sax.inputsource; import org.xml.sax.saxexception; import org.xml.sax.xmlreader; import org.xml.sax.helpers.xmlfilterimpl; import org.xml.sax.helpers.xmlreaderfactory; public class xmlutil { public static string 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头声明信息 stringwriter out = new stringwriter(); outputformat format = new outputformat(); format.setindent(true); format.setnewlines(true); format.setnewlineafterdeclaration(false); xmlwriter writer = new xmlwriter(out, format); xmlfilterimpl nsffilter = new xmlfilterimpl() { private boolean ignorenamespace = false; private string rootnamespace = null; private boolean isrootelement = true; @override public void startdocument() throws saxexception { super.startdocument(); } @override public void startelement(string uri, string localname, string qname, attributes atts) throws saxexception { if (this.ignorenamespace) uri = ""; if (this.isrootelement) this.isrootelement = false; else if (!uri.equals("") && !localname.contains("xmlns")) localname = localname + " xmlns=\"" + uri + "\""; super.startelement(uri, localname, localname, atts); } @override public void endelement(string uri, string localname, string qname) throws saxexception { if (this.ignorenamespace) uri = ""; super.endelement(uri, localname, localname); } @override public void startprefixmapping(string prefix, string url) throws saxexception { if (this.rootnamespace != null) url = this.rootnamespace; if (!this.ignorenamespace) super.startprefixmapping("", url); } }; nsffilter.setcontenthandler(writer); marshaller.marshal(obj, nsffilter); return out.tostring(); } catch (exception e) { throw new runtimeexception(e); } } public static <t> t fromxml(string xml, class<t> valuetype) { try { jaxbcontext context = jaxbcontext.newinstance(valuetype); unmarshaller unmarshaller = context.createunmarshaller(); // return (t) unmarshaller.unmarshal(new stringreader(xml)); serializeutil obj = new serializeutil(); xmlreader reader = xmlreaderfactory.createxmlreader(); xmlfilterimpl nsffilter = new xmlfilterimpl() { private boolean ignorenamespace = false; @override public void startdocument() throws saxexception { super.startdocument(); } @override public void startelement(string uri, string localname, string qname, attributes atts) throws saxexception { if (this.ignorenamespace) uri = ""; super.startelement(uri, localname, qname, atts); } @override public void endelement(string uri, string localname, string qname) throws saxexception { if (this.ignorenamespace) uri = ""; super.endelement(uri, localname, localname); } @override public void startprefixmapping(string prefix, string url) throws saxexception { if (!this.ignorenamespace) super.startprefixmapping("", url); } }; nsffilter.setparent(reader); inputsource input = new inputsource(new stringreader(xml)); saxsource source = new saxsource(nsffilter, input); return (t) unmarshaller.unmarshal(source); } catch (exception e) { throw new runtimeexception(e.getmessage()); } } }
示例实体类
import javax.xml.bind.annotation.*; @xmlrootelement(namespace="http://www.lzrabbit.cn/") @xmlaccessortype(xmlaccesstype.field) public class classa { private int classaid; @xmlelement(name="classaname") private string classaname; @xmlelement(namespace="http://www.cnblogs.com/") private classb classb; public int getclassaid() { return classaid; } public void setclassaid(int classaid) { this.classaid = classaid; } public string getclassaname() { return classaname; } public void setclassaname(string classaname) { this.classaname = classaname; } public classb getclassb() { return classb; } public void setclassb(classb classb) { this.classb = classb; } } import javax.xml.bind.annotation.*; @xmlaccessortype(xmlaccesstype.field) public class classb { private int classbid; private string classbname; public int getclassbid() { return classbid; } public void setclassbid(int classbid) { this.classbid = classbid; } public string getclassbname() { return classbname; } public void setclassbname(string classbname) { this.classbname = classbname; } }
调用
import com.bjpowernode.util.xmlutil; public class mainrun { /** * @param args */ public static void main(string[] args) { classb classb = new classb(); classb.setclassbid(22); classb.setclassbname("b2"); classa classa = new classa(); classa.setclassaid(11); classa.setclassaname("a1"); classa.setclassb(classb); system.out.println(xmlutil.toxml(classa)); } }
输出结果:
<?xml version="1.0" encoding="utf-8"?> <classa xmlns="http://www.lzrabbit.cn/"> <classaid>11</classaid> <classaname>a1</classaname> <classb xmlns="http://www.cnblogs.com/"> <classbid>22</classbid> <classbname>b2</classbname> </classb> </classa>
可以看到输出的xml完全达到我们的预期
实现细节都在代码里面了,很简单,当遇到有特殊需求的xml命名空间问题时,再也不用愁了
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。