使用 Jackson XmlWrapper 在类中第二个时无法反序列化(转换)未包装的列表

2023-12-04

我正在尝试使用 Jackson 的 XmlMapper 来反序列化一些包含未包装列表的简单 xml 文件。

My code:

package zm.study.xmlserialize.jackson;

import java.util.List;

import org.junit.Test;

import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper    ;

public class JacksonListTest {

    public static class A {
        public String c;
        @JacksonXmlElementWrapper(useWrapping=false)
        public List<String> as;
    }

    @Test
    public void deserializeTest() throws Exception
    {
        XmlMapper mapper = new XmlMapper();
        String xml = "<A><c>c</c><as>a1</as><as>a2</as></A>";
        //mapper.readValue(xml, A.class);
        mapper.convertValue(mapper.readTree(xml), A.class);
    }

}

不幸的是,当列表不是 class/xml 中的第一个时,库会引发异常。

当我从 xml 和类中删除“c”元素时,异常消失了。 如果我使用 readValue 而不是 ConvertValue,异常也会消失,但我需要 ConvertMethod 才能工作。

例外的是:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList` out of VALUE_STRING token
 at [Source: (StringReader); line: 1, column: 18] (through reference chain: zm.study.xmlserialize.jackson.JacksonListTest$A["as"])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343)

...


我不确定是否可以通过这种方式做到这一点。readTree方法返回扩展的对象JsonNode,在这种情况下它将是ObjectNode. ObjectNode不接受两个同名的属性,最后反序列化后它代表:

{"c":"c","as":"a2"}

之后你想将该节点转换为A POJO班级。默认解串器List期望START_ARRAY令牌不String。您可以通过实现扩展的自定义转换器来使其工作StdConverter<String, List>但列表将被修剪为一个元素。在这种情况下,我认为,你必须使用readValue方法,因为你需要指示Jackson that as元素是展开的数组。

EDIT
在你的评论之后我意识到我们可以欺骗XmlMapper使用我们想要的任何东西。很明显Jackson uses JsonNodeDeserializer反序列化JsonNode-s。因此,我们需要做的就是找到一个可以注入代码的地方。幸好有一个方法_handleDuplicateField它处理我们的案例。默认情况下,如果FAIL_ON_READING_DUP_TREE_KEY标志已启用:

protected void _handleDuplicateField(JsonParser p, DeserializationContext ctxt,
        JsonNodeFactory nodeFactory,
        String fieldName, ObjectNode objectNode,
        JsonNode oldValue, JsonNode newValue)
    throws JsonProcessingException
{
    // [databind#237]: Report an error if asked to do so:
    if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY)) {
        ctxt.reportInputMismatch(JsonNode.class,
                "Duplicate field '%s' for ObjectNode: not allowed when FAIL_ON_READING_DUP_TREE_KEY enabled",
                fieldName);
    }
}

那么,让我们利用这个事实来扩展这个类:

class MergeDuplicateFieldsJsonNodeDeserializer extends JsonNodeDeserializer {
    @Override
    protected void _handleDuplicateField(JsonParser p, DeserializationContext ctxt, 
                                         JsonNodeFactory nodeFactory, String fieldName, ObjectNode objectNode, 
                                         JsonNode oldValue, JsonNode newValue) throws JsonProcessingException {
        super._handleDuplicateField(p, ctxt, nodeFactory, fieldName, objectNode, oldValue, newValue);

        ArrayNode array;
        if (oldValue instanceof ArrayNode) {
            // Merge 3-rd, 4-th, ..., n-th element to already existed array
            array = (ArrayNode) oldValue;
            array.add(newValue);
        } else {
            // Merge first two elements
            array = nodeFactory.arrayNode();
            array.add(oldValue);
            array.add(newValue);
        }
        objectNode.set(fieldName, array);
    }
}

现在,我们需要注册这个反序列化器。整个测试可能如下所示:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;

import java.util.Arrays;
import java.util.List;

public class XmlMapperApp {

    public static void main(String[] args) throws Exception {
        A a = new A();
        a.c = "String";
        a.as = Arrays.asList("1", "2", "tom", "Nick");

        SimpleModule mergeDuplicatesModule = new SimpleModule("Merge duplicated fields in array");
        mergeDuplicatesModule.addDeserializer(JsonNode.class, new MergeDuplicateFieldsJsonNodeDeserializer());

        XmlMapper mapper = new XmlMapper();
        mapper.registerModule(mergeDuplicatesModule);

        String xml = mapper.writeValueAsString(a);

        System.out.println(xml);
        System.out.println(mapper.readTree(xml));
    }
}

上面的代码打印:

<A><c>String</c><as>1</as><as>2</as><as>tom</as><as>Nick</as></A>
{"c":"String","as":["1","2","tom","Nick"]}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Jackson XmlWrapper 在类中第二个时无法反序列化(转换)未包装的列表 的相关文章

  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • Spring Data JPA 应用排序、分页以及 where 子句

    我目前正在使用 Spring JPA 并利用此处所述的排序和分页 如何通过Spring data JPA通过排序和可分页查询数据 https stackoverflow com questions 10527124 how to query
  • 我可以使用 HSQLDB 进行 junit 测试克隆 mySQL 数据库吗

    我正在开发一个 spring webflow 项目 我想我可以使用 HSQLDB 而不是 mysql 进行 junit 测试吗 如何将我的 mysql 数据库克隆到 HSQLDB 如果您使用 spring 3 1 或更高版本 您可以使用 s
  • 无法解析插件 Java Spring

    我正在使用 IntelliJ IDEA 并且我尝试通过 maven 安装依赖项 但它给了我这些错误 Cannot resolve plugin org apache maven plugins maven clean plugin 3 0
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • 为什么HashMap不能保证map的顺序随着时间的推移保持不变

    我在这里阅读有关 Hashmap 和 Hashtable 之间的区别 http javarevisited blogspot sg 2010 10 difference Between hashmap and html http javar
  • JRE 系统库 [WebSphere v6.1 JRE](未绑定)

    将项目导入 Eclipse 后 我的构建路径中出现以下错误 JRE System Library WebSphere v6 1 JRE unbound 谁知道怎么修它 右键单击项目 特性 gt Java 构建路径 gt 图书馆 gt JRE
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 玩!框架:运行“h2-browser”可以运行,但网页不可用

    当我运行命令时activator h2 browser它会使用以下 url 打开浏览器 192 168 1 17 8082 但我得到 使用 Chrome 此网页无法使用 奇怪的是它以前确实有效 从那时起我唯一改变的是JAVA OPTS以启用
  • 在activity_main.xml中注释

    我是安卓新手 据我所知 XML 中的注释与 HTML 中的注释相同 使用 形式 我想在 Android 项目的 Activity main xml 配置文件中写一些注释 但它给了我错误 值得注意的是 我使用的是 Eclipse 但目前 我直
  • 获取 JVM 上所有引导类的列表?

    有一种方法叫做findBootstrapClass对于一个类加载器 如果它是引导的 则返回一个类 有没有办法找到类已经加载了 您可以尝试首先通过例如获取引导类加载器呼叫 ClassLoader bootstrapLoader ClassLo
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口
  • java.lang.IllegalStateException:驱动程序可执行文件的路径必须由 webdriver.chrome.driver 系统属性设置 - Similiar 不回答

    尝试学习 Selenium 我打开了类似的问题 但似乎没有任何帮助 我的代码 package seleniumPractice import org openqa selenium WebDriver import org openqa s
  • 如何实现仅当可用内存较低时才将数据交换到磁盘的写缓存

    我想将应用程序生成的数据缓存在内存中 但如果内存变得稀缺 我想将数据交换到磁盘 理想情况下 我希望虚拟机通知它需要内存并将我的数据写入磁盘并以这种方式释放一些内存 但我没有看到任何方法以通知我的方式将自己挂接到虚拟机中before an O
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两

随机推荐

  • jQuery 原地弹跳

    我需要我的列表项元素弹跳到位 而不是相互掉落 我创建了一个 JSFiddle 来表达我的意思 http jsfiddle net RGvjj 有人可以告诉我为什么这些元素会这样做以及我需要做什么来解决这个问题吗 尝试删除inline显示从
  • WPF ErrorTemplate 在未聚焦时可见?

    我正在使用 WPF 验证进行 TextBox 验证 我定义了这个模板
  • GZipStream:压缩文件比原始文件大

    我正在尝试在 C 中使用 gzip 流 但压缩后的文件似乎比以前大 当我使用 avi 和 mkv 文件时会发生这种情况 但是如果我使用比原始文件小的 txt 和 html 压缩文件 using MemoryStream output new
  • 如何使用 cURL 将文件内容作为正文实体发送

    我正在使用 cURL 命令行实用程序将 HTTP POST 发送到 Web 服务 我想将文件的内容作为 POST 的正文实体包含在内 我尝试过使用 d to filename gt 以及带有类型信息的其他变体 例如 data to file
  • 如何使用 TcpListener 和 TcpClient 创建双工连接?

    我遇到一种情况 我需要并行发送和接收信息 我的协议可以定义读取端口和写入端口 我目前有以下代码 public void Listen ThreadPool SetMinThreads 50 50 listener Start while t
  • Twitter LED 时间线

    你好 我已经为 twitter 时间轴编写了一个脚本 它可以工作 除了我不知道如何授权我的 twitter api 密钥之外 我的 led 标志只是说 错误的身份验证数据 这是我的代码 usr bin perl require LWP Us
  • sf sfc对象的坐标变换似乎不起作用

    我有一个 R sf 对象 library sf library magritr g1 structure list ele c 1819 80249 1821 150879 1825 393188 1817 905029 time stru
  • 如何访问 .ashx 文件中的本地化资源?

    我有一个 ashx 文件 它返回本地化消息 这是从 Ajax 请求调用的 我需要访问 ashx 文件中的 Asp net ResourceManager 以下代码对我有用 HttpContext GetGlobalResourceObjec
  • 为 C++/C Visual Studio 解决方案项目创建 Nuget 包

    我有几个用 C C 编写的旧组件 希望将它们包装到 Nuget 包中并从 C 代码中使用此包 将 C 代码实际包装在 nuget 包中的最佳方法是什么 我看过CoApp解决方案 但现在似乎不受支持 离线稳定版本 我可以回答如何从 Visua
  • 在 jquery ui 日期选择器中如何允许选择特定工作日并禁用其他工作日

    我需要将 jquery ui 日期选择器限制为仅将未来的星期二和星期四作为可选日期 我怎样才能做到这一点 这一切都在文档中 beforeShowDay 函数将执行您想要的操作 http api jqueryui com datepicker
  • IPython 将变量加载到工作区:你能想到比这更好的解决方案吗?

    我正在从 MATLAB 迁移到 ipython 在迈出这一步之前 我将完成我的最小工作流程 以确保我每天在 MATLAB 上执行的用于数据处理的每项操作都可以在 ipython 上使用 我目前陷入了通过单行命令 例如 MATLAB 的命令
  • 实现像 Wordle 这样的词云的算法

    Context 看看Wordle http www wordle net 它比我见过的任何其他词云生成器都要好看得多 注意 来源不可用 请阅读常见问题解答 http www wordle net faq code 我的问题 有没有一种算法可
  • 如果 BYMONTHDAY 是周末,iCal 可以在 BYMONTHDAY 之后的第一个工作日安排活动吗?

    如果我在该月的某一天 即 15 日 有一个重复发生的事件 并且该天恰逢周六或周日 iCal 是否可以将该事件安排在下一个可用的工作日发生 您不能设置例外 但可以使用 byday 和 bymonthday 的组合 类似的东西会给你一个周末后的
  • 如何在“android水平进度条”中绘制垂直线

    我需要制作一个自定义水平进度条 如下图所示 我使用图层列表设计了如下图所示的进度条 可绘制 我想在进度大于 25 时画一条垂直线 如图所示 我需要的 我写了这段代码 但它不起作用 myProgressBar ProgressBar find
  • 按列进行动态 SQL 透视 SQL Server

    假设我们有n列与m rows table 1 someName1 someName2 someName3 someNameN 12 5 12 34 56 6 33 2 1 2323 12 5 57 2 123 1 2 789 45 2 76
  • STM32 F072上的软件如何跳转到bootloader(DFU模式)?

    STM32应用笔记2606对此进行了讨论 但没有简单的代码示例 该答案已使用 IAR EWARM 在 STM32F072 Nucleo 板上进行了测试 这个答案使用 STM32标准外设库 仅此而已 请注意 验证您是否成功进入引导加载程序模式
  • ArrayList 中类对象属性的总和

    我有一个 ArrayList 其中有很多对象 我想要计算相同属性名称的值的总和 示例 数据在Array List这是对象损益数据DO Michel 5000 Alex 5000 Edvin 4000 Sosha 3000 Michel 20
  • R:制作加拿大邮政编码地图

    我正在使用 R 编程语言 这是我的问题的一些背景 在加拿大 每个地址都有一个邮政编码 如美国邮政编码 这些邮政编码的格式为 字母编号字母 数字字母编号 例如 A1B 2C3 邮政编码的前三个字符称为 FSA 所有前三个字母相同的邮政编码均被
  • 通过反射检索参数值

    我试图提出一种方法的设计 该方法采用另一个方法作为参数并检索所传递方法的参数值 如何才能做到这一点 我尝试过使用java lang reflect 但似乎找不到支持此的API 您无法真正获得像这样作为参数传递的值 你可以自己做Proxy并在
  • 使用 Jackson XmlWrapper 在类中第二个时无法反序列化(转换)未包装的列表

    我正在尝试使用 Jackson 的 XmlMapper 来反序列化一些包含未包装列表的简单 xml 文件 My code package zm study xmlserialize jackson import java util List