当前位置: 首页 > 知识库问答 >
问题:

Apache camel xml反序列化失败

龙俭
2023-03-14

我正在尝试使用apache camel jackson xml对xml进行反序列化,然后发生了一些奇怪的事情,我无法解释。这是我正在尝试反序列化的xml(它是简单的xmltd v xml文件):

<?xml version="1.0" encoding="UTF-8"?>
<tv>
  <programme start="20210102000300 +0000" stop="20210102003000 +0000" channel="XTV100005403" recordable="Y" npvrenable="Y" id="SH032096260000.20210102000300.44345" type="program">
     <title lang="en">Barbados Ninja Throwdown</title>
     <desc lang="en">Contestants compete to complete a challenging obstacle course the fastest.</desc>
     <credits>
        <actor nameId="1288485">Wayne Simmons</actor>
     </credits>
     <date>20190427</date>
     <category>Reality</category>
     <category>Action sports</category>
     <category>Action</category>
     <category>Adventure</category>
     <releaseType>TV</releaseType>
     <extentionInfo>
        <key>releaseStatus</key>
        <value>1</value>
     </extentionInfo>
  </programme>
</tv>

这是我的POJO:

电视。Java语言

@XmlRootElement(name = "tv")
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class Tv {

  @XmlElement(name = "programme")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<Programme> programmes = new ArrayList<>();

}

程序Java语言

@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class Programme {

  @XmlAttribute(name = "id")
  @XmlJavaTypeAdapter(NormalizedStringAdapter.class)
  private String id;

  @XmlAttribute(name = "type")
  @XmlJavaTypeAdapter(NormalizedStringAdapter.class)
  private String type;

  @XmlAttribute(name = "start", required = true)
  @JsonDeserialize(using = OffsetDateTimeDeserializer.class)
  private OffsetDateTime start;

  @XmlAttribute(name = "stop")
  @JsonDeserialize(using = OffsetDateTimeDeserializer.class)
  private OffsetDateTime stop;

  @XmlAttribute(name = "pdc-start")
  @JsonDeserialize(using = OffsetDateTimeDeserializer.class)
  private OffsetDateTime pdcStart;

  @XmlAttribute(name = "vps-start")
  @JsonDeserialize(using = OffsetDateTimeDeserializer.class)
  private OffsetDateTime vpsStart;

  @XmlAttribute(name = "showview")
  @XmlJavaTypeAdapter(NormalizedStringAdapter.class)
  private String showview;

  @XmlAttribute(name = "videoplus")
  @XmlJavaTypeAdapter(NormalizedStringAdapter.class)
  private String videoplus;

  @XmlAttribute(name = "channel", required = true)
  @XmlJavaTypeAdapter(NormalizedStringAdapter.class)
  private String channel;

  @XmlAttribute(name = "clumpidx")
  @XmlJavaTypeAdapter(NormalizedStringAdapter.class)
  private String clumpidx;

  @XmlElement(name = "title", required = true)
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<Label> titles;

  @XmlElement(name = "sub-title")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<Label> subTitle;

  @XmlElement(name = "desc")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<Label> descriptions;

  @XmlElement(name = "credits")
  private Credits credits;

  private String date;

  @XmlElement(name = "category")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<Label> categories;

  @XmlElement(name = "keyword")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<Label> keywords;

  private Label language;

  @XmlElement(name = "orig-language")
  private Label origLanguage;

  private Length length;

  @XmlElement(name="icons")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<Icon> icons;

  @XmlElement(name = "url")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<String> urls;

  @XmlElement(name = "country")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<Label> countries;

  @XmlElement(name = "episode-num")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<EpisodeNum> episodeNumbers;

  private Video video;

  private Audio audio;

  @XmlElement(name = "previously-shown")
  private PreviouslyShown previouslyShown;

  private Label premiere;

  @XmlElement(name = "last-chance")
  private Label lastChance;

  @XmlElement(name = "new")
  private Label isNew;

  @JacksonXmlElementWrapper(useWrapping = false)
  private List<Subtitles> subtitles;

  @XmlElement(name = "rating")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<Rating> ratings;

  @XmlElement(name = "star-rating")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<StarRating> starRatings;

  @XmlElement(name = "review")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<Review> reviews;
  
}

Credits.java

@Data
public class Credits {
  @XmlElement(name = "director")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<String> directors;

  @XmlElement(name = "actor")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<String> actors;

  @XmlElement(name = "writer")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<String> writers;

  @XmlElement(name = "adapter")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<String> adapters;

  @XmlElement(name = "producer")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<String> producers;

  @XmlElement(name = "composer")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<String> composers;

  @XmlElement(name = "editor")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<String> editors;

  @XmlElement(name = "presenter")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<String> presenters;

  @XmlElement(name = "commentator")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<String> commentators;

  @XmlElement(name = "guest")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<String> guests;
}

其他POJO并不重要。下面是路由配置:

@Override
  public void configure() throws Exception {
    final JacksonXMLDataFormat dataFormat = new JacksonXMLDataFormat();
    dataFormat.setUnmarshalType(Tv.class);

    from("file:///someLocation")
        .routeId(getClass().getSimpleName())
        .autoStartup(true)
        .unmarshal(dataFormat)
        .process("someProcessorBean")

  }

使用此设置和我在开始时提供的xml,会发生以下异常:

通用域名格式。fasterxml。杰克逊。数据绑定。exc.MismatchedInputException:无法构造程序的实例(尽管至少存在一个创建者):在[源:(BufferedInputStream);行:9,列:20](通过引用链:com.azdio.mdw.ingest.epg.xmltv.common.domain.Tv[“Program”]处,没有可从字符串值('20190427')反序列化的字符串参数构造函数/工厂方法-

我花了很多时间才明白这意味着什么。因此,它似乎接受结束标记作为标记的结束,然后它尝试用标记值创建一个新的程序实例,但失败了,因为它不知道如何做。为了证明我自己,我将标记移到了标记的末尾,因此xml如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<tv>
  <programme start="20210102000300 +0000" stop="20210102003000 +0000" channel="XTV100005403" recordable="Y" npvrenable="Y" id="SH032096260000.20210102000300.44345" type="program">
     <title lang="en">Barbados Ninja Throwdown</title>
     <desc lang="en">Contestants compete to complete a challenging obstacle course the fastest.</desc>
     <date>20190427</date>
     <category>Reality</category>
     <category>Action sports</category>
     <category>Action</category>
     <category>Adventure</category>
     <releaseType>TV</releaseType>
     <extentionInfo>
        <key>releaseStatus</key>
        <value>1</value>
     </extentionInfo>
     <credits>
        <actor nameId="1288485">Wayne Simmons</actor>
     </credits>
  </programme>
</tv>

这次当我运行应用程序时,xml被正确地反序列化,没有任何异常。有人能解释一下为什么会这样,我在什么地方犯了错吗?

我使用的是apache camel 2.25.3和camel-jacksonxml的相同版本。

编辑:

我成功地向jackson指出了这个问题:

 JacksonXmlModule jacksonXmlModule = new JacksonXmlModule();
 jacksonXmlModule.setDefaultUseWrapper(false);
 ObjectMapper objectMapper = new XmlMapper(jacksonXmlModule);
 objectMapper.registerModule(new JaxbAnnotationModule());
 objectMapper.readValue(new File("xmlFilePath"), Tv.class);

这导致了同样的例外。

共有1个答案

丌官承
2023-03-14

所以我找到了导致这个异常的原因,尽管我不完全确定为什么会这样。在对jackson的对象映射器进行调试之后,我发现问题出在actor标记的nameId属性中。当我有以下情况时,反序列化程序似乎无法决定如何执行:

  @XmlElement(name = "actor")
  @JacksonXmlElementWrapper(useWrapping = false)
  private List<String> actors;

所以我发现的一个解决方案(我不确定这是最正确的)是创建另一个pojo CreditsElement.java:

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class CreditsElement {

  @XmlValue
  private String value;
}

我不包括nameId属性,因为我不需要它。除了这个解决方案之外,还有没有更好的方法来映射它,而无需创建另一个类并使用List属性?

 类似资料:
  • 问题内容: 我正在使用Newtonsoft.Json将Web服务的输出反序列化到对象。在我向我的课程(名为)添加一个属性以保存化身之前,它一直运行良好。 Web服务正按预期返回该属性作为Base64字符串。问题是当我尝试将JSON从WS转换回a时,在此代码块中引发了a : 异常的输出是: 并查看内部异常: 显然,它无法解析Base64字符串,但不清楚原因。 有任何想法/解决方法吗? 编辑 我知道我

  • 我正在尝试使用kryo序列化和反序列化到二进制。我想我已经完成了序列化,但似乎无法反序列化。下面是我正在处理的代码,但最终我想存储一个字节[],然后再次读取它。文档只显示了如何使用文件。

  • 问题内容: 我尝试过在Java和Android之间实现跨平台序列化。我使用了Serializable,并将我的代码在Android中与台式机Java放在同一软件包中。 来源:java-desktop序列化 资料来源:Android-反序列化 学生是一类,实现了Serializable。在桌面上,我将学生实例序列化为“ thestudent.dat”。我将此文件放在Android设备上的SD卡上,并

  • 问题内容: 我注意到存储在Redis中的某些序列化对象在反序列化方面遇到问题。 当我对Redis中存储的对象类进行更改时,通常会发生这种情况。 我想了解问题,以便为解决方案设计一个清晰的方案。 我的问题是,什么导致反序列化问题?移除公共/私人财产会引起问题吗?也许添加新属性?向类添加新功能会产生问题吗?那么更多的构造函数呢? 在我的序列化对象中,我有一个属性Map,如果我更改(更新了一些属性,添加

  • 问题内容: Golang中将结构序列化和反序列化为字符串的最佳方法(完整性和性能)是什么,反之亦然? 例如,如果我有这个结构: 我想将其存储在Redis上并取回。我试过保存,整型和字符串,这很好,但是如何存储结构对象? 问题答案: 使用gob和base64可以解决问题,例如: 当您需要序列化自定义结构或类型(例如struct)时,只需添加以下行:

  • 主要内容:1 Java序列化和反序列化,2 Java序列化的优点,3 java.io.Serializable接口,4 Java ObjectOutputStream,5 Java ObjectInputStream,6 Java序列化的例子,7 Java反序列化的例子1 Java序列化和反序列化 Java中的序列化是一种将对象状态写入字节流的机制。它主要用于Hibernate,RMI,JPA,EJB和JMS技术。 序列化的反向操作称为反序列化,其中字节流被转换为对象。序列化和反序列化过程与平台