JAXB Java 7 与 Java 8 的差异

2024-04-15

我发现在 Java 7 上处理 Jaxb 与在 Java 8 上处理 Jaxb 之间存在另一个区别。我已将问题简化为一个简化的示例,并且代码应作为单个类运行。 (更改了类别,因此它与工作无关等)当 Unmarshaller 调用列表的 setter 时: 我的问题实际上是一个变体

  1. 编码列表访问器时建议省略 在编写 JaxB 时完全使用 Setter 吗? (因为它似乎确实处理 通过 Getter 列出)
  2. 有推荐的替代方法吗?

在 Java 7 中运行时,将使用列表中的数据调用 setter。 当在 Java 8 中运行时,只会使用一个空的 List 对象来调用 setter,该对象显然会在稍后的解组过程中填充。 我体验到的不同之处在于,我不能让 setter 对 List 进行任何处理,而是有一个仅在整个对象解组后才调用的进程。或者总结一下,“不要在 setter 中进行任何处理”。 示例如下:(三个类)- 在 Java 7 下,返回的结果是在 setter 中找到的列表中的第一个“专辑”标题。在 Java 8 下,返回 null。 该代码应作为没有依赖项的单个类运行。 如果在 Java 7 中运行,“第一张专辑”显示的标题是“Abbey Road”。 如果在 Java 8 中运行“第一张专辑”标题为 null

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

public class MainJaxbCase {
    public static void main( String[] args ) {
        new MainJaxbCase().testIt();
    }
    private void testIt() {
        try {
        AlbumLib   myLib = (AlbumLib) loadJaxbDocFromString( inXmlStr, AlbumLib.class );
        System.out.println("category:"+ myLib.getCateg());
        List<AlbumItm> albumList = myLib.getAlbumList();
        System.out.println("AlbumList size is " + albumList.size());
        System.out.println("The first album is titled:"
                + myLib.getFirstAlbumTitle() 
                + "- shows \"null\" if using Java 8,  \"Abbey Road\" if using Java 7"
             );
        } catch ( Exception e ) {
            System.out.println( e.getClass().getSimpleName() + ", msg:" + e.getMessage() );
            e.printStackTrace();
        }
    }
    private final String inXmlStr = 
            "<my_lib categ='albums'>"
            + "  <album title='Abbey Road'/> "
            + "  <album title='Revolver'/>"
            + "  <album title='Sgt.Pepper'/>"
            + "</my_lib>";      


    private Object loadJaxbDocFromString ( String inStr, Class<?> clazz ) throws Exception {
        Object result = null;
        try {
            InputStream is = new ByteArrayInputStream( inStr.getBytes() );
            result = unmarshal( is, clazz  );
        } catch ( Exception e ) {
            String msg = this.getClass().getSimpleName() + ".loadJaxbDocFromResource() caught " + e.getClass().getSimpleName() + " msg:" + e.getMessage();
            throw new Exception(msg);
        }
        return result;
    }
    private Object unmarshal( InputStream prmIs, Class<?> clazz ) throws Exception{
        Object obj = null;
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance( clazz );
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            obj = jaxbUnmarshaller.unmarshal( prmIs );
        } catch ( Exception e ) {
            String msg = this.getClass().getSimpleName() + " caught " + 
                    e.getClass().getSimpleName() + ", msg:" + e.getMessage();
            msg += " Trying to Unmarshall class " + clazz.getName();
            System.err.println(msg);
            e.printStackTrace();
            throw new Exception(msg);
        }
        return obj;
    }
}



@XmlRootElement ( name= "my_lib")
class AlbumLib {
    private String      categ;
    private List<AlbumItm> albumList;
    private String firstAlbumTitle;

    @XmlAttribute ( name="categ")
    public String getCateg() {
        return this.categ;
    }
    public void setCateg( String val ) {
        this.categ=val;
    }

    @XmlElement ( name="album")
    public List<AlbumItm> getAlbumList() {
        return this.albumList;
    }
    public void setAlbumList( List<AlbumItm> newList ) {
        if ( newList != null && newList.size() > 0 ) {
            firstAlbumTitle = newList.get(0).getTitle();
        }
        this.albumList = newList;
    }
    public String getFirstAlbumTitle() {
        return this.firstAlbumTitle;
    }
}



@XmlType(name = "album")
class AlbumItm {
    private String title;
    @XmlAttribute ( name="title" )
    public String getTitle() {
        return this.title;
    }
    public void setTitle(String val ) {
        this.title = val;
    }
}

出现这个问题是因为我们的代码在切换到 Java 8 时开始表现出微妙(但重要)的差异,但没有任何明显的异常。


我们遇到了与您同样的问题,因为这篇博文 http://tonyz93.blogspot.com/2017/02/jaxb-diff-results-in-java7-and-java8.html#further stated.

  1. 在编码 JaxB 时,编码 List 访问器的建议做法是否完全省略 Setter? (因为它似乎确实通过 Getter 处理 List )
  2. 有推荐的替代方法吗?

重点不是“省略 Setter”,而是不要向 setter 添加更多功能。二传手只是二传手,仅此而已。添加更多逻辑违反了 setter 的“单一责任规则”,并且该函数的名称与其实际执行的操作不同,可能会出现更多错误。

当谈到推荐的方法时,没有涵盖所有情况的标准答案。考虑到不存在构造函数 init (这对于 JAXB 来说有点困难)并且我们在 setter 之后需要更多逻辑,我们有两个方向可供您选择:

  • Use XmlAdapter自定义构造以添加逻辑:适配器示例 http://tonyz93.blogspot.com/2017/01/jaxb-problem-list-2.html;
  • 不在此类中添加任何逻辑,创建另一个类来处理 xml 中的数据 --(这是首选,因为此类只是一些不应该有逻辑的 DTO)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAXB Java 7 与 Java 8 的差异 的相关文章

  • 如何克隆 JAXB 对象

    我有一些需要克隆的 jaxb 对象 由 jaxb 从 xsd 生成的代码实例化 Jaxb 类似乎没有提供可以轻松完成此操作的接口 我无法手动编辑该类 也无法扩展它 所以我需要创建一个帮助器 实用方法来执行此操作 最好的方法是什么 鉴于 JA
  • 如何拥有两个具有不同命名空间和相同 JAXB 类的不同端点?

    我正在使用弹簧肥皂ws 我有以下对应于复杂类型的 JAXB 域类 XmlAccessorType XmlAccessType FIELD XmlType name propOrder reference reason XmlRootElem
  • 使用 CXF Web 服务进行服务器端 XML 验证

    我正在开发 Apache CXF Web 服务 使用 JAX WS 通过 SOAP 该服务本身非常简单 接收请求 将请求插入数据库 然后返回插入是否成功 我想依靠 XML 验证来对请求实施一些约束 那么 我的问题 如何向我的服务客户返回详细
  • 使用 JAXB 将元素表示为布尔值?

    我们有这个 XML
  • JAXB - 将 SOAP 映射到 Java 类

    我需要帮助将我的 Soap Envelope 映射到 java 类 我的目的是将结果操纵到数据库 我在获取 SOAP 信封或使用 DB 方面没有任何问题 我的问题完全在于 JABX 以及根据我的 SOAP 信封映射我的类 这是我的肥皂
  • 如何在 Android 中通过 POST 请求查询 Web 服务?

    我完全陌生网络要素服务 WFS http en wikipedia org wiki Web Feature Service但我想构建一个 Android 应用程序ksoap2 android http code google com p
  • Spring AOP 日志拦截器和 JAXB 问题

    我正在尝试将日志记录方面实现到我的应用程序中 这是我第一次尝试 AOP 所以如果我遗漏了一些明显的东西 请告诉我 为了实现编织外部 jar 我正在尝试实现加载时间编织器 我确实在应用程序上下文中指定了加载时编织器 并在 context xm
  • XML 属性的 JAXB 解组问题

    我在使用 JAXB 解组 XML 文件时遇到问题 某些 xml 元素上有一个名为 display value 的属性 我需要获取该属性 以下是 XML 文件的一个小示例
  • MOXy 在 2.6.0 版本中支持非字符串 @XmlID 吗?

    根据https gist github com VineetReynolds 5108580 https gist github com VineetReynolds 5108580 JAXB 规范要求元素注释为 XmlID成为一个Stri
  • JAXB Java 7 与 Java 8 的差异

    我发现在 Java 7 上处理 Jaxb 与在 Java 8 上处理 Jaxb 之间存在另一个区别 我已将问题简化为一个简化的示例 并且代码应作为单个类运行 更改了类别 因此它与工作无关等 当 Unmarshaller 调用列表的 sett
  • XMI 2.1.1 的 XSD

    我必须使用 JAXB 解析 XMI 文件 xmi 版本 2 1 1 为此 我必须生成与 XMI 文件相对应的 Java 类 因此 我需要 xmi 文件的 shema 定义才能使用 jxc 工具执行此操作 我希望有人知道在哪里可以找到这个文件
  • 提取元素文本值

    我在用JAXB使用以下命令生成将 xml 解组为 java 实体的代码xsd原理图文件 问题是生成的代码不会生成name of an organization在以下 xml 中指定
  • 导致 SAXException2 的原因:“com.foo.Bar”的实例正在替换“java.lang.Object”,但“com.foo.Bar”绑定到匿名类型[重复]

    这个问题在这里已经有答案了 将现有 jaxb 同时使用 jaxb1 0 1 和 jaxb 2 0 5 应用程序 在带有 jdk5 的 JBoss 4 3 上 迁移到 jaxb 2 1 10 随 jdk6 提供 更新 jdk1 6 0 30
  • 最新的 Open JDK 8 JAXB 库无法解组具有包含换行符的属性的对象

    我在 Ubuntu 16 04 上使用 Java 最近我升级到使用 oracle java8 installer 包 包版本 8u161 1 webupd8 0 安装的 Open JDK java 版本 1 8 0 161 自从进行此升级以
  • 如何使用 JAXB 从 xsd 生成实现 Serialized 接口的 Java 类?

    我想将缓存引入到现有的 Spring 项目中 该项目使用 JAXB 来公开 WebServices 缓存将在端点级别完成 为了做到这一点 使用 JAXB 从 XSD 生成的类需要实现Serializable接口和覆盖Object s toS
  • JAXB/Jackson:没有父标签的两个元素的序列

    Update 寻找杰克逊orJAXB 解决方案 在对 Jackson 的行为进行了一些研究之后 我发现 Jackson 总是会使用集合的包装器 所以杰克逊可能无法满足我的需求 因此 将 JAXB 添加到标题中 原始问题 我需要为以下 XML
  • XmlAdapter 到 JAXB 绑定 Joda 的时间间隔?

    我已经被 Web 服务的 JAXB 绑定问题困扰了几个小时 为了准备一个必须返回 Joda Time 类实例 即时 持续时间 间隔等 的更大的 Web 服务 我从一个只有一个返回 Interval 的方法的 Web 服务开始 package
  • 将 XML 转换为 Java 对象 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用 Jaxb 和 JDK 9 的小程序中的非法反射访问[重复]

    这个问题在这里已经有答案了 我有一个 Java 小程序 它提供了一个 GUI 来调用 Web 服务 它使用 Jaxb 解析 XML 数据并将其解组为对象 它可以在 Java 1 5 到 1 8 上正确运行 对于 Java 9 情况就不那么严
  • JAXB - 列表<可序列化>?

    我使用 xjc 制作了一些课程 public class MyType XmlElementRefs XmlElementRef name MyInnerType type JAXBElement class required false

随机推荐