webentwicklung-frage-antwort-db.com.de

Retrofit 2 - Dynamische URL

Mit Retrofit 2 können Sie eine vollständige URL in der Anmerkung einer Dienstmethode wie folgt festlegen:

public interface APIService {
  @GET("http://api.mysite.com/user/list")
  Call<Users> getUsers();
}

In meiner App ist die URL meiner Webservices zum Zeitpunkt der Kompilierung jedoch nicht bekannt. Die App ruft sie in einer heruntergeladenen Datei ab, sodass ich mich frage, wie Retrofit 2 mit einer vollständigen dynamischen URL verwendet werden kann.

Ich habe versucht, einen vollständigen Pfad wie folgt festzulegen:

public interface APIService {
  @GET("{fullUrl}")
  Call<Users> getUsers(@Path("fullUrl") fullUrl);
}

new Retrofit.Builder()
  .baseUrl("http://api.mysite.com/")
  .build()
  .create(APIService.class)
  .getUsers("http://api.mysite.com/user/list"); // this url should be dynamic
  .execute();

Hier sieht Retrofit jedoch nicht, dass der Pfad tatsächlich eine vollständige URL ist und versucht, http://api.mysite.com/http%3A%2F%2Fapi.mysite.com%2Fuser%2Flist Herunterzuladen.

Gibt es einen Hinweis, wie ich Retrofit mit einer solchen dynamischen URL verwenden könnte?

Danke

140
pdegand59

Ich denke, Sie verwenden es falsch. Hier ist ein Auszug aus dem Changelog :

Neu: Mit der @Url-Parameteranmerkung kann eine vollständige URL für einen Endpunkt übergeben werden.

Ihre Benutzeroberfläche sollte also so aussehen:

public interface APIService {
    @GET
    Call<Users> getUsers(@Url String url);
}
307
Yazazzello

Ich wollte nur einen Teil der URL ersetzen und bei dieser Lösung muss ich nicht die gesamte URL übergeben, sondern nur den dynamischen Teil:

public interface APIService {

  @GET("users/{user_id}/playlists")
  Call<List<Playlist> getUserPlaylists(@Path(value = "user_id", encoded = true) String userId);
}
93
Andras Kloczl

Sie können das codierte Flag in der Annotation @Path Verwenden:

public interface APIService {
  @GET("{fullUrl}")
  Call<Users> getUsers(@Path(value = "fullUrl", encoded = true) String fullUrl);
}
  • Dies verhindert das Ersetzen von / Durch %2F.
  • Es wird Sie jedoch nicht davor bewahren, ? Durch %3F Ersetzt zu werden, sodass Sie weiterhin keine dynamischen Abfragezeichenfolgen übergeben können.
26
fgysin

Ab Retrofit 2.0.0-beta2 gilt: http: // myhost/mypath

Folgendes funktioniert nicht:

public interface ClientService {
    @GET("")
    Call<List<Client>> getClientList();
}

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("http://myhost/mypath")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

ClientService service = retrofit.create(ClientService.class);

Response<List<Client>> response = service.getClientList().execute();

Aber das ist ok:

public interface ClientService {
    @GET
    Call<List<Client>> getClientList(@Url String anEmptyString);
}

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("http://myhost/mypath")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

ClientService service = retrofit.create(ClientService.class);

Response<List<Client>> response = service.getClientList("").execute();
16
yann-h

Sie können dies verwenden:

@GET("group/{id}/users")

Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);

Weitere Informationen finden Sie in der Dokumentation https://square.github.io/retrofit/

3
Dev_Abraham

Schritt-1

  Please define a method in Api interface like:-
 @FormUrlEncoded
 @POST()
 Call<RootLoginModel> getForgotPassword(
        @Url String apiname,
        @Field(ParameterConstants.email_id) String username
 );

Schritt-2 Für eine optimale Vorgehensweise definieren Sie eine Klasse für die Nachrüstinstanz: -

  public class ApiRequest {
       static Retrofit retrofit = null;



public static Retrofit getClient() {
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
            .addInterceptor(logging)
            .connectTimeout(60, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .writeTimeout(60, TimeUnit.SECONDS)
            .build();

    if (retrofit==null) {
        retrofit = new Retrofit.Builder()
                .baseUrl(URLConstants.base_url)
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit;
}

} Schritt- definiere in deiner Aktivität: -

  final APIService request =ApiRequest.getClient().create(APIService.class);
  Call<RootLoginModel> call = request.getForgotPassword("dynamic api 
  name",strEmailid);
2
Govind Chauhan

Wenn Sie Ihren Code bereits eingerichtet haben und keine Änderungen an den verschiedenen Schnittstellen vornehmen möchten, verwenden Sie die in diesem Link beschriebene Lösung. Der Hauptpunkt ist die Methode changeApiBaseUrl, die die URL aktualisiert und den Builder für Nachrüstung neu erstellt.

public class ServiceGenerator {  
public static String apiBaseUrl = "http://futurestud.io/api";
private static Retrofit retrofit;

private static Retrofit.Builder builder =
        new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(apiBaseUrl);

private static OkHttpClient.Builder httpClient =
        new OkHttpClient.Builder();

// No need to instantiate this class.
private ServiceGenerator() {
}

public static void changeApiBaseUrl(String newApiBaseUrl) {
    apiBaseUrl = newApiBaseUrl;

    builder = new Retrofit.Builder()
                    .addConverterFactory(GsonConverterFactory.create())
                    .baseUrl(apiBaseUrl);
}

public static <S> S createService(Class<S> serviceClass, AccessToken token) {
    String authToken = token.getTokenType().concat(token.getAccessToken());
    return createService(serviceClass, authToken);
}

// more methods
// ...
}

Sie können es wie folgt verwenden:

public class DynamicBaseUrlActivity extends AppCompatActivity {

public static final String TAG = "CallInstances";
private Callback<ResponseBody> downloadCallback;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_file_upload);

    downloadCallback = new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            Log.d(TAG, "server contacted at: " + call.request().url());
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            Log.d(TAG, "call failed against the url: " + call.request().url());
        }
    };

    // first request
    FileDownloadService downloadService = ServiceGenerator.create(FileDownloadService.class);
    Call<ResponseBody> originalCall = downloadService.downloadFileWithFixedUrl();
    originalCall.enqueue(downloadCallback);

    // change base url
    ServiceGenerator.changeApiBaseUrl("http://development.futurestud.io/api");

    // new request against new base url
    FileDownloadService newDownloadService = ServiceGenerator.create(FileDownloadService.class);
    Call<ResponseBody> newCall = newDownloadService.downloadFileWithFixedUrl();
    newCall.enqueue(downloadCallback);
    }
}
0
step -*1 

movie_list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:background="?android:attr/selectableItemBackground"
    Android:clickable="true"
    Android:focusable="true"

    Android:orientation="horizontal"
    Android:paddingLeft="@dimen/activity_horizontal_margin"
    Android:paddingTop="@dimen/row_padding_vertical"
    Android:paddingRight="@dimen/activity_horizontal_margin"
    Android:paddingBottom="@dimen/row_padding_vertical">

    <ImageView
        Android:id="@+id/ivImage"
        Android:layout_width="60dp"
        Android:layout_height="60dp"
        Android:layout_marginRight="10dp"
        Android:src="@mipmap/ic_launcher" />

    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_weight="1"
        Android:orientation="vertical">

        <TextView
            Android:id="@+id/title"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layout_alignParentTop="true"
            Android:text="Hello"
            Android:textColor="@color/title"
            Android:textSize="16dp"
            Android:textStyle="bold" />

        <TextView
            Android:id="@+id/genre"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layout_below="@id/title"
            Android:text="realName" />
    </LinearLayout>

    <TextView
        Android:id="@+id/year"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_alignParentRight="true"
        Android:text="Team"
        Android:textColor="@color/year" />

</LinearLayout>                                                                                                            

Api.Java                                                                                  
import org.json.JSONObject;

import Java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;

public interface  Api {

    String BASE_URL = "https://simplifiedcoding.net/demos/";

    @GET("marvel")
    Call<List<Hero>> getHeroes();

    @FormUrlEncoded
    @POST("/login")
    public void login(@Field("username") String username, @Field("password") String password, Callback<List<Hero>> callback);

}


MoviesAdapter.Java                                                                                       import Android.content.Context;
import Android.support.v7.widget.RecyclerView;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.ImageView;
import Android.widget.TextView;
import Android.widget.Toast;

import com.squareup.picasso.Picasso;

import Java.util.List;

public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MyViewHolder> {

    private List<Hero> moviesList;

    Context context;


    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView title, year, genre;
        public ImageView ivImage;

        public MyViewHolder(View view) {
            super(view);
            title = (TextView) view.findViewById(R.id.title);
            genre = (TextView) view.findViewById(R.id.genre);
            year = (TextView) view.findViewById(R.id.year);
            ivImage =  view.findViewById(R.id.ivImage);
            ivImage.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    Toast.makeText(context, "-" + moviesList.get(getAdapterPosition()).getName(), Toast.LENGTH_SHORT).show();
                }
            });
        }
    }


    public MoviesAdapter(List<Hero> moviesList,Context context) {
        this.moviesList = moviesList;
        this.context = context;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.movie_list_row, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Hero movie = moviesList.get(position);
        holder.title.setText(movie.getName());
        holder.genre.setText(movie.getRealname());
        holder.year.setText(movie.getTeam());

        Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(holder.ivImage);
    }

    @Override
    public int getItemCount() {
        return moviesList.size();
    }
}                                                                                                                                                        main activity                                                                                                               import Android.support.v7.app.AppCompatActivity;
import Android.os.Bundle;
import Android.support.v7.widget.DefaultItemAnimator;
import Android.support.v7.widget.LinearLayoutManager;
import Android.support.v7.widget.RecyclerView;
import Android.widget.ArrayAdapter;
import Android.widget.ListView;
import Android.widget.Toast;

import Java.util.ArrayList;
import Java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class MainActivity extends AppCompatActivity {

    private List<Hero> movieList = new ArrayList<>();
    private RecyclerView recyclerView;
    private MoviesAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView=findViewById(R.id.recycler_view);
        mAdapter = new MoviesAdapter(movieList,MainActivity.this);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(mAdapter);
        //calling the method to display the heroes
        getHeroes();

    }


    private void getHeroes() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(ApiInterface.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create()) //Here we are using the GsonConverterFactory to directly convert json data to object
                .build();

        ApiInterface api = retrofit.create(ApiInterface.class);

        Call<List<Hero>> call = api.getHeroes();

        call.enqueue(new Callback<List<Hero>>() {
            @Override
            public void onResponse(Call<List<Hero>> call, Response<List<Hero>> response) {
                List<Hero> heroList = response.body();

                //Creating an String array for the ListView
                String[] heroes = new String[heroList.size()];

                //looping through all the heroes and inserting the names inside the string array
                for (int i = 0; i < heroList.size(); i++) {
                    //heroes[i] = heroList.get(i).getName();
                    movieList.add(new Hero( heroList.get(i).getName(), heroList.get(i).getRealname(), heroList.get(i).getTeam()));
                }
                mAdapter.notifyDataSetChanged();

            }

            @Override
            public void onFailure(Call<List<Hero>> call, Throwable t) {
                Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

}
Hero.Java
package com.example.owner.apipractice;
public class Hero {

    private String name;
    private String realname;
    private String team;

    public Hero(String name, String realname, String team) {
        this.name = name;
        this.realname = realname;
        this.team = team;
    }

    private String firstappearance;
    private String createdby;
    private String publisher;
    private String imageurl;
    private String bio;


    public Hero(String name, String realname, String team, String firstappearance, String createdby, String publisher, String imageurl, String bio) {
        this.name = name;
        this.realname = realname;
        this.team = team;
        this.firstappearance = firstappearance;
        this.createdby = createdby;
        this.publisher = publisher;
        this.imageurl = imageurl;
        this.bio = bio;
    }

    public String getName() {
        return name;
    }

    public String getRealname() {
        return realname;
    }

    public String getTeam() {
        return team;
    }

    public String getFirstappearance() {
        return firstappearance;
    }

    public String getCreatedby() {
        return createdby;
    }

    public String getPublisher() {
        return publisher;
    }

    public String getImageurl() {
        return imageurl;
    }

    public String getBio() {
        return bio;
    }
}
0
Nis