我正在编写一个RESTeasy代理客户端,以使用Apple的API来检索其iTunes类别列表。当您查询有关给定类别的信息时,例如使用此 URL:
https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/genres?id=1420
…您得到的JSON响应如下:
{
"1420":{
"name":"Self-Help",
"id":"1420",
"url":"https://itunes.apple.com/us/genre/podcasts-health-self-help/id1420?mt=2",
"rssUrls":{
"topVideoPodcastEpisodes":"https://itunes.apple.com/us/rss/topvideopodcastepisodes/genre=1420/json",
"topAudioPodcasts":"https://itunes.apple.com/us/rss/topaudiopodcasts/genre=1420/json",
"topVideoPodcasts":"https://itunes.apple.com/us/rss/topvideopodcasts/genre=1420/json",
"topPodcasts":"https://itunes.apple.com/us/rss/toppodcasts/genre=1420/json",
"topAudioPodcastEpisodes":"https://itunes.apple.com/us/rss/topaudiopodcastepisodes/genre=1420/json",
"topPodcastEpisodes":"https://itunes.apple.com/us/rss/toppodcastepisodes/genre=1420/json"
},
"chartUrls":{
"videoPodcastEpisodes":"https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/charts?cc=us&g=1420&name=VideoPodcastEpisodes",
"podcasts":"https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/charts?cc=us&g=1420&name=Podcasts",
"audioPodcastEpisodes":"https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/charts?cc=us&g=1420&name=AudioPodcastEpisodes",
"audioPodcasts":"https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/charts?cc=us&g=1420&name=AudioPodcasts",
"podcastEpisodes":"https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/charts?cc=us&g=1420&name=PodcastEpisodes",
"videoPodcasts":"https://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/charts?cc=us&g=1420&name=VideoPodcasts"
}
}
}
我试图使用JAXB和Jackson将这个JSON响应映射到一个Java对象。然而,“1420”根元素名称似乎引起了一个问题,因为我在调用我的客户端时得到了以下异常:
Unrecognized field "1420" (class foo.bar.ITunesCategoryList), not marked as ignorable
我的JAXB类如下所示:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ITunesCategory implements TransferObject {
private static final long serialVersionUID = 3443545925023804457L;
@XmlElement(name = "id")
@JsonProperty("id")
private String identifier = null;
@XmlElement
private String name = null;
@XmlElementWrapper(name = "subgenres")
private List<ITunesCategory> subcategories = new ArrayList<ITunesCategory>();
...
}
我甚至尝试过创建一个包装类,因为搜索可能导致返回多个类别。它看起来像这样:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ITunesCategoryList implements TransferObject {
private static final long serialVersionUID = 3303125979016445238L;
@XmlElement
private List<ITunesCategory> categories = new ArrayList<ITunesCategory>();
...
}
然而,无论我将哪个类指定为我的返回类型,我都会得到相同的错误,因为类别标识符是JSON对象的根元素名。
有没有办法告诉JAXB/Jackson/JAX-RS/RESTeasy忽略根元素名,只把底层对象映射到Java?我没有办法在开发/编译时知道根元素的名称,因为它直接对应于搜索返回的结果。有什么办法可以解决这个html" target="_blank">异常吗?感谢你能给予的任何帮助!
我找不到太多关于动态忽略根的东西,至少没有任何适合JAX-RS环境的东西。我唯一能想到的是写一个自定义的反序列化器,跳过根节点。大约
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.Map;
public abstract class IHateRootElemsJsonDeserializer<T> extends JsonDeserializer<T> {
private final ObjectMapper mapper = new ObjectMapper();
private final Class<T> cls;
public IHateRootElemsJsonDeserializer(Class<T> cls) {
this.cls = cls;
}
@Override
public T deserialize(JsonParser jp, DeserializationContext dc)
throws IOException, JsonProcessingException {
JsonNode rootNode = jp.getCodec().readTree(jp);
Map.Entry<String,JsonNode> field = rootNode.fields().next();
JsonNode node = field.getValue();
T result = mapper.convertValue(node, cls);
return result;
}
}
然后用具体的类型扩展它。
public class GenreDeserializer extends IHateRootElemsJsonDeserializer<Genre>{
public GenreDeserializer() {
super(Genre.class);
}
}
这是一个使用您上面提供的确切JSON的测试
public class Test {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
GenreDeserializer deserializer = new GenreDeserializer();
SimpleModule module = new SimpleModule();
module.addDeserializer(Genre.class, deserializer);
mapper.registerModule(module);
Genre genre = mapper.readValue(JSON_FILE, Genre.class);
System.out.println(genre);
genre = mapper.readValue(JSON_FILE, Genre.class);
System.out.println(genre);
}
static final File JSON_FILE = new File("json.json");
}
模型
public class Genre {
public String id;
public String name;
public String url;
public RssUrls rssUrls;
public ChartUrls chartUrls;
@Override
public String toString() {
return "Category{" + "id=" + id + ", name="
+ name + ", url=" + url + ", rssUrls=" + rssUrls + '}';
}
public static class RssUrls {
public String topVideoPodcastEpisodes;
public String topAudioPodcasts;
public String topVideoPodcasts;
public String topPodcasts;
public String topAudioPodcastEpisodes;
public String topPodcastEpisodes;
@Override
public String toString() {
return "RssUrls{" + "topVideoPodcastEpisodes=" + topVideoPodcastEpisodes
+ ", topAudioPodcasts=" + topAudioPodcasts
+ ", topVideoPodcasts=" + topVideoPodcasts
+ ", topPodcasts=" + topPodcasts
+ ", topAudioPodcastEpisodes=" + topAudioPodcastEpisodes
+ ", topPodcastEpisodes=" + topPodcastEpisodes + '}';
}
}
public static class ChartUrls {
public String videoPodcastEpisodes;
public String podcasts;
public String audioPodcastEpisodes;
public String audioPodcasts;
public String podcastEpisodes;
public String videoPodcasts;
@Override
public String toString() {
return "ChatUrls{" + "videoPodcastEpisodes=" + videoPodcastEpisodes
+ ", podcasts=" + podcasts
+ ", audioPodcastEpisodes=" + audioPodcastEpisodes
+ ", audioPodcasts=" + audioPodcasts
+ ", podcastEpisodes=" + podcastEpisodes
+ ", videoPodcasts=" + videoPodcasts + '}';
}
}
}
要在JAX-RS中配置< code>ObjectMapper,您可以看看这篇文章
开发JAX-RS应用程序并解决问题。需要从我的资源中自定义json输出以使用Jackson(2.22.2)解析器而不是默认Moxy(根据此答案)。 这是pom。xml片段 我还配置web.xml文件默认使用Jackson 但是资源输出与我使用注释和序列化器配置的有所不同。这是表示为json的模型 和序列化程序 } 这是资源片段 响应json根本不是定制的。 期望的输出是 谢谢。
问题内容: 我有一个像这样的JSON字符串: 现在,我将使用 Jackson 2.0进行 解析。我正在尝试从JSON字符串获取a 。 可能吗? 问题答案: 您的媒体资源看起来不像数组。它代表具有动态属性的对象,因此我们应将其视为对象。如果我们对属性一无所知,可以使用注释。算法可能如下所示: 将JSON反序列化为JSON模型类。 使用ObjectMapper将动态对象(地图)转换为应用的POJO类
问题内容: 我有一个这样的模型: 例如,我从远程获取以下JSON: 当我反序列化此JSON时,and 变量将获得正确的值。但是我不想解释我变量的内容。相反,我希望它是以下字符串: 之后,我将自己解释。我如何获得的价值? 问题答案: Jackson问题596是为原始问题中描述的所需功能而创建的。如果要实施它,请投票。 当前可用的解决方案是实现自定义反序列化处理。 另外,如何使用Jackson将原始J
问题内容: 我有一个像这样的JSON字符串: 现在,我将使用 Jackson 2.0进行 解析。我正在尝试从JSON字符串获取a 。 可能吗? 问题答案: 您的媒体资源看起来不像数组。它代表具有动态属性的对象,因此我们应将其视为对象。如果我们对属性一无所知,可以使用注释。算法可能如下所示: 将JSON反序列化为JSON模型类。 使用ObjectMapper将动态对象(地图)转换为应用的POJO类
我在Java创建了一个REST网络服务。我使用Joda-time作为日期,使用Jackson作为JSON格式。所有内容都上传到Glassfish 4.1服务器上。 avax.ws.rs-api-2.0.1.jar joda-time-2.7.jar jackson-annotation-2.8.8.jar jackson-core-2.8.8.jar jackson-databind-2.8.8.
问题内容: 我有一个JSON字符串,将标记为而不是。因此,例如,如果我有一个没有子对象的对象,我将收到类似以下的字符串: 我想将其反序列化为Parent类,并将子级正确设置为一个空的子级列表。 对于上述JSON字符串,我想要一个对象,其设置为,而设置为。 我会知道如何在整个课堂上使用注释 然后 但是,我想解决一个从字符串正确实例化List的一般问题: 我能得到类似的东西吗? 问题答案: 几个选择;