如何使用 Moshi 将不同的对象属性反序列化为一个共同的 class?
How to deserialize different object properties into a common class with Moshi?
我开始编写 Java 库 Brockman to parse a JSON response similar to this example using Moshi。但是,格式需要对 stream
个对象进行一些概括。
视频流摘录:
{
"slug": "hd-native",
"display": "Saal 1 FullHD Video",
"type": "video",
"isTranslated": false,
"videoSize": [
1920,
1080
],
"urls": {
"webm": {
"display": "WebM",
"tech": "1920x1080, VP8+Vorbis in WebM, 2.8 MBit/s",
"url": "http://example.com/s1_native_hd.webm"
},
"hls": {
"display": "HLS",
"tech": "1920x1080, h264+AAC im MPEG-TS-Container via HTTP",
"url": "http://example.com/hls/s1_native_hd.m3u8"
}
}
}
音频流摘录:
{
"slug": "audio-native",
"display": "Saal 1 Audio",
"type": "audio",
"isTranslated": false,
"videoSize": null,
"urls": {
"mp3": {
"display": "MP3",
"tech": "MP3-Audio, 96 kBit/s",
"url": "http://example.com/s1_native.mp3"
},
"opus": {
"display": "Opus",
"tech": "Opus-Audio, 64 kBit/s",
"url": "http://example.com/s1_native.opus"
}
}
}
urls = {}
对象的内容根据 stream
type
是 video
还是 audio
而不同,如上例所示.
目前只有Mp3
and Opus
两个属性相同的模型。我想用 Format
class 代替它们,它也可以作为缺少的 Webm
和 Hls
class 的替代品。我怎样才能真正将 Urls
对象的不同字段映射到 Format
class?
public class Format {
public final String display;
public final String tech;
public final String url;
public Format(String display, String tech, String url) {
this.display = display;
this.tech = tech;
this.url = url;
}
}
我可以想象 Stream
class 看起来像这样:
public class Stream {
public final String display;
public final boolean isTranslated;
public final String slug;
public final String type;
public final VideoSize videoSize;
public final List<Format> urls; // How to map into List<Format>?
// ...
我得出以下结论:
public class StreamAdapter {
@ToJson
public String toJson(Stream stream) throws Exception {
throw new UnsupportedOperationException("Not yet implemented.");
}
@FromJson
public Stream fromJson(StreamJson streamJson) throws Exception {
String slug = streamJson.slug;
String display = streamJson.display;
boolean isTranslated = streamJson.isTranslated;
Stream.TYPE type = streamJson.type;
VideoSize videoSize = streamJson.videoSize;
Map<String, Object> urlsJson = streamJson.urls;
List<Url> urls = getUrls(urlsJson);
return new Stream(display, isTranslated, slug, type, videoSize, urls);
}
private List<Url> getUrls(Map<String, Object> urlsJson) {
Set<String> urlTypes = urlsJson.keySet();
List<Url> urls = new ArrayList<Url>(urlTypes.size());
for (String urlType : urlTypes) {
@SuppressWarnings("unchecked")
Map<String, String> urlProperties = (Map<String, String>) urlsJson.get(urlType);
urls.add(getUrl(urlType, urlProperties));
}
return urls;
}
private Url getUrl(String urlType, Map<String, String> properties) {
Url.TYPE type = new UrlTypeAdapter().fromJson(urlType);
String display = properties.get("display");
String tech = properties.get("tech");
String url = properties.get("url");
return new Url(type, display, tech, url);
}
private static final class StreamJson {
String slug;
String display;
boolean isTranslated;
Stream.TYPE type;
VideoSize videoSize;
Map<String, Object> urls;
}
}
请注意,我现在使用 Url
class 而不是问题中提到的 Format
class。请查找更多详细信息 here。如果您有关于如何改进这一点的想法,欢迎您在此处发表评论或在存储库上创建一个issue/pull请求。
我开始编写 Java 库 Brockman to parse a JSON response similar to this example using Moshi。但是,格式需要对 stream
个对象进行一些概括。
视频流摘录:
{
"slug": "hd-native",
"display": "Saal 1 FullHD Video",
"type": "video",
"isTranslated": false,
"videoSize": [
1920,
1080
],
"urls": {
"webm": {
"display": "WebM",
"tech": "1920x1080, VP8+Vorbis in WebM, 2.8 MBit/s",
"url": "http://example.com/s1_native_hd.webm"
},
"hls": {
"display": "HLS",
"tech": "1920x1080, h264+AAC im MPEG-TS-Container via HTTP",
"url": "http://example.com/hls/s1_native_hd.m3u8"
}
}
}
音频流摘录:
{
"slug": "audio-native",
"display": "Saal 1 Audio",
"type": "audio",
"isTranslated": false,
"videoSize": null,
"urls": {
"mp3": {
"display": "MP3",
"tech": "MP3-Audio, 96 kBit/s",
"url": "http://example.com/s1_native.mp3"
},
"opus": {
"display": "Opus",
"tech": "Opus-Audio, 64 kBit/s",
"url": "http://example.com/s1_native.opus"
}
}
}
urls = {}
对象的内容根据 stream
type
是 video
还是 audio
而不同,如上例所示.
目前只有Mp3
and Opus
两个属性相同的模型。我想用 Format
class 代替它们,它也可以作为缺少的 Webm
和 Hls
class 的替代品。我怎样才能真正将 Urls
对象的不同字段映射到 Format
class?
public class Format {
public final String display;
public final String tech;
public final String url;
public Format(String display, String tech, String url) {
this.display = display;
this.tech = tech;
this.url = url;
}
}
我可以想象 Stream
class 看起来像这样:
public class Stream {
public final String display;
public final boolean isTranslated;
public final String slug;
public final String type;
public final VideoSize videoSize;
public final List<Format> urls; // How to map into List<Format>?
// ...
我得出以下结论:
public class StreamAdapter {
@ToJson
public String toJson(Stream stream) throws Exception {
throw new UnsupportedOperationException("Not yet implemented.");
}
@FromJson
public Stream fromJson(StreamJson streamJson) throws Exception {
String slug = streamJson.slug;
String display = streamJson.display;
boolean isTranslated = streamJson.isTranslated;
Stream.TYPE type = streamJson.type;
VideoSize videoSize = streamJson.videoSize;
Map<String, Object> urlsJson = streamJson.urls;
List<Url> urls = getUrls(urlsJson);
return new Stream(display, isTranslated, slug, type, videoSize, urls);
}
private List<Url> getUrls(Map<String, Object> urlsJson) {
Set<String> urlTypes = urlsJson.keySet();
List<Url> urls = new ArrayList<Url>(urlTypes.size());
for (String urlType : urlTypes) {
@SuppressWarnings("unchecked")
Map<String, String> urlProperties = (Map<String, String>) urlsJson.get(urlType);
urls.add(getUrl(urlType, urlProperties));
}
return urls;
}
private Url getUrl(String urlType, Map<String, String> properties) {
Url.TYPE type = new UrlTypeAdapter().fromJson(urlType);
String display = properties.get("display");
String tech = properties.get("tech");
String url = properties.get("url");
return new Url(type, display, tech, url);
}
private static final class StreamJson {
String slug;
String display;
boolean isTranslated;
Stream.TYPE type;
VideoSize videoSize;
Map<String, Object> urls;
}
}
请注意,我现在使用 Url
class 而不是问题中提到的 Format
class。请查找更多详细信息 here。如果您有关于如何改进这一点的想法,欢迎您在此处发表评论或在存储库上创建一个issue/pull请求。