草庐IT

java - JAXB:反序列化扩展类 A 的类 B 时出现问题

coder 2024-04-04 原文

请考虑以下示例:

有一个ClassA 和一个扩展它的ClassB。我现在的问题是我必须从 xml 文件中解码 ClassB。请注意 ClassA 无法更改,因为它不在我的控制之下。

这个例子中有几个问题:

主要问题是 ClassA 没有没有 Adapter 的 JAXB 所需的默认无参数构造函数。因此,我实现了 MyAdapter,它将 ClassB 映射到简单的类 ValB,JAXB 可以毫无问题地对其进行处理。

主要问题是如何让 JAXB 使用这个适配器?无论是在类级别上定义 @XmlJavaTypeAdapter 还是将适配器注册到解码器,都不会这样做。

有人知道如何让 JAXB 使用 MyAdapter 以便解码器返回一个对象,该对象是 ClassA 的实例吗?

public class JaxbTest {

    public static abstract class ClassA {
        public ClassA(String id) {
        }
    }

    @XmlRootElement
    @XmlJavaTypeAdapter(MyAdapter.class) // does not have an effect
    public static class ClassB extends ClassA {

        public String text;

        public ClassB() {
            super("");
        }
    }

    public static class ValB {
        public String text;
    }

    public static class MyAdapter extends XmlAdapter<ValB, ClassB> {

        @Override
        public ClassB unmarshal(ValB v) throws Exception {
            ClassB b = new ClassB();
            b.text = v.text;
            return b;
        }

        @Override
        public ValB marshal(ClassB v) throws Exception {
            ValB b = new ValB();
            b.text = v.text;
            return b;
        }

    }

    public static void main(String[] args) {
        try {
            JAXBContext context = JAXBContext.newInstance(ClassB.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            unmarshaller.setAdapter(new MyAdapter()); // does not have an effect
            ClassA a = (ClassA) unmarshaller.unmarshal(new File("test.xml"));
            // do somthing with a
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

顺便说一句:不要把代码看得太认真——它只是一个演示问题的例子。我知道 ClassAClassB 的定义并不是很有用。

最佳答案

更新

我们已在即将发布的 EclipseLink JAXB (MOXy) 中解决了这个问题2.2.0 版本(参见 bug #332742)。在此版本中,将不会检查抽象类的无参数构造函数。

从 12 月 18 日开始,可以在此处获得带有此修复程序的预发布版本:

解决方法

这就是@XmlTransient 注释的用途。如果可能,请执行以下操作:

@XmlTransient
public static abstract class ClassA {
    public ClassA(String id) {
    }
}

如果无法直接注释 ClassA,您可以利用 EclipseLink JAXB (MOXy)扩展来做到这一点。 MOXy 允许您将 JAXB 元数据指定为 XML 文件。当您无法修改模型类时,这很有用:

下面是一些解释@XmlAdapter的文章:

关于java - JAXB:反序列化扩展类 A 的类 B 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4459737/

有关java - JAXB:反序列化扩展类 A 的类 B 时出现问题的更多相关文章

  1. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  2. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  3. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  4. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  5. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  6. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  7. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  8. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  9. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  10. ruby - 更改 ActiveRecord 中对象的类 - 2

    假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。

随机推荐