使用RestAssured、JAXB和Groovy解析iTunes RSS时的itunes前缀元素反序列化问题求助
解决JAXB + RestAssured解析带itunes命名空间RSS的问题
我之前处理Podcast RSS的时候也踩过这个JAXB命名空间的坑!问题出在你只指定了元素的前缀(比如itunes:category),但JAXB需要明确知道前缀对应的命名空间URI才能正确匹配XML里的元素。XML里的xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"才是关键,前缀只是个别名而已。
下面是具体的修复步骤:
1. 给itunes元素添加命名空间注解
修改你的Channel类,给所有带itunes前缀的元素加上namespace属性,值就是RSS里定义的itunes命名空间URI:http://www.itunes.com/dtds/podcast-1.0.dtd。
2. 单独处理itunes:image元素
注意到你的RSS里有<itunes:image href="..."/>,这是一个带属性的元素,不能直接用@XmlAttribute在Channel类里映射,需要单独创建一个类来对应它。
修改后的模型代码
@XmlRootElement(name = "rss") @XmlAccessorType(XmlAccessType.NONE) class Rss { @XmlElement(name = "channel") public Channel channel } @XmlAccessorType(XmlAccessType.NONE) class Channel { @XmlElement public String title @XmlElement public String description @XmlElement(name = "language") public String language // 处理itunes:image元素 @XmlElement(name = "image", namespace = "http://www.itunes.com/dtds/podcast-1.0.dtd") public ItunesImage itunesImage // 给itunes元素指定命名空间 @XmlElement(name = "category", namespace = "http://www.itunes.com/dtds/podcast-1.0.dtd") public String category @XmlElement(name = "explicit", namespace = "http://www.itunes.com/dtds/podcast-1.0.dtd") public Boolean explicit @XmlElement(name = "author", namespace = "http://www.itunes.com/dtds/podcast-1.0.dtd") public String author // ... } // 对应itunes:image的类 @XmlAccessorType(XmlAccessType.NONE) class ItunesImage { @XmlAttribute(name = "href") public String href }
3. 验证测试代码
你的RestAssured测试代码不需要大改,只要模型正确,JAXB就能正常反序列化了:
when: Response response = RestAssured.given() .baseUri("...") .contentType("application/rss+xml") .when() .get("...") then: def rss = response.then() .statusCode(200) .extract() .as(Rss.class, ObjectMapperType.JAXB) // 可以验证一下itunes字段是否正确解析 assert rss.channel.itunesImage.href != null assert rss.channel.category == "Foo" assert rss.channel.explicit == true
为什么之前会失败?
XML里的带命名空间的元素,实际的“全名”是{http://www.itunes.com/dtds/podcast-1.0.dtd}category,而不是itunes:category——itunes只是这个命名空间的简写前缀。JAXB默认只会匹配没有命名空间的元素,所以必须明确指定每个itunes元素对应的命名空间URI,才能让它正确识别并反序列化。
内容的提问来源于stack exchange,提问作者pixel
相关产品推荐
相关产品推荐

