JAXB命名空间_动力节点Java学院整理

发布时间 - 2026-01-11 02:54:23    点击率:

本篇介绍下JAXB进阶使用,命名空间处理

使用package-info.java添加默认命名空间

在需要添加命名空间的包下面添加package-info.java文件,然后添加@XmlSchema注解,这样整个包序列化时就都会自动加上命名空间了

@XmlSchema(namespace = "http://www.lzrabbit.cn")
package com.bjpowernode.test;

import javax.xml.bind.annotation.XmlSchema;

命名空间前缀处理

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

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:classA xmlns:ns2="http://www.lzrabbit.cn">
  <classAId>11</classAId>
  <ClassAName>A1</ClassAName>
  <classB>
    <ClassBId>22</ClassBId>
    <ClassBName>B2</ClassBName>
  </classB>
</ns2:classA>

解决方法一(不推荐):

添加package-info.java添加@XmlSchema注解并设置属性xmlns

@XmlSchema( xmlns = { @XmlNs(namespaceURI = "http://www.lzrabbit.cn", prefix = "rabbit"), @XmlNs(namespaceURI = "http://www.cnblogs.com", prefix = "blog")})

package com.bjpowernode.test;
import javax.xml.bind.annotation.XmlSchema;
import javax.xml.bind.annotation.XmlNs;

ClassA如下

Package com.bjpowernode.test;

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;

  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;
  }
}

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

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rabbit:classA xmlns:rabbit="http://www.lzrabbit.cn" xmlns:blog="http://www.cnblogs.com">
  <classAId>11</classAId>
  <ClassAName>A1</ClassAName>
  <classB>
    <ClassBId>22</ClassBId>
    <ClassBName>B2</ClassBName>
  </classB>
</rabbit:classA>

注意事项

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方法,看到方法名应该都明白了,对就是在序列化的时候重写获取命名空间前缀方法,为了简洁这里使用类匿名内部类实现的

marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapper() {
        @Override
        public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
          if (namespaceUri.equals("http://www.lzrabbit.cn")) return "abc";
          return suggestion;
        }
      });

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

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<abc:classA xmlns:abc="http://www.lzrabbit.cn">
  <classAId>11</classAId>
  <ClassAName>A1</ClassAName>
  <classB>
    <ClassBId>22</ClassBId>
    <ClassBName>B2</ClassBName>
  </classB>
</abc:classA>

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

package com.bjpowernode.test;

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.*;

import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
import com.sun.xml.bind.v2.WellKnownNamespace;

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头声明信息

      marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapper() {
        @Override
        public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
          if (namespaceUri.equals("http://www.lzrabbit.cn")) return "abc";
          if (namespaceUri.contains("http://www.cnblogs.com")) return "blog";
          return suggestion;
        }
      });

      StringWriter writer = new StringWriter();
      marshaller.marshal(obj, writer);
      return writer.toString();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @SuppressWarnings("unchecked")
  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));
    } catch (Exception e) {
      throw new RuntimeException(e.getMessage());
    }
  }
}

 现在我们基本解决了jaxb序列化xml的命名空间及前缀问题,但还是有很多问题,比如序列化和反序列化时如何忽略命名空间,如何使用@XmlRootElement控制每个实体类的默认命名空间也就是消除命名空间前缀

下一篇继续深入,Java XML操作之JAXB玩转命名空间 

最后给下jaxb-core-2.2.7.jar和jaxb-impl-2.2.7.jar两个包的maven引用

<dependency>
 <groupId>com.sun.xml.bind</groupId>
 <artifactId>jaxb-core</artifactId>
 <version>2.2.7</version>
</dependency>

<dependency>
 <groupId>com.sun.xml.bind</groupId>
 <artifactId>jaxb-impl</artifactId>
 <version>2.2.7</version>
</dependency>

也可以自行去官网下载 https://jaxb.java.net/

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# JAXB  # 命名空间  # JAXB命名空间及前缀_动力节点Java学院整理  # 序列化  # 自定义  # 不需要  # 实体类  # 重写  # 解决方法  # 进阶  # 就会  # 都在  # 是有  # 也就  # 很多人  # 推荐使用  # 要注意  # 有兴趣  # 会对  # 可以看到  # 大名鼎鼎  # 时就  # 可以实现 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法  JS中对数组元素进行增删改移的方法总结  ,网页ppt怎么弄成自己的ppt?  使用PHP下载CSS文件中的所有图片【几行代码即可实现】  Laravel如何与Docker(Sail)协同开发?(环境搭建教程)  详解阿里云nginx服务器多站点的配置  JavaScript实现Fly Bird小游戏  Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】  laravel怎么使用数据库工厂(Factory)生成带有关联模型的数据_laravel Factory生成关联数据方法  高性能网站服务器配置指南:安全稳定与高效建站核心方案  小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像  详解Android图表 MPAndroidChart折线图  Laravel如何与Pusher实现实时通信?(WebSocket示例)  教你用AI将一段旋律扩展成一首完整的曲子  消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工  Windows10如何更改计算机工作组_Win10系统属性修改Workgroup  微信推文制作网站有哪些,怎么做微信推文,急?  米侠浏览器网页图片不显示怎么办 米侠图片加载修复  如何在阿里云虚拟服务器快速搭建网站?  jQuery validate插件功能与用法详解  购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?  详解jQuery停止动画——stop()方法的使用  Zeus浏览器网页版官网入口 宙斯浏览器官网在线通道  独立制作一个网站多少钱,建立网站需要花多少钱?  宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法  Laravel怎么配置S3云存储驱动_Laravel集成阿里云OSS或AWS S3存储桶【教程】  JS去除重复并统计数量的实现方法  Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】  Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门  HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】  大型企业网站制作流程,做网站需要注册公司吗?  Android okhttputils现在进度显示实例代码  如何快速生成可下载的建站源码工具?  详解jQuery中基本的动画方法  如何挑选优质建站一级代理提升网站排名?  轻松掌握MySQL函数中的last_insert_id()  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  Laravel如何升级到最新的版本_Laravel版本升级流程与兼容性处理  如何快速搭建自助建站会员专属系统?  Java遍历集合的三种方式  活动邀请函制作网站有哪些,活动邀请函文案?  简历没回改:利用AI润色让你的文字更专业  html5audio标签播放结束怎么触发事件_onended回调方法【教程】  Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程  Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置  node.js报错:Cannot find module &#39;ejs&#39;的解决办法  如何快速搭建高效可靠的建站解决方案?