简体   繁体   中英

How do i define Gson java class for this json input

How do I define the tracks for Json for deserializing this json

"user": {
    "authority": "user",
    "title": "Renata Tebaldi Serenata Tebaldi [Disc 2]",
    "artist": "Renata Tebaldi",
    "tracks": {
        "1": "Track 01 - BELLINI: Vaga luna che inargenti",
        "2": "Track 02 - BELLINI: Per pieta bel ‘idol mio",
        "3": "Track 03 - MASCAGNI: M’ama ... Non m’ama",
        "4": "Track 04 - RESPIGHI: Notte",
        "5": "Track 05 - TOSTI: ‘A vuchella",
        "6": "Track 06 - DAVICO: O luna che fa lume",
        "7": "Track 07 - DONIZETTI: Me voglio fa ‘na casa",
        "8": "Track 08 - MASCAGNI: La tua Stella",
        "9": "Track 09 - TOSTI: Sogno",
        "10": "Track 10 -ROSSINI: L’invito",
        "11": "Track 11 - ZANDONAI: L’assiulo",
        "12": "Track 12 - CIMARA: Stormello",
        "13": "Track 13 - PONCHIELLI: Noi leggevamo insieme",
        "14": "Track 14 - MASCAGNI:  Serenato",
        "15": "Track 15 - PARISOTTI: Se tu m’ami",
        "16": "Track 16 - PARADISI: M’ha presa alla sua ragna",
        "17": "Track 17 - SCARLATTI: O cessati di piagarmi",
        "18": "Track 18 - GLUCK: O dell mio dolce ardor",
        "19": "Track 19 - RICCI: Il carrettiere del Vomero",
        "20": "Track 20 - MERCADANTE: La sposa del marinaro",
        "21": "Track 21 - BELLINI:  Malliconia, ninfa gemtile",
        "22": "Track 22 - PUCCINI: E l’luccelino"
    }
},

My definition of User is as follows

public class UnitiCoreUser
{
    private String authority;
    private String artist;
    private String title;


    public String getAuthority()
    {
        return authority;
    }

    public void setAuthority(String authority)
    {
        this.authority = authority;
    }

    public String getArtist()
    {
        return artist;
    }

    public void setArtist(String artist)
    {
        this.artist = artist;
    }

    public String getTitle()
    {
        return title;
    }

    public void setTitle(String title)
    {
        this.title = title;
    }
}

My problem is track because the elements within are not fixed by name, ie they are all the same but are labelled 1,2,3,4,... so can t just have an array of tracks.

eg Track[] tracks;

You have to use

Map<String,String> tracks

It will automatically be deserialized to map.

Try using a Map :

Map<Integer, String> tracks;

Here is an example (the class you showed along with the JSON you showed didn't quite match up either):

import com.google.gson.Gson;
import java.util.Map;

public class TestApp {

    public TestApp() {
        String test = "{\"user\":{\"authority\":\"user\",\"title\":\"Renata Tebaldi Serenata Tebaldi [Disc 2]\",\"artist\":\"Renata Tebaldi\",\"tracks\":{\"1\":\"Track 01 - BELLINI: Vaga luna che inargenti\",\"2\":\"Track 02 - BELLINI: Per pieta bel \u2018idol mio\",\"3\":\"Track 03 - MASCAGNI: M\u2019ama ... Non m\u2019ama\",\"4\":\"Track 04 - RESPIGHI: Notte\",\"5\":\"Track 05 - TOSTI: \u2018A vuchella\",\"6\":\"Track 06 - DAVICO: O luna che fa lume\",\"7\":\"Track 07 - DONIZETTI: Me voglio fa \u2018na casa\",\"8\":\"Track 08 - MASCAGNI: La tua Stella\",\"9\":\"Track 09 - TOSTI: Sogno\",\"10\":\"Track 10 -ROSSINI: L\u2019invito\",\"11\":\"Track 11 - ZANDONAI: L\u2019assiulo\",\"12\":\"Track 12 - CIMARA: Stormello\",\"13\":\"Track 13 - PONCHIELLI: Noi leggevamo insieme\",\"14\":\"Track 14 - MASCAGNI:  Serenato\",\"15\":\"Track 15 - PARISOTTI: Se tu m\u2019ami\",\"16\":\"Track 16 - PARADISI: M\u2019ha presa alla sua ragna\",\"17\":\"Track 17 - SCARLATTI: O cessati di piagarmi\",\"18\":\"Track 18 - GLUCK: O dell mio dolce ardor\",\"19\":\"Track 19 - RICCI: Il carrettiere del Vomero\",\"20\":\"Track 20 - MERCADANTE: La sposa del marinaro\",\"21\":\"Track 21 - BELLINI:  Malliconia, ninfa gemtile\",\"22\":\"Track 22 - PUCCINI: E l\u2019luccelino\"}}}";
        UnitiCoreUser user = new Gson().fromJson(test, UnitiCoreUser.class);
    }

    public static void main(String[] args) {
        new TestApp();
    }

    public class UnitiCoreUser {

        private User user;

        public User getUser() {
            return user;
        }
    }

    class User {

        public String authority;
        private String artist;
        private String title;
        Map<Integer, String> tracks;

        public String getAuthority() {
            return authority;
        }

        public void setAuthority(String authority) {
            this.authority = authority;
        }

        public String getArtist() {
            return artist;
        }

        public void setArtist(String artist) {
            this.artist = artist;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public Map<Integer, String> getTracks() {
            return tracks;
        }
    }
}

Gson has type adapters that can deal with some oddities. These type adapters can read/write JSON elements mapping them to/from classes, and make some additional checks (say, array-like map verification).

public final class SequentiveMapTypeAdapterFactory
        implements TypeAdapterFactory {

    private static final ConstructorConstructor constructorConstructor = new ConstructorConstructor(ImmutableMap.of(
            List.class, type -> new ArrayList<>()
    ));

    private SequentiveMapTypeAdapterFactory() {
    }

    @Override
    @Nullable
    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
        final Class<? super T> rawType = typeToken.getRawType();
        if ( !List.class.isAssignableFrom(rawType) ) {
            return null;
        }
        final Type type = typeToken.getType();
        final Type elementType = $Gson$Types.getCollectionElementType(type, rawType);
        @SuppressWarnings("unchecked")
        final TypeAdapter<T> typeAdapter = (TypeAdapter<T>) new SequentiveMapTypeAdapter<>(
                (ObjectConstructor<? extends List<Object>>) constructorConstructor.get(typeToken),
                (TypeAdapter<Object>) gson.getAdapter(TypeToken.get(elementType))
        );
        return typeAdapter.nullSafe();
    }

    private static final class SequentiveMapTypeAdapter<E>
            extends TypeAdapter<List<E>> {

        private final ObjectConstructor<? extends List<E>> objectConstructor;
        private final TypeAdapter<E> elementTypeAdapter;

        private SequentiveMapTypeAdapter(final ObjectConstructor<? extends List<E>> objectConstructor, final TypeAdapter<E> elementTypeAdapter) {
            this.objectConstructor = objectConstructor;
            this.elementTypeAdapter = elementTypeAdapter;
        }

        @Override
        public void write(final JsonWriter out, final List<E> list) {
            throw new UnsupportedOperationException();
        }

        @Override
        public List<E> read(final JsonReader in)
                throws IOException {
            in.beginObject();
            final List<E> list = objectConstructor.construct();
            for ( int i = 1; in.hasNext(); i++ ) {
                final String name = in.nextName();
                if ( !name.equals(String.valueOf(i)) ) {
                    throw new JsonParseException("Expected " + i + " but was name " + name);
                }
                final E element = elementTypeAdapter.read(in);
                list.add(element);
            }
            in.endObject();
            return list;
        }

    }

}

Then your mapping object should be aware of how to convert the JSON object to a list or an array by annotating the respective field:

final class UnitiCoreUser {

    String authority;
    String artist;
    String title;

    @JsonAdapter(SequentiveMapTypeAdapterFactory.class)
    List<String> tracks;

}

Then it will work:

final UnitiCoreUser unitiCoreUser = gson.fromJson(jsonReader, UnitiCoreUser.class);
for ( final String track : unitiCoreUser.tracks ) {
    System.out.println(track);
}

Output:

Track 01 - BELLINI: Vaga luna che inargenti
Track 02 - BELLINI: Per pieta bel ‘idol mio
Track 03 - MASCAGNI: M’ama ... Non m’ama
Track 04 - RESPIGHI: Notte
Track 05 - TOSTI: ‘A vuchella
Track 06 - DAVICO: O luna che fa lume
Track 07 - DONIZETTI: Me voglio fa ‘na casa
Track 08 - MASCAGNI: La tua Stella
Track 09 - TOSTI: Sogno
Track 10 -ROSSINI: L’invito
Track 11 - ZANDONAI: L’assiulo
Track 12 - CIMARA: Stormello
Track 13 - PONCHIELLI: Noi leggevamo insieme
Track 14 - MASCAGNI:  Serenato
Track 15 - PARISOTTI: Se tu m’ami
Track 16 - PARADISI: M’ha presa alla sua ragna
Track 17 - SCARLATTI: O cessati di piagarmi
Track 18 - GLUCK: O dell mio dolce ardor
Track 19 - RICCI: Il carrettiere del Vomero
Track 20 - MERCADANTE: La sposa del marinaro
Track 21 - BELLINI:  Malliconia, ninfa gemtile
Track 22 - PUCCINI: E l’luccelino

尝试使用属性 Map<String,String> 轨道

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM