• 15
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

Add Header Parameter in Retrofit

I'm trying to call an API which requires me to pass in an API key.

My Service call using HttpURLConnection is working perfectly.

url = new URL("https://developers.zomato.com/api/v2.1/search?entity_id=3&entity_type=city&q=" + params[0]);
        urlConnection = (HttpURLConnection) url.openConnection();

        urlConnection.setRequestProperty("user-key","9900a9720d31dfd5fdb4352700c");

        if (urlConnection.getResponseCode() != 200) {
            Toast.makeText(con, "url connection response not 200 | " + urlConnection.getResponseCode(), Toast.LENGTH_SHORT).show();
            Log.d("jamian", "url connection response not 200 | " + urlConnection.getResponseCode());
            throw new RuntimeException("Failed : HTTP error code : " + urlConnection.getResponseCode());
        }

However, I'm not sure how this works with RetroFit as my call in going into Failure at all times. Heres the code I'm using for the same service call

 @GET("search")
Call<String> getRestaurantsBySearch(@Query("entity_id") String entity_id, @Query("entity_type") String entity_type, @Query("q") String query,@Header("Accept") String accept, @Header("user-key") String userkey);

and I'm using this to call it

Call<String> call = endpoint.getRestaurantsBySearch("3","city","mumbai","application/json","9900a9720d31dfd5fdb4352700c");

All these calls are going into the OnFailure Method in RetroFit. If I send it without the HeaderParameters it goes into Success with a 403 because I obviously need to pass the api key somewhere but I cant figure out how.

@GET("search")
Call<String> getRestaurantsBySearch(@Query("entity_id") String entity_id, @Query("entity_type") String entity_type, @Query("q") String query);

The error I'm getting in OnFailure is

java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 2 path $

You can use the below

 @Headers("user-key: 9900a9720d31dfd5fdb4352700c")
 @GET("api/v2.1/search")
 Call<String> getRestaurantsBySearch(@Query("entity_id") String entity_id, @Query("entity_type") String entity_type, @Query("q") String query);

and

 Call<String> call = endpoint.getRestaurantsBySearch("3","city","cafes");

The above is based in the zomato api which is documented at

https://developers.zomato.com/documentation#!/restaurant/search

Thing to note is the end point change api/v2.1/search and the Header @Headers("user-key: 9900a9720d31dfd5fdb4352700c").

Also check your base url .baseUrl("https://developers.zomato.com/")

Also i tried the above with a api key i generated and it works and my query was cafes as suggested the zomato documentation.

Note : I hope you have the below

 .addConverterFactory(ScalarsConverterFactory.create()) // for string conversion
 .build();

and the below in build.gradle file

compile group: 'com.squareup.retrofit2', name: 'converter-scalars', version: '2.2.0'

Edit:

You can also pass header with dynamic value as below

@GET("api/v2.1/search")
Call<String> getRestaurantsBySearch(@Query("entity_id") String entity_id, @Query("entity_type") String entity_type, @Query("q") String query,@Header("user-key") String userkey);

And

Call<String> call = endpoint.getRestaurantsBySearch("3","city","cafes","9900a9720d31dfd5fdb4352700c");
  • 44
Reply Report

Try this type header for Retrofit 1.9 and 2.0. For Json Content Type.

@Headers({"Accept: application/json"})
@POST("user/classes")
Call<playlist> addToPlaylist(@Body PlaylistParm parm);

You can add many more headers i.e

@Headers({
        "Accept: application/json",
        "User-Agent: Your-App-Name",
        "Cache-Control: max-age=640000"
    })

Dynamically Add to headers:

@POST("user/classes")
Call<ResponseModel> addToPlaylist(@Header("Content-Type") String content_type, @Body RequestModel req);

Call you method i.e

mAPI.addToPlayList("application/json", playListParam);

Or

Want to pass everytime then Create HttpClient object with http Interceptor:

OkHttpClient httpClient = new OkHttpClient();
        httpClient.networkInterceptors().add(new Interceptor() {
            @Override
            public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
                Request.Builder requestBuilder = chain.request().newBuilder();
                requestBuilder.header("Content-Type", "application/json");
                return chain.proceed(requestBuilder.build());
            }
        });

Then add to retrofit object

Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).client(httpClient).build();

UPDATE if you are using Kotlin remove the { } else it will not work

  • 41
Reply Report

After trying a couple of times i figured out the answer.

The error

java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 2 path $

was coming due the failure of parsing the json.

In the method call I was passing a String instead of a POJO class.

@Headers("user-key: 9900a9720d31dfd5fdb4352700c")
@GET("api/v2.1/search")
Call<String> getRestaurantsBySearch(@Query("entity_id") String entity_id, @Query("entity_type") String entity_type, @Query("q") String query);

I should have passed instead of Call<String> the type of Call<Data>

Data being the Pojo class

something like this

@Headers("user-key: 9900a9720d31dfd5fdb4352700c")
@GET("api/v2.1/search")
Call<Data> getRestaurantsBySearch(@Query("entity_id") String entity_id, @Query("entity_type") String entity_type, @Query("q") String query);
  • 6
Reply Report
      • 1
    • it depends on what type of converter you use. Gson converter for parsing json. or use scalar converter for string. Since you had not mentioned nay of those i had put a note in my answer. Call is possible

As far as i can see you are passing the data in a wrong way. Your method getRestaurantsBySearch is accepting the last two parameter as header field i.e accept and user-key. But while calling the method you are passing headers first. Pass the data as you have declared it in method signature of getRestaurantsBySearch

  • 0
Reply Report