如何使用Moshi将不同的对象属性反序列化为一个公共类?

时间:2015-12-02 17:20:35

标签: java json json-deserialization moshi

我开始编写Java库Brockman以使用this example解析类似于Moshi的JSON响应。但是,格式需要对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 typevideo还是audio,这可以从上面的示例中看到。< / p>

目前,只有模型Mp3Opus的属性相同。我想用Format类替换它们,这类也可以替代丢失的WebmHls类。如何将Urls对象的不同字段实际映射到Format类?

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>?

// ...

1 个答案:

答案 0 :(得分:1)

我想出了以下内容:

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课程,而不是问题中提到的Format课程。请查看更多详情here。如果您对如何改进这一点有任何想法,欢迎您在存储库中发表评论创建问题/拉取请求