Uso de Retrofit para acceder a los arrays JSON
Pensé que entendía cómo hacer esto, pero obviamente no. Tengo mi API de Flickr, que comienza así:
jsonFlickrApi({ "photos":{ "page":1, "pages":10, "perpage":100, "total":1000, "photo":[ { "id":"12567883725", "owner":"74574845@N05", "secret":"a7431762dd", "server":"7458", "farm":8, "title":"", "ispublic":1, "isfriend":0, "isfamily":0, "url_l":"http:\/\/farm8.staticflickr.com\/7458\/12567883725_a7431762dd_b.jpg", "height_l":"683", "width_l":"1024" }
Ahora la información que necesito para obtener es de dentro de la matriz de fotos, así que lo que he estado tratando de hacer es:
- Intentando construir Android Emulator con ionic falla .. "Clase no encontrada: javac1.8"
- Intenta invocar método de interfaz en una referencia de objeto nulo finishComposingText ()
- Los caracteres árabes en String.Format ("% d", 1, Locale.US)
- Android sin Java
- Obtener la altura de STATUS BAR
interface ArtService { @GET("/services/rest/?method=flickr.photos.getRecent&extras=url_l&owner_name&format=json") PhotosResponse getPhotos(); public class PhotosResponse { Photos photos; } public class Photos { List<Arraz> photo; } public class Arraz { int id; String title; String owner; String url_l; } }
Muy claro que me parece que falta el punto, sin embargo no estoy seguro de cómo obtener la información ..
- Excepción Outofmemory utilizando la biblioteca retrofit android
- Intent.putExtra (String, Bundle) vs Intent.putExtra (Bundle)
- ¿Puedo estar seguro de que la aplicación Android terminó de ejecutarse comprobando isFinish () en OnPause () de la actividad principal?
- ¿Cómo maneja el XmlPullParser de Android las vulnerabilidades?
- Problema con Proguard de Android: sigue recibiendo error "java.io.IOException: No se puede procesar la clase ..." cuando se oculta la obfuscación
- Finalización de la asignación de actividad de la interfaz de usuario
- Bucle de audio de Android Gapless
- ¿Puede el androide sqlite interfaz ser utilizado fuera de Android
Una mirada rápida a los documentos de Retrofit dice que utiliza Gson para convertir JSON a clases Java. Esto significa que necesita una jerarquía de clases en Java que coincida con JSON. El tuyo … no.
El JSON devuelto es un objeto con un solo campo "fotos" que contiene un objeto;
{ "photos" : { ... } }
Por lo tanto, su clase de nivel superior sería una clase Java con un solo campo:
public class PhotosResponse { private Photos photos; // getter/setter }
Y ese tipo de Photos
sería otra clase que coincida con el JSON para el objeto que contiene el campo:
{ "page":1, "pages":10, ... }
Así que tendrías:
public class Photos { private int page; private int pages; private int perpage' private int total; private List<Photo> photo; // getters / setters }
Y luego crearía una clase Photo
para que coincida con la estructura del objeto en esa matriz interna. Gson entonces mapeará el JSON devuelto apropiadamente.
Yo sugeriría usar http://www.jsonschema2pojo.org . Puede pegar su JSON y generará los POJOs para usted.
Eso debería hacer el truco.
La respuesta aceptada es correcta pero requiere la construcción de una clase PhotoResponse que sólo tiene un objeto en ella. Esta es la siguiente solución, solo necesitamos crear la clase Photos y alguna esterilización.
Creamos un JsonDeserializer:
class PhotosDeserializer implements JsonDeserializer<Photos> { @Override public Photos deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonElement content = json.getAsJsonObject().get("photos"); return new Gson().fromJson(content, Photos.class); } }
Ahora creamos nuestro objeto gson personalizado en el RestAdapter de Retrofit:
Gson gson = new GsonBuilder() .registerTypeAdapter(Photos.class, new PhotosDeserializer()) .create();
Y luego ponemos el convertidor en el adaptador de retrofit:
RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(ArtService.ENDPOINT) .setConverter(new GsonConverter(gson)) .build();
Y la interfaz se vería así:
@GET("/?method="+METHOD_GET_RECENT+"&api_key="+API_KEY+"&format=json&nojsoncallback=1&extras="+EXTRAS_URL) public void getPhotos(Callback<Photos> response);
De esta manera obtendremos el objeto Photos sin tener que crear la clase PhotosResponse. Podemos usarlo así:
ArtService artService = restAdapter.create(ArtService.class); artService.getPhotos(new Callback<Photos>() { @Override public void success(Photos photos, Response response) { // Array of photos accessing by photos.photo } @Override public void failure(RetrofitError error) { } });
Debe poder acceder directamente a com.google.gson.JsonObject desde Retrofit y acceder a cualquier campo que desee. Así que si sólo está interesado en la matriz de fotos algo así debería funcionar:
interface ArtService { @GET("/services/rest/?method=flickr.photos.getRecent&extras=url_l&owner_name&format=json") JsonObject getPhotos(); public class Photo { int id; String title; String owner; String url_l; } }
Y cuando usted realmente llama al servicio apenas funciona el JsonObject para conseguir lo que usted desea:
JsonObject json = mRestClient.getArtService().getPhotos(); List<ArtService.Photo> photos = new Gson().fromJson(json.getAsJsonObject("photos").get("photo").toString(), new TypeToken<List<ArtService.Photo>>() {}.getType());
Por supuesto, todo el control de la cordura se deja para usted.
Como ya hay pocas respuestas por encima de las cuales usted puede usar. Pero según mi opinión use esto. Hacer una clase de fotos con todas las variables dadas en el objeto de las fotos y crear getter setter de todos y también crear una clase de foto con mantendrá la lista de fotos y también crear getter setter de esta lista en el lado de la clase Photos. A continuación se muestra el código dado.
public static class Photos { @JsonProperty("page") private double page; @JsonProperty("pages") private double pages; @JsonProperty("perpage") private double perpage; @JsonProperty("total") private double total; @JsonProperty("photo") private List<Photo> photo; public double getPage() { return page; } public void setPage(double page) { this.page = page; } public double getPages() { return pages; } public void setPages(double pages) { this.pages = pages; } public double getPerpage() { return perpage; } public void setPerpage(double perpage) { this.perpage = perpage; } public double getTotal() { return total; } public void setTotal(double total) { this.total = total; } } public static class Photo { // refer first class and declare all variable of photo array and generate getter setter. }
- Cómo centrar el vector dibujable en la lista de capas sin escala
- ¿Cómo usar el tema predeterminado del dispositivo para la aplicación?