Retrofit returns 404 respone code - android

ApiClient.java class -
public class ApiClient {
public static final String BASE_URL = "https://jsonplaceholder.typicode.com/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
Interface -
public interface ApiInterface {
#POST("posts/1")
Call<ModelClass> savePost();
}
In onCreate of activity -
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<ModelClass> call = apiService.savePost();
call.enqueue(new Callback<ModelClass>() {
#Override
public void onResponse(Call<ModelClass>call, Response<ModelClass> response) {
Log.i(TAG,"response is "+response.body());
Log.i(TAG,"response code is "+response.code());
}
#Override
public void onFailure(Call<ModelClass>call, Throwable t) {
// Log error here since request failed
Log.i(TAG, t.toString());
}
});
Dependencies which I included in Gradle -
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
why retrofit returns 404 response code.Is there any problem with the above code?
Thanks in advance.

Bro your code is fine problem is with api.
When i hit your api in post method on POSTMAN its showing 404 Not Found so please check your server
But its not showing the empty json object as body so maybe there are parameters missing and you are using 404 status for showing this which is a bad practice show 404 only when this api doesnt exist and use other error codes like 409,422 for this type of action so you are more clear about response

What you should check if the endpoint is correct , or the url I had the same problem my BASE_URL was right but the endpoint not then I I was getting the 404 error.
Hope this helps .

You can check in the postman for status server.
Usually there is response in the body but the status maybe still 404, so it will be errorbody not response.body.

Related

How i change the retrofit URL at runtime

I need change the URL base in retrofit, i'm using koin to create a retrofit module on app startup and i want change this url in runtime.
I already tried change the baseUrl("http://192.168.192.168/") to baseUrl("http://")and change the url on retrofit call but my app crashs and return illegal URL error.
This is my fun to create the builder
fun createRetrofit(okHttpClient: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl("http://192.168.192.168/")//i need change this at runtime
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
}
create a bean to my module
val retrofitModule: Module = applicationContext {
bean { createRetrofit(get()) }
}
and start the koin:
startKoin(application = this,
modules = listOf(retrofitModule, ...)
)
someone can i help me with this?
you must have to add these lines in your code:
First Step:
Add the new CallAdapter RxJavaCallAdapterFactory.create() when building a Retrofit instance.
public static final String BASE_URL = "http://google.com/";
public static Retrofit getClient(String baseUrl) {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
Next step:
Update the APIService for example:-> savePost(String title, String body, String userId) method to become an Observable.
public interface APIService {
#GET
Call<ResponseBody> list(#Url String url);
//or
#POST("/posts")
#FormUrlEncoded
Observable<Post> savePost(#Field("title") String title,
#Field("body") String body,
#Field("userId") long userId);
}
Final step:
When making the requests, our anonymous subscriber responds to the observable's stream which emits event.
public void sendPost(String title, String body) {
// RxJava
mAPIService.savePost(title, body, 1).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Post>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(Post post) {
showResponse(post.toString());
}
});
}
this is way you build your dynamic urls: want to learn more details full description link: Sending Data With Retrofit 2 HTTP Client for Android
and See base URL for details of how the value will be resolved against a base URL to create the full endpoint URL.
if you are doing using kotlin: follow this link. dynamic urls at Runtime with Retrofit 2
I already tried change the baseUrl("http://192.168.192.168/") to baseUrl("http://")and change the url on retrofit call but my app crashs and return illegal URL error.
You can leave it as a baseUrl if you use #URL it will overwrite the one on yout Retrofit.Builder()
You can use #URL parameter to change the endpoint dynamically.
#GET
fun getUsers(#Url String url) : Observable<UserResponse>

How to get the request URL for a Retrofit object?

I need to log the request URL that Retrofit creates. I don't find any getter methods on Retrofit object or web interface that is generated via Retrofit. The following is my code, where I want to log the address of every request:
public void onRequestFoods() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Const.BASE_LOCAL)
.addConverterFactory(GsonConverterFactory.create())
.build();
FoodOrderInterface foodInterface = retrofit.create(FoodOrderInterface.class);
Log.d(TAG, "onRequestFoods: request url: ");
foodInterface.listFoods().enqueue(new Callback<FoodResponse>() {
#Override
public void onResponse(Call<FoodResponse> call, Response<FoodResponse> response) {
List<Food> foods = response.body().getBody().getFoods();
mPresenter.onResponse((ArrayList<Food>) foods);
}
#Override
public void onFailure(Call<FoodResponse> call, Throwable t) {
mPresenter.onRequestFailed(t.getMessage());
}
});
}
I think what you need is http logging interceptor the github repo has a straightforward example of how to get it up and running

Retrofit 2 : End of input at line 1 column 1 path $

Have made a thorough searching to this particular problem but while implementing answers under each question I encountered, am still getting the same output:
End of input at line 1 column 1 path $
I perfomed my Request on PostMan and I got expected output:
Here is the Screenshot of the Postman Request
Interfaces
#POST(Constant.API_REQUEST)
Observable<ServerResponse> postToWinnersList(#Body ServerRequest serverRequest);
ApiClient
public class ApiClient {
public static Retrofit retrofit;
private static OkHttpClient.Builder okHttpClientBuilder;
private static HttpLoggingInterceptor loggingInterceptor;
public static Retrofit getApiClient(){
if (retrofit == null){
// create instance of Httpclient
okHttpClientBuilder = new OkHttpClient.Builder();
loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
if(BuildConfig.DEBUG){
okHttpClientBuilder.addInterceptor(loggingInterceptor);
}
// instance of retrofit
retrofit = new Retrofit.Builder().baseUrl(Constant.BASE_URL).
addCallAdapterFactory(RxJava2CallAdapterFactory.create()).
addConverterFactory(GsonConverterFactory.create())
.client(okHttpClientBuilder.build())
.build();
}
return retrofit;
}
}
Retrofit/RxJava Request Code:
Observable<ServerResponse> response = apiInterface.postToWinnersList(serverRequest);
response.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribeWith(new DisposableObserver<ServerResponse>() {
#Override
public void onNext(ServerResponse serverResponse) {
AVLoadingIndicatorView1.setVisibility(View.GONE);
txtSubmitWinner.setVisibility(View.VISIBLE);
}
#Override
public void onError(Throwable e) {
AVLoadingIndicatorView1.setVisibility(View.GONE);
txtSubmitWinner.setVisibility(View.VISIBLE);
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
#Override
public void onComplete() {
showShortMsg(getString(R.string.submit_success));
}
});
Kindly help, thanks in Advance.
You can get this error when you are expecting an object in the response, but the API doesn't return anything other than result codes (200,...). Options:
- Check that the API really returns a ServerResponse.
- If you don't really need it to return anything, use Observable<Response<Void>> instead of Observable<ServerResponse>
You only get that error when something is wrong with your json response, Check again to make sure both the error response and correct response are well formatted.
Enter wrong credentials using postman and see what the output looks like.
Not sure but I think in Constant.API_REQUEST you are not appending "/".Let me know if it is right.
ex.#POST("index.php") // wrong
#POST("/index.php") //correct way
This error happens when an answer is void.
To correct this error make sure that in the return of the request there will be void.
Eg.
Interface whit kotlin
#POST("endPoint/")
fun relatarProblema(#Body serverRequest: ServerRequest ): Call<Void>
Don't forget to override the return type in the api call.
example whit Kotlin
call.enqueue (object: Callback <Void> {
override fun onResponse(call: Call<Void>, response: Response<Void>) {
}
override fun onFailure(call: Call<Void>, t: Throwable) {
}
})
When I used Coroutines what helped was to basically not return anything from the method:
#GET
#Headers("X-Requested-With:XMLHttpRequest")
suspend fun methodCall(
#Url url: String
)
I was getting the same exception yesterday and figured out that I was using a LogOutResponse data class as the expected response for the API, but then I got to know that the API doesn't return any JSON response corresponding to that data class, in fact, it didn't return anything in the body and only returned result code (200,300,400, etc). So I changed my implementation from:
#POST("logout")
suspend fun logout(): LogOutResponse
to
#POST("logout")
suspend fun logout(): Response<Unit>
Earlier retrofit tried to parse a JSON response at line 1 when there was no JSON there, that's why it threw that exception.
After the changes, the code worked fine as Response is a default retrofit class and Unit type inside it is of void type meaning we don't expect anything in return (no JSON body in response).

Retrofit is not making api call

I'm using retrofit 2 to make api call to my server but it get stucked when trying to make api call. This is my code
public interface GOTApi {
#GET("characters.json")
Call<GOTCharacterResponse> getCharacters();
}
Intermediate class to get the data
public class GOTCharacterResponse {
List<GOTCharacter> characters;
}
My class to make api call
public class GOTService {
public static final String BASE_URL = "https://project-8424324399725905479.firebaseio.com/";
public static GOTApi getGOTApi(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(GOTApi.class);
}
public static void getCharacters(){
getGOTApi().getCharacters().enqueue(new Callback<GOTCharacterResponse>() {
#Override
public void onResponse(Call<GOTCharacterResponse> call, Response<GOTCharacterResponse> response) {
if(response.isSuccessful()){
}
}
#Override
public void onFailure(Call<GOTCharacterResponse> call, Throwable t) {
int a = 0;
}
});
}
}
These are the libraries I'm using
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
compile 'com.squareup.okhttp3:okhttp:3.3.1'
It always get stucked in the getCharacters() method. Of course I have internet permission set in Mainfest.
You may try using Retrofit2 with RxJava, it is more convenient.
public Retrofit providedRetrofit(OkHttpClient okHttpClient){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
return retrofit;
}
Your API interface will look like
public interface Api {
#GET("api/service/schedule/{filial}")
Observable<Response<GOTCharacter>> getSchedule(#Path("some_param") String param);
}
You also need to parse response from JSON. You didn't provided
GOTCharacter class, but you can create code from json response by using
http://www.jsonschema2pojo.org/ service
I think you are implementing wrong onResponse() OR Callback(), because I am using Retrofit 2 too, in which onResponse() looks like this:
#Override
public void onResponse(Response<ListJsonResponseRestaurant> response, Retrofit retrofit) {
...
...
}

How to handle No Network connection using Retrofit 2.0 in Android?

I am using Retrofit 2.0 library in my android application by adding it into build.gradle file
// retrofit, gson
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
related code is given below
ApiInterface.java
public interface ApiInterface {
#GET("contacts/")
Call<ContactsModel> getContactsList();
}
ApiClient.java
public class ApiClient {
public static final String BASE_URL = "http://myexamplebaseurl/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
MainActivity.java
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<ContactsModel> call = apiService.getContactsList();
call.enqueue(new Callback<ContactsModel>() {
#Override
public void onResponse(Call<ContactsModel> call, Response<ContactsModel> response) {
if(response.isSuccessful()){
/*here is my data handling*/
}
}
#Override
public void onFailure(Call<ContactsModel> call, Throwable t) {
/*It is the request failure case,
I want to differentiate Request timeout, no internet connection and any other reason behind the request failure
*/
}
});
if we get status code as 4xx or 5xx even though onResponse() will called, so there we need handle that condition also.
Here my question is, How to differentiate reason for request failure i.e onFailure() by using Retrofit 2.0 in Android?
Here my question is, How to differentiate reason for request failure
by using Retrofit 2.0 in Android?
if you have a 4xx or 5xx error, onResponse is still called. There you have to check the response code of the code to check if everything was fine. E.g
if (response.code() < 400) {
in case of No Network connection, onFailure is called. There you could check the instance of the throwable. Typically an IOException

Categories

Resources