Jackson XML:如何将空/空集合序列化为空节点

2023-12-14

我正在使用 Jackson XML 2.8.9,不幸的是我找不到任何方法将空/空集合序列化为空节点。

负责序列化为 XML 的方法:

protected byte[] toXml(final Collection<ReportView> reports) throws IOException
{
    final XmlMapper mapper = new XmlMapper();
    // place for code which will solve my problem
    return mapper.writerWithDefaultPrettyPrinter().withRootName("report").writeValueAsBytes(reports);
}

我尝试使用:

  • 序列化包含:

    mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
    
  • 序列化提供者:

    final XmlSerializerProvider provider = new XmlSerializerProvider(new XmlRootNameLookup());
    provider.setNullValueSerializer(new JsonSerializer<Object>()
    {
        @Override
        public void serialize(final Object value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException
        {
            jgen.writeString("");
        }
    });
    mapper.setSerializerProvider(provider);
    
  • Jackson 2.9.0 EMPTY_ELEMENT_AS_NULL 功能:

    mapper.configure(FromXmlParser.Feature.EMPTY_ELEMENT_AS_NULL, false);
    

不幸的是没有任何效果。有人知道如何实现它吗?

测试方法:

@Test
public void testToXml() throws IOException
{
    final Map<String, Object> payload = new LinkedHashMap<>();
    payload.put("amp", "&");
    payload.put("empty", Collections.emptyList());
    final Date date = new Date();
    final ReportView reportView = new ReportView(payload, date, "system");

    // when
    final byte[] xmlBytes = reportService.toXml(Arrays.asList(reportView));

    // then
    final StringBuilder expected = new StringBuilder();
    expected.append("<report>");
    expected.append("  <item>");
    expected.append("    <payload>");
    expected.append("      <amp>&amp;</amp>");
    expected.append("      <empty></empty>");
    expected.append("    </payload>");
    expected.append("    <timestamp>" + date.getTime() + "</timestamp>");
    expected.append("    <changingUser>system</changingUser>");
    expected.append("  </item>");
    expected.append("</report>");

    final String xmlText = new String(xmlBytes).replace("\n", "").replace("\r", "");
    assertThat(xmlText).isEqualTo(expected.toString());
}

ReportView class:

public class ReportView {
    private final Map<String, Object> payload;
    private final Date timestamp;
    private final String changingUser;

    public ReportView(Map<String, Object> payload, Date timestamp, String changingUser) {
        this.payload = payload;
        this.timestamp= timestamp;
        this.changingUser = changingUser;
    }

    public String getChangingUser() {
        return changingUser;
    }

    public Date getTimestamp() {
        return timestamp;
    }

    public Map<String, Object> getPayload() {
        return payload;
    }
}

我准备了一个包含示例代码的存储库:https://github.com/agabrys/bugs-reports/tree/master/jackson-xml/empty-elements-serialization


EDIT:

我延长了测试时间toXml方法并进行了一些代码清理。

我还尝试创建一个基于的解决方案Module and SerializerModifier。可惜两者都以失败告终。我创建了一个问题jackson-dataformat-xml积压:

  • 使用自定义实现覆盖映射序列化器后的 NPE (XmlBeanSerializerModifier.modifyMapSerializer)

EDIT:

我有一个如何解决异常问题的提示(请参阅使用自定义实现覆盖映射序列化器后的 NPE (XmlBeanSerializerModifier.modifyMapSerializer))但仍然没有解决丢失的问题empty/null values.


我需要解决同样的问题,这就是我的解决方法:

首先,我创建一个序列化器,将 null 序列化为空字符串:

public class NullAsEmptyStringSerializer extends JsonSerializer<Object> {

  static final JsonSerializer<Object> INSTANCE = new NullAsEmptyStringSerializer();

  private static final String EMPTY_STRING = "";
  private final StringSerializer stringSerializer = new StringSerializer();

  @Override
  public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers)
      throws IOException {
    stringSerializer.serialize(EMPTY_STRING, gen, serializers);
  }
}

然后我创建一个序列化器修饰符,它用我的新序列化器覆盖 bean 属性的空序列化器:

public class NullToEmptyPropertySerializerModifier extends BeanSerializerModifier {

  @Override
  public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
      BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
    for (BeanPropertyWriter beanProperty : beanProperties) {
      beanProperty.assignNullSerializer(NullAsEmptyStringSerializer.INSTANCE);
    }

    return beanProperties;
  }
}

最后,我配置 xml 映射器以使用我的修饰符:

NullToEmptyPropertySerializerModifier modifier = new NullToEmptyPropertySerializerModifier();
SerializerFactory serializerFactory = BeanSerializerFactory.instance.withSerializerModifier(modifier);
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.setSerializerFactory(serializerFactory);

尝试看看它是否适用于字符串和对象(Person and Dog是虚拟数据持有者对象):

Dog dog = new Dog("bobby");
Person person = new Person("utku", null, 29, null);
String serialized = xmlMapper.writeValueAsString(person);
System.out.println(serialized);

给出以下输出:

<Person><name>utku</name><address></address><age>29</age><dog></dog></Person>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Jackson XML:如何将空/空集合序列化为空节点 的相关文章

随机推荐

  • 如何为结构的可变引用中的字段交换新值?

    我有一个带有字段的结构 struct A field SomeType Given a mut A 我怎样才能移动的值field并交换一个新值 fn foo a mut A let mut my local var a field a fi
  • php 中 var-export 函数的反义词是什么?

    我通过 将变量导出到文本区域变量导出 schools true 这样用户就可以编辑它 然后我想用所做的更改来 更新 变量 更新是通过 POST 方法接收的 我有一些text我想要成为变量 我怎样才能做到这一点 我现在所做的是在 php 文件
  • 如何在 CultureInfo(c#) 中显示尼日利亚奈拉符号

    我想显示带有尼日利亚货币符号的金额 即 N 带有双删除线 我已经尝试过 ff 段代码 它只显示带有 N 的金额 而不是带有正确的符号 N 带有双删除线 IFormatProvider currencyFormat new System Gl
  • Outlook REST API - getFolders 不返回所有文件夹

    我刚刚开始使用 Outlook REST API 我的基准是使用node outlook的教程 第一个任务是检索我的邮件帐户中的所有文件夹 所以我发出这个 REST 请求 GET https outlook office com api v
  • UTF-8 和 os.listdir()

    我在处理包含 字符的文件时遇到了一些麻烦 即 xC8 x99采用 UTF 8 拉丁文小写字母 S 下面带逗号 我正在创建一个 txt文件并尝试将其恢复os listdir 很遗憾 os listdir 将其返回为s xCC xA6 s 下面
  • 何时使用 toString() 方法

    这听起来可能非常基本 有人可以解释一下toString 方法以及何时有效使用该方法 在谷歌上进行了搜索 但找不到任何好的资源 在大多数语言中 toString或者等效的方法只是保证一个对象可以用文本表示 这对于日志记录 调试或任何其他需要能
  • Android:FragmentTabHost - java.lang.IllegalArgumentException:您必须指定一种创建选项卡内容的方法

    我在课堂上有以下内容用于创建FragmentTabHost public class TabsActivity extends FragmentActivity private FragmentTabHost mTabHost Overri
  • 双向重复测量ANOVA python函数

    预先感谢您的任何答复 我想在 python 中进行 2 路重复测量方差分析 其中一个 IV 有 5 个级别 其他 4 个级别 有一个 DV 我尝试查看 scipy 文档和一些在线博客 但似乎找不到任何东西 您可以使用rm anovaPino
  • 我希望能够通过网络从 BIOS 提取错误日志

    我希望能够通过网络从 BIOS 提取错误日志 查看 MSDN 中的 Win32 BIOS 我没有看到任何定义错误日志的内容 很乐意在 C 中使用 WMI 来完成此操作 但我愿意接受建议 是否可以 Win32 BIOS 没有包含 BIOS 错
  • 为什么在 PHP 中使用 ORM?

    最近开始学习ORM 突然想到一个问题 PHP 应用程序主要使用 MySql 和 Sqlite 几乎所有 PHP 服务器都安装了它们 那么是否值得在 PHP 中使用 ORM 来独立于数据库呢 性能怎么样 数据库独立性并不是使用 ORM 的主要
  • Jquery 自动完成 - 无结果消息

    我希望自动完成在下拉列表中显示 无结果 如果没有找到结果 则列出 我的情况就像 JQuery 默认示例 function var availableTags ActionScript AppleScript Asp BASIC C C Cl
  • R Shiny:Vtree 图未使用 Shiny 渲染

    如何在闪亮中使用 vtree 包 尝试从服务器端渲染时 没有出现所需的绘图 我的代码 library shiny library vtree Define UI ui lt pageWithSidebar App title headerP
  • ColdFusion、MS Word 文档和希腊字符

    我正在尝试从数据库动态构建 Word 文档 我使用 CFC 进行查询处理 我的努力是成功的 但我只能复制英语文档 但是 我的应用程序使用希腊语 当我尝试构建包含希腊字符的文档时 输出如下所示 我尝试了很多事情但没有任何效果 这里奇怪的是 当
  • 以天:小时:分钟:秒格式计算 SQL 中的 DateDiff

    我目前正在使用 SQL 脚本来计算两个日期之间的差异 这将为我提供 DD HH MI SEC 格式的结果 例子 日期 1 2012 年 7 月 30 日 下午 4 00 日期 2 2012 年 5 月 4 日上午 10 31 结果应该是 8
  • 当 puppet-rspec 存在时,为什么我会收到“类不存在”?

    我设置了一个新的木偶demo模块具有以下内容Gemfile当我运行一个简单的 puppet rspec 测试时 它按预期工作 Gemfile source https rubygems org if puppetversion ENV PU
  • 如何通过纯javascript中的每次点击来选择循环中下一个特定数量的元素?

    我试图为每次单击 下一步 按钮选择接下来的 3 个项目 nextElementSiblings 项目长度为 14 直到项目 12 为止它都工作正常 在项目 12 之后 它检查接下来的 3 个项目 但循环中只剩下 2 个项目 十三个 13 十
  • C++ 中重载运算符->

    我有一个智能指针类 我想重载operator gt 提供它是为了方便 这样我就可以直接访问智能指针中包含的类的成员 我正在研究 Boost 在其中实现该运算符的方式shared ptr模板 我注意到他们添加了一个断言 在返回指针之前检查指针
  • 将绘图映射到 FacetGrid 时的图例问题

    我还在seaborn git repo 中提出了一个问题here 然而 我很可能犯了一些基本错误 而不是错误 但我还没有弄清楚 问题 相同的颜色被分配给图例中的两个不同的值 当我扩展到更多仅包含分配给 色调 的值的子集的图形时 如何防止这种
  • 从检测方法调用自己的类时出现 Java NoClassDefFoundError

    我正在开发一套简单的 Java 代理工具包 以帮助我 也希望其他人 排除 Java 应用程序的故障 我想创建的代理之一是 JComponent getToolTipText 方法 只需将鼠标光标悬停在任何 GUI 类上即可快速识别该类 您可
  • Jackson XML:如何将空/空集合序列化为空节点

    我正在使用 Jackson XML 2 8 9 不幸的是我找不到任何方法将空 空集合序列化为空节点 负责序列化为 XML 的方法 protected byte toXml final Collection