遇到换行符时,无法反序列化标签中的空白内容

问题描述

具有以下2个课程:

@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnkNown = true)
public class Structure {
    @JacksonXmlProperty
    private Info info;


@Data
@JsonIgnoreProperties(ignoreUnkNown = true)
@NoArgsConstructor
@AllArgsConstructor
public class Info{
    private Subinfo subinfo;
}

进行反序列化,例如:

 private static final XmlMapper XML_MAPPER = new XmlMapper();
 Structure structure = XML_MAPPER.readValue(input,Structure.class);

其中input是我的XML(请参见下文)

获得例外:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.test.models.Info` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('

    ')

Jackson的这项功能没有帮助:

XML_MAPPER.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

失败的我的XML:

<?xml version='1.0' encoding='UTF-8' ?>
  <Structure>
    <Info>

    </Info>
  </Structure>

此XML反序列化工作正常:

<?xml version='1.0' encoding='UTF-8' ?>
  <Structure>
    <Info/>
  </Structure>

问题在于标签关闭方法<Info/><Info></Info>

<Info/>正常运行 而

<Info>

 </Info>

当出现行终止符时会导致异常

解决方法

正如其他人在评论中已经提到的那样,DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT仅将空字符串转换为null,但是在Info元素中有空格和行分隔符。

其他人无法重现您的问题,因为您可能错过了自己在代码中也使用XML_MAPPER.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES,true)或示例XML中的 Info 的情况,因此XML实际上应该是 info ,否则该元素将被忽略。

要处理空字符串和仅包含空格和/或行分隔符的字符串,可以在解析XML之前添加以下代码:

XML_MAPPER.addHandler(new DeserializationProblemHandler() {
    
    @Override
    public Object handleMissingInstantiator(DeserializationContext ctxt,Class<?> instClass,ValueInstantiator valueInsta,JsonParser p,String msg) throws IOException {
    
      String value = p.getValueAsString();
    
      // ignore "empty" Info elements
      if (instClass.isAssignableFrom(Info.class) && (value.isEmpty() || value.matches("[\n\s]+"))) {
        return null;
      }
      return super.handleMissingInstantiator(ctxt,instClass,valueInsta,p,msg);
    }
   
});

如果您想对所有元素执行此操作,则只需忽略instClass