GSON generyfikacja metody parsowania

0

Hej, chciałem sobie napisać parsera do obiektów JSON na androida, w tym celu uzywam biblioteki GSON do tworzenia obiektów JSON i napisałem prostą metodę parsującą

 public List<ObiektJSON> parseGitHub(InputStream stream) {
        Gson gson = new Gson();
        Type collectionType = new TypeToken<List<ObiektJSON>>() {
        }.getType();
        Reader jsonReader = new InputStreamReader(stream);
        return gson.fromJson(jsonReader, collectionType);
    }

Problem w tym że obiektów JSON mam dużo (np ObiektJSON1 , ObiektJSON2 itd) i funkcja do nich wszystkich wygląda identycznie , różni się jedynie typem zwracanej listy, czyli sobie umyśliłem że upakuję to w generyka i będzie gitara

 
public abstract class GSONparser<T> {



    public List<T> parseGitHub(InputStream stream) {
        Gson gson = new Gson();
        Type collectionType = new TypeToken<List<T>>() {
        }.getType();
        Reader jsonReader = new InputStreamReader(stream);
        return gson.fromJson(jsonReader, collectionType);
    }

}

no niestety wszystko dziedziczące po GSONparser zwraca obiekty typu Object a nie typu jaki mu zapodam. Chyba jednak nie do końca kumam generyki. Ktoś może mi podpowiedzieć jak to zrobić poprawnie ? :)

z góry dzięki

1

Pobierasz te dane z internetu? Jeżeli tak to może lepiej skorzystać z biblioteki pokroju http://square.github.io/retrofit/ ?
Wtedy masz z głowy ręczną konwersję, jest ona wykonywana przez bibliotekę. Do parsowania polecam Jacksona, jest on trochę bardziej inteligentny, radzi sobie tam, gdzie Gson wysiada. Jest również bardziej wydajny na androidzie.

Jeżeli jednak chcesz to robić tak jak pokazałeś, to najprościej będzie użyć https://docs.oracle.com/javase/tutorial/extra/generics/methods.html


public interface Model { // niech każdy obiekt modelu implementuje ten interfejs
}

static ObjectMapper objectMapper = new ObjectMapper(); 
public static <T extends Model> List<T> parseJson(String json,Class clazz) {
    retrurn objectMapper.readValue(json, clazz);
}
0

Dzięki za pomoc :) porozglądam się zatem za innymi bibliotekami a póki co sięknę sobie przez extendsa.

Czym u Ciebie jest static ObjectMapper, czym jest string json i najważniejsze, jak mam wywołać tą metodę :D

1

Dalej nie wiem, czy pobierasz te jsony z internetu czy lokalnie z pamięci. Jeżeli z internetu to użyj biblioteki retrofit (mogę pomóc z konfiguracją).
Jeżeli lokalnie pobierasz te jsony to taka metoda zwróci Ci listę obiektów bez rzutowania:

    public interface Model {
    }

    public class TwojModelJson1 implements Model {
    }

    public class TwojModelJson2 implements Model {
    }

    public static <T extends Model> List<T> parseJson(String json, Class<T> clazz) throws IOException {
        TypeFactory t = TypeFactory.defaultInstance();
        CollectionType collectionType = t.constructCollectionType(ArrayList.class, clazz);
        //noinspection unchecked
        return (List<T>) objectMapper.readValue(json,collectionType);
    }

    public static void main(String ...args) throws IOException {
        List<TwojModelJson1> lista1 = parseJson("jakis_json",TwojModelJson1.class);
        List<TwojModelJson2> lista2 = parseJson("jakis_json",TwojModelJson2.class);
    }

Na podobnej zasadzie możesz zrobić swoją wersję findViewById, która nie wymaga rzutowania:

    public static <T extends View> T view(View parent, int id) {
        //noinspection unchecked
        return (T) parent.findViewById(id);
    }
0

z internetów ściągam, dzięki za pomoc :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1