【问题标题】:How can I deal with "null objects" (not null) using JAXB?如何使用 JAXB 处理“空对象”(非空)?
【发布时间】:2015-09-09 21:21:51
【问题描述】:

我正在编写一个软件来管理盒子事件。核心类是BoxEventFightFighter。一个盒子事件有一个所有可用战士的列表以及包含对特定战士的引用的战斗。

对于引用,每个Fighter 都有一个唯一的 ID,用作@XmlID,并在通过@XmlIDREF 的战斗列表中引用。 JAXB(un)编组工作正常。 XML 文件与此类似:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<boxEvent>
<fighter uuid="id_efc8c3f6-f95c-424f-a6d4-f9fde1cdd3a1">
    <birthday>1995-08-31</birthday>
    <firstName>Donald</firstName>
    <lastName>Duck</lastName>
    <gender>MALE</gender>
    <weight>62.0</weight>
</fighter>
<fighter uuid="id_356f82d1-14a7-4cce-bf5b-18d6e59eddfe">
    <birthday>1994-08-25</birthday>
    <firstName>Mickey</firstName>
    <lastName>Mouse</lastName>
    <gender>MALE</gender>
    <weight>56.9</weight>
</fighter>
<fighter uuid="id_c4b8d4c9-de24-4bfb-bad8-36a5bd4433b5">
    <birthday>1991-08-12</birthday>
    <firstName>Minnie</firstName>
    <lastName>Mouse</lastName>
    <gender>FEMALE</gender>
    <weight>40.8</weight>
</fighter>
<fights>
    <fighterInBlueCorner>id_356f82d1-14a7-4cce-bf5b-18d6e59eddfe</fighterInBlueCorner>
    <fighterInRedCorner>id_efc8c3f6-f95c-424f-a6d4-f9fde1cdd3a1</fighterInRedCorner>
</fights>
</boxEvent>

现在的问题是,一场战斗可能还没有两个战士,而只有一个。这是通过使用特殊的 Fighter 对象(null object)和 not null 在内部实现的,并且此特殊对象 not 在所有拳击手列表中(因为它不是真正的拳击手,而是一个实现细节)。这意味着:一个失踪的战士可以在战斗中被编组(因为它有一个 ID,因为从技术上讲它是一个Fighter),但它不能被解组,因为这个 ID 不会在所有战士的列表中找到。

虽然我已经找到了存储null(例如this question)的解决方案,但我找不到适合“空对象”的解决方案。

所以我的问题是:是否可以使用@XmlJavaTypeAdapter 或任何其他技术将空对象替换为null 进行编组?而在解组时则相反:为一个角落里失踪的战士创建这个特殊的空对象?

我也很高兴听到有关如何处理该问题的其他想法,或者您能否为我指明正确的方向。谢谢!

【问题讨论】:

    标签: java xml jaxb


    【解决方案1】:

    不,@XmlJavaTypeAdapter 不会触发空值。相反,您应该拥有所需的任何“默认值”。如果它确实在 XML 中,则解组代码将覆盖战斗机。

    @XmlElement
    private Fighter fighter = DEFAULT_FIGHTER_OR_NULL_OR_WHATEVER;
    

    【讨论】:

      【解决方案2】:

      我最初的问题可能有点太复杂了——抱歉! :) 我终于自己发现了如何正确解决我的问题——好吧,只需在Fight 类中使用@XmlJavaTypeAdapter。适配器非常简单,如下所示:

      public class FighterXmlAdapter extends XmlAdapter<Fighter, Fighter> {
      
        @Override
        public Fighter unmarshal(final Fighter fighter) throws Exception {
          return fighter == null ? NULL_FIGHTER : fighter;
        }
      
        @Override
        public Fighter marshal(final Fighter fighter) throws Exception {
          return fighter.equals(NULL_FIGHTER) ? null : fighter;
        }
      
      }
      

      所以如果只有红角的战斗机出现,序列化的 XML 将如下所示:

      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <boxEvent>
        <fighter uuid="id_efc8c3f6-f95c-424f-a6d4-f9fde1cdd3a1">
          <birthday>1995-08-31</birthday>
          <firstName>Donald</firstName>
          <lastName>Duck</lastName>
          <gender>MALE</gender>
          <weight>62.0</weight>
        </fighter>
        <fighter uuid="id_356f82d1-14a7-4cce-bf5b-18d6e59eddfe">
          <birthday>1994-08-25</birthday>
          <firstName>Mickey</firstName>
          <lastName>Mouse</lastName>
          <gender>MALE</gender>
          <weight>56.9</weight>
        </fighter>
        <fights>
          <fighterInRedCorner>id_efc8c3f6-f95c-424f-a6d4-f9fde1cdd3a1</fighterInRedCorner>
        </fights>
      </boxEvent>
      

      这意味着丢失的战斗机的内部实现没有公开,并且在加载文件时会实例化NULL_FIGHTER。很简单,但我花了一段时间才弄明白... ;)

      【讨论】:

        猜你喜欢
        • 2023-03-03
        • 2014-05-12
        • 2016-01-16
        • 2022-01-19
        • 1970-01-01
        • 2012-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多