欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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命名空间问题时,再也不用愁了

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。