有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Jackson反序列化Xml元素,将换行符作为Java POJO的值

我正在尝试使用Jackson 2.11.2将我无法控制的XML文件反序列化到Java POJO。我的XML的一部分可能如下所示:

<ComplexTypeA>
    <ComplexTypeB>
        </PrimitiveType>
    </ComplexTypeB>
<ComplexTypeA>

可以使用Jackson将XML成功反序列化为Java POJO,其模型如下所示:

@JsonNaming(PropertyNamingStrategy.UpperCamelCaseStrategy.class)
public class ComplexTypeA {

    private ComplexTypeB complexTypeB;

    // constructor, getter and setter ommitted
}

@JsonNaming(PropertyNamingStrategy.UpperCamelCaseStrategy.class)
public class ComplexTypeB {

    private String primitiveType;

    // constructor, getter and setter ommitted
}

但是,如果XML对于可选的ComplexTypeB具有如下结构,则解析将失败:

<ComplexTypeA>
    <!-- fails -->
    <ComplexTypeB>
    </ComplexTypeB>
<ComplexTypeA>

<ComplexTypeA>
    <!-- succeeds -->
    <ComplexTypeB></ComplexTypeB>
<ComplexTypeA>

错误如下:

cannot construct instance of `ComplexTypeB` (although at least one Creator exists): 
no String-argument constructor/factory method to deserialize from String value ('
    ')

错误在于解析器试图解析分隔ComplexTypeB元素的开始标记和结束标记的换行符。因为我无法控制XML的格式,所以我希望将非基本类型的换行符视为空的和不存在的。如何扩展Jacksons功能以处理此情况


共 (1) 个答案

  1. # 1 楼答案

    我在修改了给定的答案后找到了答案

    此反序列化程序将忽略任何用字符串修剪的字符。将Xml反序列化为Java bean时使用trim()

    public class XmlEmptyElementWithWhitespacesModule extends SimpleModule{
    
        private static class CustomizedBeanDeserialiser extends BeanDeserializer {
    
            private static final long serialVersionUID = 1L;
    
            protected CustomizedBeanDeserialiser(BeanDeserializerBase src) {
                super(src);
            }
    
            @Override
            public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
                if (JsonToken.VALUE_STRING.equals(p.currentToken())) {
                    String textValue = p.getText();
                    if (textValue != null && textValue.trim().isBlank()) {
                        return null;
                    }
                }
    
                return super.deserialize(p, ctxt);
            }
        }
    
        private static final long serialVersionUID = 1L;
    
        @Override
        public void setupModule(SetupContext context) {
            super.setupModule(context);
            context.addBeanDeserializerModifier(new BeanDeserializerModifier() {
                @Override
                public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc,
                        JsonDeserializer<?> deserializer) {
                    if (deserializer instanceof BeanDeserializer) {
                        return new CustomizedBeanDeserialiser((BeanDeserializer) deserializer);
                    }
                    return super.modifyDeserializer(config, beanDesc, deserializer);
                }
            });
        }
    }
    

    可以通过以下方式将其添加到现有的Jackson解析器:

    XmlMapper mapper=新的XmlMapper(); 制图员。registerModule(新的XMLEmptyElementTwithWhiteSpacesModule())

    同样,这是对上面链接的代码的非常接近的改编