रेट्रोफिट 2 - डायनामिक URL


181

रेट्रोफ़िट 2 के साथ, आप एक पूर्ण URL को सेवा पद्धति के एनोटेशन में सेट कर सकते हैं जैसे:

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

हालाँकि, मेरे ऐप में, मेरे वेबसर्विस के URL का संकलन समय पर ज्ञात नहीं है, ऐप उन्हें एक डाउनलोड की गई फ़ाइल में पुनः प्राप्त करता है, इसलिए मैं सोच रहा हूं कि मैं पूर्ण गतिशील URL के साथ Retrofit 2 का उपयोग कैसे कर सकता हूं।

मैंने पूरा रास्ता सेट करने की कोशिश की जैसे:

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();

लेकिन यहाँ, रेट्रोफ़िट यह नहीं देखता कि पथ वास्तव में एक पूर्ण URL है और डाउनलोड करने का प्रयास कर रहा है http://api.mysite.com/http%3A%2F%2Fapi.mysite.com%2Fuser%2Flist

इस तरह के गतिशील url के साथ मैं Retrofit का उपयोग कैसे कर सकता हूं इसका कोई संकेत?

धन्यवाद


5
भविष्य के खोजकर्ताओं के लिए, रेट्रोफिट के साथ गतिशील URL पर एक गाइड है: futurestud.io/tutorials/…
peitek

जवाबों:


389

मुझे लगता है कि आप इसे गलत तरीके से इस्तेमाल कर रहे हैं। यहाँ चैंज से एक अंश दिया गया है :

नया: @Url पैरामीटर एनोटेशन एक समापन बिंदु के लिए एक पूर्ण URL पास करने की अनुमति देता है।

तो आपका इंटरफ़ेस इस तरह होना चाहिए:

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

1
@ pdegand59 यह एकदम नया :) देखने के बदलाव का
Yazazzello

2
क्यों आधारभूत की आवश्यकता है, हालांकि समापन बिंदु के लिए url एक पूर्ण है?
बिलजोकर 10

13
अगर मैं इस @Url एनोटेशन का उपयोग करता हूं। तब हमें .baseUrl () में क्या लिखना चाहिए ??
गुलनाज घांची

12
आपको अपना प्राथमिक url लिखना चाहिए। @Url पैरामीटर वैसे भी इसे ओवरराइड करेगा।
यज्ज़ेल्लो

5
मैं जोड़ने के ऊपर एक लेकिन baseurl है कि मैं सामान्य रूप से पुराना वापस बिल्डर के लिए निर्धारित की तरह URL को इस प्रकार के बजाय पूर्ण यूआरएल मैं पैरामीटर में निर्दिष्ट overides यह होने का कोशिश की dynamic.com इसे करने के लिए अनुवाद हो जाता है //dynamic.com: MyBaseUrl / http
जोनाथन

129

मैं केवल यूआरएल के एक हिस्से को बदलना चाहता था, और इस समाधान के साथ, मुझे पूरे यूआरएल को पास नहीं करना है, बस गतिशील भाग:

public interface APIService {

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

मेरी बहुत मदद की ... धन्यवाद
सिद्धेश शिरोडकर

33

आप एनोटेशन पर एन्कोड किए गए ध्वज का उपयोग कर सकते हैं @Path:

public interface APIService {
  @GET("{fullUrl}")
  Call<Users> getUsers(@Path(value = "fullUrl", encoded = true) String fullUrl);
}
  • इस के प्रतिस्थापन कर पाएगा /साथ %2F
  • हालाँकि, यह आपके ?द्वारा प्रतिस्थापित होने से नहीं बचाएगा %3F, इसलिए आप अभी भी डायनेमिक क्वेरी स्ट्रिंग्स में पास नहीं कर सकते हैं।

यह एक टाइपो नहीं है।
मैथ्यू बह्र

और% 3F को बदलने के लिए क्या करना है?
योगेश सेरलिया

19

यदि आपके पास इस URL से JSON का जवाब देने वाली एक सेवा है, तो 2.0.0-beta2 के रूप में: http: // myhost / mypath

निम्नलिखित काम नहीं कर रहा है:

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();

लेकिन यह ठीक है:

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();

7

आप इसका उपयोग कर सकते हैं:

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

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

अधिक जानकारी के लिए देखें दस्तावेज https://square.github.io/retrofit/


3

चरण 1

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

चरण -2 सर्वश्रेष्ठ अभ्यास के लिए रेट्रोफिट उदाहरण के लिए एक वर्ग को परिभाषित करें: -

  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;
}

} चरण -3 अपनी गतिविधि में परिभाषित करें: -

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

2

RetrofitHelper पुस्तकालय kotlin में लिखा है, तो आप कोड की कुछ लाइनें का उपयोग कर API कॉल करने, दूँगी और आप उपयोग कर सकते , शीर्ष लेख और पैरामीटर अलग-अलग URL हर कॉल में,।

इस तरह अपने आवेदन वर्ग में कई यूआरएल जोड़ें:

class Application : Application() {

    override fun onCreate() {
    super.onCreate()

        retrofitClient = RetrofitClient.instance
                    //api url
                .setBaseUrl("https://reqres.in/")
                    //you can set multiple urls
        //                .setUrl("example","http://ngrok.io/api/")
                    //set timeouts
                .setConnectionTimeout(4)
                .setReadingTimeout(15)
                    //enable cache
                .enableCaching(this)
                    //add Headers
                .addHeader("Content-Type", "application/json")
                .addHeader("client", "android")
                .addHeader("language", Locale.getDefault().language)
                .addHeader("os", android.os.Build.VERSION.RELEASE)
            }

        companion object {
        lateinit var retrofitClient: RetrofitClient

        }
    }  

और फिर अपनी कॉल में उस URL का उपयोग करें जिसकी आपको आवश्यकता है:

retrofitClient.Get<GetResponseModel>()
            //set base url
            .setBaseUrlKey("example")
            //set path
            .setPath("api/users/2")
            //set url params Key-Value or HashMap
            .setUrlParams("KEY","Value")
            .setResponseHandler(GetResponseModel::class.java,
                object : ResponseHandler<GetResponseModel>() {
                    override fun onSuccess(response: Response<GetResponseModel>) {
                        super.onSuccess(response)
                        //handle response
                    }
                }).run(this)

अधिक जानकारी के लिए दस्तावेज़ीकरण देखें


2

रिट्रोफिट (MVVM) में प्राप्त करें और पोस्ट विधि के साथ गतिशील URL

रेट्रोफ़िट सेवा इंटरफ़ेस:

public interface NetworkAPIServices {

@POST()
Observable<JsonElement> executXYZServiceAPI(@Url String url,@Body AuthTokenRequestModel param);


@GET
Observable<JsonElement> executeInserInfo(@Url String url);

MVVM सेवा वर्ग:

   public Observable<JsonElement> executXYZServiceAPI(ModelObject object) {
    return networkAPIServices.authenticateAPI("url",
            object);
}

 public Observable<JsonElement> executeInserInfo(String ID) {
    return networkAPIServices.getBank(DynamicAPIPath.mergeUrlPath("url"+ID)));
}

और रेट्रोफिट क्लाइंट क्लास

 @Provides
@Singleton
@Inject
@Named("provideRetrofit2")
Retrofit provideRetrofit(@Named("provideRetrofit2") Gson gson, @Named("provideRetrofit2") OkHttpClient okHttpClient) {


   builder = new Retrofit.Builder();
    if (BaseApplication.getInstance().getApplicationMode() == ApplicationMode.DEVELOPMENT) {
        builder.baseUrl(NetworkURLs.BASE_URL_UAT);
    } else {
        builder.baseUrl(NetworkURLs.BASE_URL_PRODUCTION);
    }


    builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
    builder.client(okHttpClient);
    builder.addConverterFactory(GsonConverterFactory.create(gson));


    return builder.build();
}

उदाहरण के लिए यह url है: https://gethelp.wildapricot.com/en/articles/549-changing-your

आधार: https://gethelp.wildapricot.com

शेष @ @: / en / लेख / 549-बदलते-आपके (जो आप रेट्रो सर्विस क्लास में पास हैं)


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

यदि आपके पास पहले से ही अपना कोड सेटअप है और आप अलग-अलग इंटरफेस पर बदलाव नहीं करना चाहते हैं, तो इस लिंक में वर्णित समाधान का उपयोग करें । मुख्य बिंदु वह विधि changeApiBaseUrlहै जो URL को अपडेट करती है और रेट्रोफिट बिल्डर को फिर से बनाती है।

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
// ...
}

आप इसका उपयोग इस प्रकार कर सकते हैं:

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);
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.