Быстрый API-код ошибки 500 с Retrofit2 Android - PullRequest
0 голосов
/ 21 июня 2019

Я использую API spoonacular для проекта приложения с рецептами. Проблема возникает при попытке сделать несколько запросов GET к API. Первый запрос - это простой поиск с параметром запроса. Результирующий JSON первого запроса содержит идентификатор рецепта, и я использую этот идентификатор для выполнения второго запроса GET, где возникает проблема. API отвечает только тогда, когда я делаю запрос в первый раз, но после этого он отвечает кодом ошибки 500 [Внутренняя ошибка сервера].

Я проверил GET-запрос на Почтальоне, но там он каждый раз работает нормально. Я новичок в работе с API, и любая помощь будет очень признательна.

Это мой класс обслуживания по модернизации

общедоступный класс ServiceGenerator {

public static final String API_BASE_URL = "https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/";

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

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

private static Retrofit retrofit = builder.build();

public static <S> S createService(Class<S> serviceClass, final String HostName, final String KeyVal)
{
    if (!TextUtils.isEmpty(HostName) && !TextUtils.isEmpty(KeyVal))
    {
        HeadersInterceptor interceptor = new HeadersInterceptor(HostName,KeyVal);

        if (!httpClient.interceptors().contains(interceptor))
        {
            httpClient.addInterceptor(interceptor);
            builder.client(httpClient.build());
            retrofit = builder.build();
        }
    }

    return retrofit.create(serviceClass);
}

Это перехватчик, который я использую для добавления заголовков с запросом.

открытый класс HeadersInterceptor реализует Interceptor {

private String HostName,KeyVal;

HeadersInterceptor(final String HostName,final String KeyVal) {
    this.HostName = HostName;
    this.KeyVal = KeyVal;
}

@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
    Request original = chain.request();

    Request.Builder builder = original.newBuilder()
            .addHeader("X-RapidAPI-Host",HostName)
            .addHeader("X-RapidAPI-Key",KeyVal);

    Request request = builder.build();
    return chain.proceed(request);
}

}

Это мой фрагмент, который выполняет поисковый запрос и УСПЕШНО возвращает результаты [Идентификатор квитанции]

открытый класс ListSelectedFragments extends Fragment {

private ProgressBar PreviewFragPrg;
private final String TAG = "ListSelectedFragment->";

private PreviewRecipeAdapter adapter;
private RecyclerView SelectedItemRV;
private ArrayList<RecipePreviewHolder> RecipePreviewsList = new ArrayList<>();

public ListSelectedFragments() {
    // Required empty public constructor
}


@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    final View view = inflater.inflate(R.layout.fragment_list_selected_fragments, container, false);
    SelectedItemRV = view.findViewById(R.id.SelectedItemRV);
    TextView DisplayNameTV = view.findViewById(R.id.DisplayNameTV);
    PreviewFragPrg = view.findViewById(R.id.PreviewFragPrg);
    ImageView BackBtn = view.findViewById(R.id.BackBtn);

    BackBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (getFragmentManager() != null) {
                getFragmentManager().popBackStackImmediate();
            }
        }
    });

    if (getArguments() != null) {
        final String QueryTag = getArguments().getString("QueryTag");
        final String CuisineName = getArguments().getString("CuisineName");

        if(CuisineName!=null){
            DisplayNameTV.setText(CuisineName);
        }
        if(QueryTag!=null){
            ProcessQuery(QueryTag);
        }
    }

    return view;
}

private void ProcessQuery(final String QueryStr){

    String hostname = getResources().getString(R.string.spoonacular_host_name);
    String key      = getResources().getString(R.string.spoonacular_apikey_val);


    final ServiceGenerator.GetDataService mService =
            ServiceGenerator.createService(ServiceGenerator.GetDataService.class, hostname,key);

    Call<RecipeInfoModel> call = mService.getRecipes(QueryStr);

    call.enqueue(new Callback<RecipeInfoModel>() {
        @Override
        public void onResponse(@NonNull Call<RecipeInfoModel> call,
                               @NonNull Response<RecipeInfoModel> response)
        {
            Log.d(TAG, "Request Response Received");
            Log.d(TAG, response.toString());

            if (response.body() != null) {
                Results[] mRES = response.body().getResults();
                SetUpRecipePreviews(mRES);
                PreviewFragPrg.setVisibility(View.GONE);
            }
        }

        @Override
        public void onFailure(@NonNull Call<RecipeInfoModel> call, @NonNull Throwable t) {
            Log.d(TAG, "Request Failed");
            Log.d(TAG, call.toString());
            Log.d(TAG, "Throwable ->" + t);
            PreviewFragPrg.setVisibility(View.GONE);
            Toast.makeText(getActivity(),"Could not get required recipes",Toast.LENGTH_SHORT).show();
        }
    });

    Log.d(TAG, "User Inputed Request\n"+call.request().url().toString());

}

private void SetUpRecipePreviews(final Results[] mRES) {

    RecipePreviewsList.clear();
    adapter = new PreviewRecipeAdapter(getActivity(),RecipePreviewsList);
    SelectedItemRV.setLayoutManager(new GridLayoutManager(getActivity(), 2));
    SelectedItemRV.setAdapter(adapter);

    for (Results mRE : mRES) {
        String ImgUrls = mRE.getImage();
        RecipePreviewHolder obj = new RecipePreviewHolder(Integer.valueOf(mRE.getId()),
                mRE.getTitle(), ImgUrls);
        Log.d("GlideLogs->","Rid->"+mRE.getId());
        Log.d("GlideLogs->","Img URL->"+ ImgUrls);
        Log.d("GlideLogs->","Name->"+mRE.getTitle());

        RecipePreviewsList.add(obj);
    }

    if(RecipePreviewsList.size()>1){
        adapter.notifyDataSetChanged();
    }
}

Это действие, к которому я перехожу из своего фрагмента после нажатия на карточку рецепта ... Отправка идентификатора рецепта в дополнениях. Эта функция вызывается сразу после получения преднамеренных дополнений.

private void RetrieveRecipeInfo (окончательный int recipeID) {

    String hostname = getResources().getString(R.string.spoonacular_host_name);
    String key   = getResources().getString(R.string.spoonacular_apikey_val);


    final ServiceGenerator.GetDataService mService =
            ServiceGenerator.createService(ServiceGenerator.GetDataService.class, hostname,key);

    Call<RecipeDetailedInfo> call = mService.getInformation(185071);
    Log.d(TAG , "Your GET Request:\n"+call.request().url().toString());

    call.enqueue(new Callback<RecipeDetailedInfo>() {
        @Override
        public void onResponse(@NonNull Call<RecipeDetailedInfo> call, @NonNull Response<RecipeDetailedInfo> response)
        {
            Log.d(TAG,"OnResponse()  Called\n");
            Log.d(TAG,"Response = "+ response);

            if(response.body()!=null) {
                String obj = response.body().getSourceUrl();
                Log.d(TAG,"Getting Recipe Info\n");
                Log.d(TAG, String.valueOf(obj));
            }
        }

        @Override
        public void onFailure(@NonNull Call<RecipeDetailedInfo> call, @NonNull Throwable t){
        }
    });
}

Используя почтальон, я получаю результаты каждый раз, но в моем приложении API перестает отвечать после первого запроса. Есть ли проблема с тем, как я включаю заголовки?

1 Ответ

1 голос
/ 22 июня 2019

Итак, наконец-то все заработало. Проблема была с HeadersInterceptor.java. Я использовал Interceptor для добавления заголовков к вызову, но я нашел гораздо более простой способ, и он работает как чудо.

Просто добавьте @Header с вызовом, чтобы добавить заголовки без перехватчика в Retrofit.

public interface GetDataService {
    @GET("recipes/complexSearch?")
    Call<RecipeInfoModel> getRecipes(
            @Header("X-RapidAPI-Host") String api,
            @Header("X-RapidAPI-Key") String apiKey,
            @Query("query") String query_str);
}
...