我们的模型类使用@XmlJavaTypeAdapter 注释(在类级别)。解码对根元素和包含/嵌套(根据我们在自定义 XmlAdapter 中实现的内容)很好地工作。
到目前为止,我们是 XML 和 JSON 序列化/反序列化的快乐露营者。但是,出现了一个新的需求,我不知道如何实现它?
在某些情况下,我希望能够“恢复”为包含的默认 JAXB 行为:我希望忽略/覆盖类级别的 @XmlJavaTypeAdapter 注释。
我花了几个小时阅读 Blaise Doughan 的博客 ( http://blog.bdoughan.com/ ) 并搜索 StackOverflow 和 Google,但找不到优雅/实用的解决方案。
这里是一个快速设置来说明我们目前拥有的东西(请注意,为了简单起见,我们所有的 JPA/Hibernate/其他注释都没有列出,但它们确实存在于我们的模型类 (POJO) 中):
类主任
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
@XmlJavaTypeAdapter(XmlMasterAdapter.class)
public class Master {
@XmlElement
private Long masterPrimaryKey;
@XmlElement
private String name;
}
类详细信息
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
@XmlJavaTypeAdapter(XmlDetailAdapter.class)
public class Detail {
@XmlElement
private Long detailPrimaryKey;
@XmlElement
private Master master; // reference/foreign key. No need for @XmlJavaTypeAdapter since it's defined at the class-level in Master.
@XmlElement
private String value;
}
当Master作为根元素时,XML是这样的:
<master>
<masterPrimaryKey>1234</masterPrimaryKey>
<name>master name</name>
</master>
当 Master 用作包含/嵌套元素时,XML 是这样的:(感谢我们自定义的 XmlAdapter,
到目前为止,一切正常,我们对此很满意。 现在,我们的新需求: 我希望遏制在特定情况下以不同的方式发挥作用。
我希望 Master 上的类级 @XmlJavaTypeAdapter 在特定上下文中“暂时”被忽略/恢复/覆盖。我希望默认的 JAXB 解码器能够启动(就好像所包含的类上从来没有类级别的@XmlJavaTypeAdapter)。 考虑一种数据导入情况,我们在一个有效负载中接收主数据和所有详细信息。就好像它们都是独立的根元素,包裹在一个大的 DTO/传输容器中。 这是呈现我们想要的内容的 XML: 类 MasterDetailImport 我正在寻找的是神奇的 [但不存在] @PLEASE_IGNORE_CLASS_LEVEL_XmlJavaTypeAdapter_AND_UNMARSHAL_AS_IF_IT_WERE_A_ROOT_ELEMENT 注释,它允许我指示 JAXB 执行操作,就好像 @XmlJavaTypeAdapter 从未在类级别为嵌套类定义过一样。 到目前为止,我们设想[但不喜欢]的解决方案是: 仅当我们必须支持导入时才创建“镜像”DTO 对象以进行反序列化。这种方法有很多缺点(仅用于反序列化的重复代码、将 DTO 内容复制到模型类中的适配器、需要编写/维护的更多单元测试等)。 在我们希望能够导入/嵌套的所有实体上摆脱类级@XmlJavaTypeAdapter,并在使用嵌套/包含的所有属性上显式使用@XmlJavaTypeAdapter。我测试了这种方法并且知道它会起作用。但是,我认为它很容易出错,不像在类级别定义它那样优雅,并且能够有一个异常/特殊情况/覆盖处理告诉 JAXB 暂时表现得好像它不知道 @XmlJavaTypeAdapter 已在类上定义. 我的想法已经用完了……我尝试寻找 JAXB 的默认 XML 适配器,但没有成功:javax.xml.bind.annotation.adapters.XmlAdapter
现在,简单的问题:
如何实现@PLEASE_IGNORE_CLASS_LEVEL_XmlJavaTypeAdapter_AND_UNMARSHAL_AS_IF_IT_WERE_A_ROOT_ELEMENT? 提前致谢!<detail>
<detailPrimaryKey>5678</detailPrimaryKey>
<master>1234</master>
<value>detail value</value>
</detail>
<masterDetailImport>
<master>
<!-- Primary keys omitted because of the import mode -->
<name>master name</name>
</master>
<details>
<detail>
<value>detail 1 value</value>
</detail>
<detail>
<value>detail 2 value</value>
</detail>
<detail>
<value>detail 3 value</value>
</detail>
</details>
</masterDetailImport>
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class MasterDetailImport implements Serializable
{
@XmlElement
@PLEASE_IGNORE_CLASS_LEVEL_XmlJavaTypeAdapter_AND_UNMARSHAL_AS_IF_IT_WERE_A_ROOT_ELEMENT
private Master master;
@XmlElementWrapper(name="details")
@XmlElement
@PLEASE_IGNORE_CLASS_LEVEL_XmlJavaTypeAdapter_AND_UNMARSHAL_AS_IF_IT_WERE_A_ROOT_ELEMENT
private List<Detail> detail = new ArrayList<Detail>();
}
最佳答案
将始终应用 JAXB 中的 XmlAdapter,但您可以将逻辑放入 XmlAdapter 本身来处理您的用例。默认情况下,每次使用时都会创建一个新的 XmlAdapter 实例,如果您的 XmlAdapter 是有状态的,您可以在 Marshaller 上设置一个实例> 或 Unmarshaller 以便改用它。您可以利用它来帮助确定是否应该应用它。
下面是我对一个相关问题给出的答案的链接,其中有状态的 XmlAdapter 用于在第一次引用对象时内联对象,然后在以后每次将其编码为链接它被引用。
关于java - 在某些情况下如何忽略/禁用/恢复/覆盖 JAXB 类级 @XmlJavaTypeAdapter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19842179/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我有一大串格式化数据(例如JSON),我想使用Psychinruby同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解