Android
Retrofit2
Zoeken…
Invoering
De officiële Retrofit-pagina beschrijft zichzelf als
Een typeveilige REST-client voor Android en Java.
Retrofit maakt van uw REST API een Java-interface. Het maakt gebruik van annotaties om HTTP-aanvragen te beschrijven, vervanging van URL-parameters en ondersteuning van query-parameters is standaard geïntegreerd. Bovendien biedt het functionaliteit voor het uploaden van bestanden met meerdere partijen en het uploaden van bestanden.
Opmerkingen
Afhankelijkheden voor de retrofitbibliotheek:
Uit de officiële documentatie :
Gradle:
dependencies {
...
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
...
}
Maven:
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.3.0</version>
</dependency>
Een eenvoudig GET-verzoek
We gaan laten zien hoe u een GET
aanvraag kunt indienen bij een API die reageert met een JSON
object of een JSON
array. Het eerste wat we moeten doen is de afhankelijkheden van Retrofit en GSON
Converter toevoegen aan het gradle-bestand van onze module.
Voeg de afhankelijkheden voor retrofitbibliotheek toe zoals beschreven in de sectie Opmerkingen.
Voorbeeld van verwacht JSON-object:
{
"deviceId": "56V56C14SF5B4SF",
"name": "Steven",
"eventCount": 0
}
Voorbeeld van JSON-array:
[
{
"deviceId": "56V56C14SF5B4SF",
"name": "Steven",
"eventCount": 0
},
{
"deviceId": "35A80SF3QDV7M9F",
"name": "John",
"eventCount": 2
}
]
Voorbeeld van overeenkomstige modelklasse:
public class Device
{
@SerializedName("deviceId")
public String id;
@SerializedName("name")
public String name;
@SerializedName("eventCount")
public int eventCount;
}
De annotaties @SerializedName
hier zijn afkomstig uit de GSON
bibliotheek en stellen ons in staat deze klasse te serialize
en te deserialize
naar JSON
met de geserialiseerde naam als sleutels. Nu kunnen we de interface bouwen voor de API die de gegevens daadwerkelijk van de server haalt.
public interface DeviceAPI
{
@GET("device/{deviceId}")
Call<Device> getDevice (@Path("deviceId") String deviceID);
@GET("devices")
Call<List<Device>> getDevices();
}
Er gebeurt hier veel in een vrij compacte ruimte, dus laten we het opsplitsen:
- De
@GET
annotatie is afkomstig van Retrofit en vertelt de bibliotheek dat we een GET-verzoek definiëren. - Het pad tussen haakjes is het eindpunt dat ons GET-verzoek zou moeten raken (we zullen de basis-URL iets later instellen).
- Met de accolades kunnen we tijdens de uitvoering delen van het pad vervangen, zodat we argumenten kunnen doorgeven.
- De functie die we definiëren heet
getDevice
en neemt de apparaat-ID die we willen als argument. - De
@PATH
annotatie vertelt Retrofit dat dit argument de "deviceId" tijdelijke aanduiding in het pad moet vervangen. - De functie retourneert een
Call
object van het typeDevice
.
Een wrapper-klasse maken:
Nu zullen we een kleine wrapper-klasse voor onze API maken om de Retrofit-initialisatiecode netjes ingepakt te houden.
public class DeviceAPIHelper
{
public final DeviceAPI api;
private DeviceAPIHelper ()
{
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
api = retrofit.create(DeviceAPI.class);
}
}
Deze klasse maakt een GSON-instantie om de JSON-reactie te kunnen parseren, maakt een Retrofit-instantie met onze basis-URL en een GSONConverter en maakt vervolgens een instantie van onze API.
Aanroepen van de API:
// Getting a JSON object
Call<Device> callObject = api.getDevice(deviceID);
callObject.enqueue(new Callback<Response<Device>>()
{
@Override
public void onResponse (Call<Device> call, Response<Device> response)
{
if (response.isSuccessful())
{
Device device = response.body();
}
}
@Override
public void onFailure (Call<Device> call, Throwable t)
{
Log.e(TAG, t.getLocalizedMessage());
}
});
// Getting a JSON array
Call<List<Device>> callArray = api.getDevices();
callArray.enqueue(new Callback<Response<List<Device>>()
{
@Override
public void onResponse (Call<List<Device>> call, Response<List<Device>> response)
{
if (response.isSuccessful())
{
List<Device> devices = response.body();
}
}
@Override
public void onFailure (Call<List<Device>> call, Throwable t)
{
Log.e(TAG, t.getLocalizedMessage());
}
});
Dit maakt gebruik van onze API-interface om respectievelijk een Call<Device>
-object te maken en een Call<List<Device>>
te maken. Calling enqueue
vertelt Retrofit om dat gesprek op een achtergrondthread te maken en het resultaat terug te brengen naar de callback die we hier maken.
Opmerking: het parseren van een JSON-array van primitieve objecten (zoals String, Integer, Boolean en Double ) is vergelijkbaar met het parseren van een JSON-array. U hebt echter geen eigen modelklasse nodig. U kunt de reeks Strings bijvoorbeeld krijgen door het retourtype van de oproep te gebruiken als Call<List<String>>
.
Logboekregistratie toevoegen aan Retrofit2
Retrofit-aanvragen kunnen worden vastgelegd met een intercepter. Er zijn verschillende detailniveaus beschikbaar: GEEN, BASIS, HEADERS, LICHAAM. Bekijk hier het Github-project .
- Voeg afhankelijkheid toe aan build.gradle:
compile 'com.squareup.okhttp3:logging-interceptor:3.8.1'
- Voeg log-interceptor toe bij het maken van Retrofit:
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(LoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.addInterceptor(loggingInterceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://example.com/")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
Het vrijgeven van de logbestanden in de Terminal (Android-monitor) is iets dat in de releaseversie moet worden vermeden, omdat dit kan leiden tot het ongewenst vrijgeven van kritieke informatie zoals Auth Tokens etc.
Controleer de volgende voorwaarde om te voorkomen dat de logboeken tijdens de uitvoering worden blootgesteld
if(BuildConfig.DEBUG){
//your interfector code here
}
Bijvoorbeeld:
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
if(BuildConfig.DEBUG){
//print the logs in this case
loggingInterceptor.setLevel(LoggingInterceptor.Level.BODY);
}else{
loggingInterceptor.setLevel(LoggingInterceptor.Level.NONE);
}
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.addInterceptor(loggingInterceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://example.com/")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
Een bestand uploaden via Multipart
Verklaar uw interface met Retrofit2-annotaties:
public interface BackendApiClient {
@Multipart
@POST("/uploadFile")
Call<RestApiDefaultResponse> uploadPhoto(@Part("file\"; filename=\"photo.jpg\" ") RequestBody photo);
}
Waar RestApiDefaultResponse
een aangepaste klasse is die het antwoord bevat.
Het bouwen van de implementatie van uw API en het winnen van de oproep:
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://<yourhost>/")
.client(okHttpClient)
.build();
BackendApiClient apiClient = retrofit.create(BackendApiClient.class);
RequestBody reqBody = RequestBody.create(MediaType.parse("image/jpeg"), photoFile);
Call<RestApiDefaultResponse> call = apiClient.uploadPhoto(reqBody);
call.enqueue(<your callback function>);
Retrofit met OkHttp interceptor
Dit voorbeeld laat zien hoe u een verzoek-interceptor gebruikt met OkHttp. Dit heeft talloze gebruiksscenario's zoals:
- Universele
header
toevoegen aan het verzoek. Bijvoorbeeld een verzoek authenticeren - Debuggen van netwerkapplicaties
- Onbewerkte
response
opgehaald - Logging netwerktransactie etc.
- Stel een aangepaste user-agent in
Retrofit.Builder builder = new Retrofit.Builder()
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://api.github.com/");
if (!TextUtils.isEmpty(githubToken)) {
// `githubToken`: Access token for GitHub
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
@Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request newReq = request.newBuilder()
.addHeader("Authorization", format("token %s", githubToken))
.build();
return chain.proceed(newReq);
}
}).build();
builder.client(client);
}
return builder.build().create(GithubApi.class);
Zie OkHttp-onderwerp voor meer informatie.
Koptekst en hoofdtekst: een authenticatievoorbeeld
De annotaties @Header
en @Body
kunnen in de handtekeningen van de methode worden geplaatst en Retrofit maakt ze automatisch op basis van uw modellen.
public interface MyService {
@POST("authentication/user")
Call<AuthenticationResponse> authenticateUser(@Body AuthenticationRequest request, @Header("Authorization") String basicToken);
}
AuthenticaionRequest is ons model, een POJO, met de informatie die de server nodig heeft. Voor dit voorbeeld wil onze server de clientsleutel en geheim.
public class AuthenticationRequest {
String clientKey;
String clientSecret;
}
Merk op dat in @Header("Authorization")
we specificeren dat we de kop Autorisatie invullen. De andere headers worden automatisch ingevuld omdat Retrofit kan afleiden wat ze zijn op basis van het type objecten dat we in ruil daarvoor verzenden en verwachten.
We creëren onze Retrofit-service ergens. We zorgen ervoor dat we HTTPS gebruiken.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https:// some example site")
.client(client)
.build();
MyService myService = retrofit.create(MyService.class)
Dan kunnen we onze service gebruiken.
AuthenticationRequest request = new AuthenticationRequest();
request.setClientKey(getClientKey());
request.setClientSecret(getClientSecret());
String basicToken = "Basic " + token;
myService.authenticateUser(request, basicToken);
Upload meerdere bestanden met Retrofit als multipart
Nadat u de Retrofit-omgeving in uw project hebt ingesteld, kunt u het volgende voorbeeld gebruiken dat laat zien hoe u meerdere bestanden kunt uploaden met Retrofit:
private void mulipleFileUploadFile(Uri[] fileUri) {
OkHttpClient okHttpClient = new OkHttpClient();
OkHttpClient clientWith30sTimeout = okHttpClient.newBuilder()
.readTimeout(30, TimeUnit.SECONDS)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL_BASE)
.addConverterFactory(new MultiPartConverter())
.client(clientWith30sTimeout)
.build();
WebAPIService service = retrofit.create(WebAPIService.class); //here is the interface which you have created for the call service
Map<String, okhttp3.RequestBody> maps = new HashMap<>();
if (fileUri!=null && fileUri.length>0) {
for (int i = 0; i < fileUri.length; i++) {
String filePath = getRealPathFromUri(fileUri[i]);
File file1 = new File(filePath);
if (filePath != null && filePath.length() > 0) {
if (file1.exists()) {
okhttp3.RequestBody requestFile = okhttp3.RequestBody.create(okhttp3.MediaType.parse("multipart/form-data"), file1);
String filename = "imagePath" + i; //key for upload file like : imagePath0
maps.put(filename + "\"; filename=\"" + file1.getName(), requestFile);
}
}
}
}
String descriptionString = " string request";//
//hear is the your json request
Call<String> call = service.postFile(maps, descriptionString);
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call,
Response<String> response) {
Log.i(LOG_TAG, "success");
Log.d("body==>", response.body().toString() + "");
Log.d("isSuccessful==>", response.isSuccessful() + "");
Log.d("message==>", response.message() + "");
Log.d("raw==>", response.raw().toString() + "");
Log.d("raw().networkResponse()", response.raw().networkResponse().toString() + "");
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Log.e(LOG_TAG, t.getMessage());
}
});
}
public String getRealPathFromUri(final Uri uri) { // function for file path from uri,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(mContext, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(mContext, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
return getDataColumn(mContext, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(mContext, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
Hierna volgt de interface
public interface WebAPIService {
@Multipart
@POST("main.php")
Call<String> postFile(@PartMap Map<String,RequestBody> Files, @Part("json") String description);
}
Download een bestand van Server met Retrofit2
Interfaceverklaring voor het downloaden van een bestand
public interface ApiInterface {
@GET("movie/now_playing")
Call<MovieResponse> getNowPlayingMovies(@Query("api_key") String apiKey, @Query("page") int page);
// option 1: a resource relative to your base URL
@GET("resource/example.zip")
Call<ResponseBody> downloadFileWithFixedUrl();
// option 2: using a dynamic URL
@GET
Call<ResponseBody> downloadFileWithDynamicUrl(@Url String fileUrl);
}
De optie 1 wordt gebruikt voor het downloaden van een bestand van de server met een vaste URL. en optie 2 wordt gebruikt om een dynamische waarde door te geven als volledige URL om een oproep aan te vragen. Dit kan handig zijn bij het downloaden van bestanden, die afhankelijk zijn van parameters zoals gebruiker of tijd.
Retrofit instellen voor het uitvoeren van API-oproepen
public class ServiceGenerator {
public static final String API_BASE_URL = "http://your.api-base.url/";
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
public static <S> S createService(Class<S> serviceClass){
Retrofit retrofit = builder.client(httpClient.build()).build();
return retrofit.create(serviceClass);
}
}
Maak nu de implementatie van api voor het downloaden van het bestand van de server
private void downloadFile(){
ApiInterface apiInterface = ServiceGenerator.createService(ApiInterface.class);
Call<ResponseBody> call = apiInterface.downloadFileWithFixedUrl();
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()){
boolean writtenToDisk = writeResponseBodyToDisk(response.body());
Log.d("File download was a success? ", String.valueOf(writtenToDisk));
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
En nadat u antwoord hebt gekregen in de callback, codeert u een standaard-IO voor het opslaan van het bestand op schijf. Hier is de code:
private boolean writeResponseBodyToDisk(ResponseBody body) {
try {
// todo change the file location/name according to your needs
File futureStudioIconFile = new File(getExternalFilesDir(null) + File.separator + "Future Studio Icon.png");
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
long fileSize = body.contentLength();
long fileSizeDownloaded = 0;
inputStream = body.byteStream();
outputStream = new FileOutputStream(futureStudioIconFile);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
Log.d("File Download: " , fileSizeDownloaded + " of " + fileSize);
}
outputStream.flush();
return true;
} catch (IOException e) {
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
return false;
}
}
Merk op dat we ResponseBody als retourtype hebben gespecificeerd, anders zal Retrofit proberen het te parseren en te converteren, wat niet logisch is wanneer u een bestand downloadt.
Als je meer wilt weten over retrofit-spullen, ga dan naar deze link, omdat het erg handig is. [1]: https://futurestud.io/blog/retrofit-getting-started-and-android-client
Debuggen met Stetho
Voeg de volgende afhankelijkheden toe aan uw toepassing.
compile 'com.facebook.stetho:stetho:1.5.0'
compile 'com.facebook.stetho:stetho-okhttp3:1.5.0'
Bel het volgende in de methode onCreate
uw toepassingsklasse.
Stetho.initializeWithDefaults(this);
Maak bij het maken van uw Retrofit
instantie een aangepaste OkHttp-instantie.
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
clientBuilder.addNetworkInterceptor(new StethoInterceptor());
Stel vervolgens deze aangepaste OkHttp-instantie in de Retrofit-instantie in.
Retrofit retrofit = new Retrofit.Builder()
// ...
.client(clientBuilder.build())
.build();
Verbind nu uw telefoon met uw computer, start de app en typ chrome://inspect
in uw Chrome-browser. Retrofit-netwerkoproepen zouden nu moeten verschijnen voor inspectie.
Retrofit 2 Custom XML-converter
Afhankelijkheden toevoegen aan het bestand build.gradle.
dependencies {
....
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile ('com.thoughtworks.xstream:xstream:1.4.7') {
exclude group: 'xmlpull', module: 'xmlpull'
}
....
}
Maak vervolgens Converter Factory aan
public class XStreamXmlConverterFactory extends Converter.Factory {
/** Create an instance using a default {@link com.thoughtworks.xstream.XStream} instance for conversion. */
public static XStreamXmlConverterFactory create() {
return create(new XStream());
}
/** Create an instance using {@code xStream} for conversion. */
public static XStreamXmlConverterFactory create(XStream xStream) {
return new XStreamXmlConverterFactory(xStream);
}
private final XStream xStream;
private XStreamXmlConverterFactory(XStream xStream) {
if (xStream == null) throw new NullPointerException("xStream == null");
this.xStream = xStream;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
if (!(type instanceof Class)) {
return null;
}
Class<?> cls = (Class<?>) type;
return new XStreamXmlResponseBodyConverter<>(cls, xStream);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
if (!(type instanceof Class)) {
return null;
}
return new XStreamXmlRequestBodyConverter<>(xStream);
}
}
maak een klasse om het body-verzoek af te handelen.
final class XStreamXmlResponseBodyConverter <T> implements Converter<ResponseBody, T> {
private final Class<T> cls;
private final XStream xStream;
XStreamXmlResponseBodyConverter(Class<T> cls, XStream xStream) {
this.cls = cls;
this.xStream = xStream;
}
@Override
public T convert(ResponseBody value) throws IOException {
try {
this.xStream.processAnnotations(cls);
Object object = this.xStream.fromXML(value.byteStream());
return (T) object;
}finally {
value.close();
}
}
}
creëer een klasse om de lichaamsreactie aan te kunnen.
final class XStreamXmlRequestBodyConverter<T> implements Converter<T, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType.parse("application/xml; charset=UTF-8");
private static final String CHARSET = "UTF-8";
private final XStream xStream;
XStreamXmlRequestBodyConverter(XStream xStream) {
this.xStream = xStream;
}
@Override
public RequestBody convert(T value) throws IOException {
Buffer buffer = new Buffer();
try {
OutputStreamWriter osw = new OutputStreamWriter(buffer.outputStream(), CHARSET);
xStream.toXML(value, osw);
osw.flush();
} catch (Exception e) {
throw new RuntimeException(e);
}
return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
}
}
Dus, op dit punt kunnen we elke XML verzenden en ontvangen. We moeten alleen XStream-annotaties maken voor de entiteiten.
Maak vervolgens een Retrofit-instantie:
XStream xs = new XStream(new DomDriver());
xs.autodetectAnnotations(true);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://example.com/")
.addConverterFactory(XStreamXmlConverterFactory.create(xs))
.client(client)
.build();
Een eenvoudig POST-verzoek met GSON
Voorbeeld JSON:
{
"id": "12345",
"type": "android"
}
Definieer uw verzoek:
public class GetDeviceRequest {
@SerializedName("deviceId")
private String mDeviceId;
public GetDeviceRequest(String deviceId) {
this.mDeviceId = deviceId;
}
public String getDeviceId() {
return mDeviceId;
}
}
Definieer uw service (te behalen eindpunten):
public interface Service {
@POST("device")
Call<Device> getDevice(@Body GetDeviceRequest getDeviceRequest);
}
Definieer uw enkele instantie van de netwerkclient:
public class RestClient {
private static Service REST_CLIENT;
static {
setupRestClient();
}
private static void setupRestClient() {
// Define gson
Gson gson = new Gson();
// Define our client
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://example.com/")
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
REST_CLIENT = retrofit.create(Service.class);
}
public static Retrofit getRestClient() {
return REST_CLIENT;
}
}
Definieer een eenvoudig modelobject voor het apparaat:
public class Device {
@SerializedName("id")
private String mId;
@SerializedName("type")
private String mType;
public String getId() {
return mId;
}
public String getType() {
return mType;
}
}
Definieer controller om de aanvragen voor het apparaat af te handelen
public class DeviceController {
// Other initialization code here...
public void getDeviceFromAPI() {
// Define our request and enqueue
Call<Device> call = RestClient.getRestClient().getDevice(new GetDeviceRequest("12345"));
// Go ahead and enqueue the request
call.enqueue(new Callback<Device>() {
@Override
public void onSuccess(Response<Device> deviceResponse) {
// Take care of your device here
if (deviceResponse.isSuccess()) {
// Handle success
//delegate.passDeviceObject();
}
}
@Override
public void onFailure(Throwable t) {
// Go ahead and handle the error here
}
});
XML-formulier-URL lezen met Retrofit 2
We zullen retrofit 2 en SimpleXmlConverter gebruiken om xml-gegevens van url en parser naar Java-klasse te krijgen.
Afhankelijkheid toevoegen aan Gradle-script:
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-simplexml:2.1.0'
Maak een interface
Maak ook xml class wrapper in onze case Rss-klasse
public interface ApiDataInterface{
// path to xml link on web site
@GET (data/read.xml)
Call<Rss> getData();
}
Xml leesfunctie
private void readXmlFeed() {
try {
// base url - url of web site
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(http://www.google.com/)
.client(new OkHttpClient())
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
ApiDataInterface apiService = retrofit.create(ApiDataInterface.class);
Call<Rss> call = apiService.getData();
call.enqueue(new Callback<Rss>() {
@Override
public void onResponse(Call<Rss> call, Response<Rss> response) {
Log.e("Response success", response.message());
}
@Override
public void onFailure(Call<Rss> call, Throwable t) {
Log.e("Response fail", t.getMessage());
}
});
} catch (Exception e) {
Log.e("Exception", e.getMessage());
}
}
Dit is een voorbeeld van de Java-klasse met SimpleXML-annotaties
Meer over annotaties SimpleXmlDocumentation
@Root (name = "rss")
public class Rss
{
public Rss() {
}
public Rss(String title, String description, String link, List<Item> item, String language) {
this.title = title;
this.description = description;
this.link = link;
this.item = item;
this.language = language;
}
@Element (name = "title")
private String title;
@Element(name = "description")
private String description;
@Element(name = "link")
private String link;
@ElementList (entry="item", inline=true)
private List<Item> item;
@Element(name = "language")
private String language;