如何反序列化java Long哪个xml标签有xsi:nil?

Posted

技术标签:

【中文标题】如何反序列化java Long哪个xml标签有xsi:nil?【英文标题】:How to deserialize java Long which xml tag has xsi:nil? 【发布时间】:2020-02-05 04:18:22 【问题描述】:

我有一个使用 Spring Boot 2.1.9 和 RestTemplate 的 maven 项目,当我使用 RestTemplate.exchange 方法时,它显示“无法在运行时反序列化 'java.lang.Long' 的实例,因为 xml 标记带有 xsi:nil="真的”。

class Pojo 
    private List<Long> values;

xml:

<?xml version="1.0" encoding="utf-8"?>
<PojoResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/">
    <values>
        <value>10</value>
        <value xsi:nil="true" />
        <value>20</value>
    </values>
</PojoResponse>

【问题讨论】:

【参考方案1】:

我解决了这个问题,包括 jackson-dataformat-xml、jackson-core 和 jackson-databind 版本 2.10.0 对 pom.xml 的依赖。

【讨论】:

【参考方案2】:

你可以注册自己的DeserializationProblemHandler,当&lt;value xsi:nil="true" /&gt;出现时返回null

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;

import java.io.File;
import java.io.IOException;
import java.util.List;

public class XmlMapperApp 

    public static void main(String[] args) throws Exception 
        File xmlFile = new File("./resource/test.xml").getAbsoluteFile();

        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.setConfig(xmlMapper.getDeserializationConfig().withHandler(new NullableItemsDeserializationProblemHandler()));
        System.out.println(xmlMapper.readValue(xmlFile, Pojo.class));
    


class NullableItemsDeserializationProblemHandler extends DeserializationProblemHandler 
    @Override
    public Object handleUnexpectedToken(DeserializationContext ctxt, Class<?> targetType, JsonToken t, JsonParser p, String failureMsg) throws IOException 
        if (targetType == Long.class && p.currentToken() == JsonToken.START_OBJECT) 
            boolean isNull = false;
            while (p.currentToken() != JsonToken.END_OBJECT) 
                p.nextToken();
                switch (p.currentToken()) 
                    case FIELD_NAME:
                        if ("nil".equals(p.getText())) 
                            isNull = true;
                        
                
            
            if (isNull) 
                return null;
            
        
        return super.handleUnexpectedToken(ctxt, targetType, t, p, failureMsg);
    

上面的代码打印:

Pojovalues=[10, null, 20]

另见:

Can't set ProblemHandler to ObjectMapper in Spring Boot

【讨论】:

以上是关于如何反序列化java Long哪个xml标签有xsi:nil?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 XML Choice 反序列化为正确的复杂类型

如何反序列化xml

xStream 问题 - 如何反序列化多个对象

XML反序列化处理具有默认值的空标签

出现错误:无法反序列化对象。无法将 java.lang.String 类型的值转换为 long

反序列化具有不同标签的 XML 相同项目