JAXB命名空间及前缀_动力节点Java学院整理
本文讲解使用jaxb结合dom4j的XMLFilterImpl过滤器实现序列化和反序列化的完全控制
主要实现以下功能
- 序列化及反序列化时忽略命名空间
- 序列化时使用@XmlRootElement(namespace="http://www.lzrabbit.cn")注解作为类的默认命名空间,彻底消除命名空间前缀
- 序列化时引用类有不同命名空间时也不会生成命名空间前缀,而是在具体的xml节点上添加相应的xmlns声明
- 其它的xml节点命名及命名空间需求
- 同一个包下有多个命名空间
- 自定义命名空间前缀
依赖的jardom4j
dom4j dom4j 1.6.1
主要原理就是在序列化和反序列化时通过XMLFilterImpl的匿名实现类实现命名空间及xml节点名称的控制,实现多样化需求,废话不多说直接上代码,有更多个性化需求的看官请自行扩展
packagecom.bjpowernode.util; importjava.io.StringReader; importjava.io.StringWriter; importjavax.xml.bind.*; importjavax.xml.transform.sax.SAXSource; importorg.dom4j.io.OutputFormat; importorg.dom4j.io.XMLWriter; importorg.xml.sax.Attributes; importorg.xml.sax.InputSource; importorg.xml.sax.SAXException; importorg.xml.sax.XMLReader; importorg.xml.sax.helpers.XMLFilterImpl; importorg.xml.sax.helpers.XMLReaderFactory; publicclassXmlUtil{ publicstaticStringtoXML(Objectobj){ try{ JAXBContextcontext=JAXBContext.newInstance(obj.getClass()); Marshallermarshaller=context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_ENCODING,"UTF-8");////编码格式 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);//是否格式化生成的xml串 marshaller.setProperty(Marshaller.JAXB_FRAGMENT,false);//是否省略xm头声明信息 StringWriterout=newStringWriter(); OutputFormatformat=newOutputFormat(); format.setIndent(true); format.setNewlines(true); format.setNewLineAfterDeclaration(false); XMLWriterwriter=newXMLWriter(out,format); XMLFilterImplnsfFilter=newXMLFilterImpl(){ privatebooleanignoreNamespace=false; privateStringrootNamespace=null; privatebooleanisRootElement=true; @Override publicvoidstartDocument()throwsSAXException{ super.startDocument(); } @Override publicvoidstartElement(Stringuri,StringlocalName,StringqName,Attributesatts)throwsSAXException{ if(this.ignoreNamespace)uri=""; if(this.isRootElement)this.isRootElement=false; elseif(!uri.equals("")&&!localName.contains("xmlns"))localName=localName+"xmlns=\""+uri+"\""; super.startElement(uri,localName,localName,atts); } @Override publicvoidendElement(Stringuri,StringlocalName,StringqName)throwsSAXException{ if(this.ignoreNamespace)uri=""; super.endElement(uri,localName,localName); } @Override publicvoidstartPrefixMapping(Stringprefix,Stringurl)throwsSAXException{ if(this.rootNamespace!=null)url=this.rootNamespace; if(!this.ignoreNamespace)super.startPrefixMapping("",url); } }; nsfFilter.setContentHandler(writer); marshaller.marshal(obj,nsfFilter); returnout.toString(); }catch(Exceptione){ thrownewRuntimeException(e); } } publicstaticTfromXML(Stringxml,Class valueType){ try{ JAXBContextcontext=JAXBContext.newInstance(valueType); Unmarshallerunmarshaller=context.createUnmarshaller(); //return(T)unmarshaller.unmarshal(newStringReader(xml)); SerializeUtilobj=newSerializeUtil(); XMLReaderreader=XMLReaderFactory.createXMLReader(); XMLFilterImplnsfFilter=newXMLFilterImpl(){ privatebooleanignoreNamespace=false; @Override publicvoidstartDocument()throwsSAXException{ super.startDocument(); } @Override publicvoidstartElement(Stringuri,StringlocalName,StringqName,Attributesatts)throwsSAXException{ if(this.ignoreNamespace)uri=""; super.startElement(uri,localName,qName,atts); } @Override publicvoidendElement(Stringuri,StringlocalName,StringqName)throwsSAXException{ if(this.ignoreNamespace)uri=""; super.endElement(uri,localName,localName); } @Override publicvoidstartPrefixMapping(Stringprefix,Stringurl)throwsSAXException{ if(!this.ignoreNamespace)super.startPrefixMapping("",url); } }; nsfFilter.setParent(reader); InputSourceinput=newInputSource(newStringReader(xml)); SAXSourcesource=newSAXSource(nsfFilter,input); return(T)unmarshaller.unmarshal(source); }catch(Exceptione){ thrownewRuntimeException(e.getMessage()); } } }
示例实体类
importjavax.xml.bind.annotation.*; @XmlRootElement(namespace="http://www.lzrabbit.cn/") @XmlAccessorType(XmlAccessType.FIELD) publicclassClassA{ privateintclassAId; @XmlElement(name="ClassAName") privateStringclassAName; @XmlElement(namespace="http://www.cnblogs.com/") privateClassBclassB; publicintgetClassAId(){ returnclassAId; } publicvoidsetClassAId(intclassAId){ this.classAId=classAId; } publicStringgetClassAName(){ returnclassAName; } publicvoidsetClassAName(StringclassAName){ this.classAName=classAName; } publicClassBgetClassB(){ returnclassB; } publicvoidsetClassB(ClassBclassB){ this.classB=classB; } } importjavax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) publicclassClassB{ privateintClassBId; privateStringClassBName; publicintgetClassBId(){ returnClassBId; } publicvoidsetClassBId(intclassBId){ this.ClassBId=classBId; } publicStringgetClassBName(){ returnClassBName; } publicvoidsetClassBName(StringclassBName){ this.ClassBName=classBName; } }
调用
importcom.bjpowernode.util.XmlUtil; publicclassMainRun{ /** *@paramargs */ publicstaticvoidmain(String[]args){ ClassBclassB=newClassB(); classB.setClassBId(22); classB.setClassBName("B2"); ClassAclassA=newClassA(); classA.setClassAId(11); classA.setClassAName("A1"); classA.setClassB(classB); System.out.println(XmlUtil.toXML(classA)); } }
输出结果:
11 A1 22 B2
可以看到输出的xml完全达到我们的预期
实现细节都在代码里面了,很简单,当遇到有特殊需求的xml命名空间问题时,再也不用愁了
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。