Question Regarding "Retrofit"
i have an api like this listing/get_listings?listing_type=featured
in this api i have a parameter listing_type ... i am using it like this
#GET("listing/get_listings")
Call<List<ProviderModel>> getProviderListing(#Query("listing_type") String listing_type);
now i want to add the value of parameter like this:
RetrofitUtil.createProviderAPI().getProviderListing("featured").enqueue(getProviders(this));
but i am not getting response can any one help me how to solve the issue
add loginterceptor and check the issue
implementation 'com.squareup.okhttp3:logging-interceptor:3.3.1'
okhttp3.OkHttpClient.Builder client = new okhttp3.OkHttpClient.Builder();
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
client.addInterceptor(loggingInterceptor);
Retrofit retrofit = new Retrofit.Builder().baseUrl(OfflineApi.base_url).client(client.build()).addConverterFactory(GsonConverterFactory.create()).build();
I would like to understand how Retrofit works, but the official documentation is very weak.
I need to make a very simple GET request and get the response as a String.
Now I use standard HTTPUrlConnection and it works nicely, just request - response
Can anyone tell me how to get a String response without converting it to an object or something like that?
You can use ScalarsConverterFactory for strings and both primitives and their boxed types to text/plain bodies.
Add this dependency to your build.gradle file:
compile 'com.squareup.retrofit2:converter-scalars:2.1.0'
Try this:
public interface ExampleService {
#GET("/users/{user}/repos")
Call<String> listRepos(#Path("user") String user);
}
And add ScalarsConverterFactory to your builder:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.build();
You can then retrieve this string like this:
Call<String> call = exampleService.listRepos(user);
Response<String> response = call.execute();
String value = response.body();
Hello I am working on an Android App which uses retrofit API getting response from server. Retrofit Automatically parse the json response and creates objects of POJO class. I am storing that json into sqlite and if internet is not connected call the json from sqllite, facing difficulty have to parse json manually.
Is there any way I use retrofit library to parse json and make pojo from json string or file path?My code is here to fetch from url:
#FormUrlEncoded
#POST("getResponse")
Observable<UserResponse> getResponse(#Field("token") String token);
I want something like this if internet is not connected.
#FromStringEncoded
Observable<UserResponse> getResponseOffline(#Field("token") String token);
Thanks.
You don't mentioned proposes. I use below solution for mocking server in app on very early stage of development when real server doesn't work yet.
So you can use interceptors in OkHttp. Like this:
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(new MockClient(context));
and MockClient looks like this:
public class MockClient implements Interceptor {
Context context;
public MockClient(Context context) {
this.context = context;
}
#Override
public Response intercept(Chain chain) throws IOException {
HttpUrl url = chain.request().url();
Log.d("TAG","url="+url);
//here determine what to do base on url.
//e.g.:
switch(url.encodedPath()) {
case "some/path" :
String response = readJsonFieleFromAssestOrAnyOtherStorage();
return new Response.Builder()
.code(200)
.message(response)
.request(chain.request())
.protocol(Protocol.HTTP_1_1)
.body(ResponseBody.create(MediaType.parse("application/json"), response.getBytes()))
.addHeader("content-type", "application/json")
.build();
}
}
}
Simply use Google's GSON Library that allows you to convert json to POJO and vice versa. Fetch json from sqlite and parse it using gson.
Gson gson=new Gson();
UserResponse userResponse= gson.fromJson(jsonInStringFromDb,UserResponse.class);
You can also parse JSON from file using Gson.
JSON to Java object, read it from a file.
Gson gson = new Gson();
Staff staff = gson.fromJson(new FileReader("D:\\file.json"), Staff.class);
THere's no point in using it from the local filesystem- retrofit is for http requests. If you need to just parse JSON, use GSON or Jackson- those are the two libraries that RetroFit uses to parse json. Both libraries are fairly easy to use.
I need to send next json via retrofit 2:
{
"Inspection": {
"UUID": "name",
"ModifiedTime": "2016-03-09T01:13",
"CreatedTime": "2016-03-09T01:13",
"ReviewedWith": "name2",
"Type": 1,
"Project": {
"Id": 41
},
"ActionTypes": [1]
}
}
With Header: Authorization: access_token_value
I tried this:
//header parameter
String accessToken = Requests.getAccessToken();
JsonObject obj = new JsonObject();
JsonObject inspection = new JsonObject();
inspection.addProperty("UUID","name");
inspection.addProperty("ModifiedTime","2016-03-09T01:13");
inspection.addProperty("CreatedTime","2016-03-09T01:13");
inspection.addProperty("ReviewedWith","name2");
inspection.addProperty("Type","1");
JsonObject project = new JsonObject();
project.addProperty("Id", 41);
inspection.add("Project", project);
obj.add("Inspection", inspection);
Retrofit restAdapter = new Retrofit.Builder()
.baseUrl(Constants.ROOT_API_URL)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.build();
IConstructSecureAPI service = restAdapter.create(IConstructSecureAPI.class);
Call<JsonElement> result = service.addInspection(accessToken, obj);
JsonElement element = result.execute().body();
But everytime i recieved exception: java.lang.IllegalArgumentException: Unable to create #Body converter for class com.google.gson.JsonObject (parameter #2)
How can I send it ? Or any another idea how I can do it. You can even offer me with parameter as simple String with json inside. It will suit for me
Solution:
declare body value in your interface with next:
#Body RequestBody body
and wrap String JSON object:
RequestBody body = RequestBody.create(MediaType.parse("application/json"), obj.toString());
There is chance of you kept same #SerializedName("") for multiple vairable/fields/tags
You can specify a Converter when you create the Retrofit like this
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseurl)
.client(okHttpClient)
.build();
If this is due to #SerializedName make sure it is not dulplicated.
For e.g. This error will be thrown in below case: (Note: bookingId is passed twice)
#SerializedName(value="bookingId", alternate={"id", "bookingId"})
But, this is the correct:
#SerializedName(value="bookingId", alternate={"id", "someOtherId", "whateverId"})
Body uses a single request object, declare your request object as following
class Inspection {
String UUID;
//..... add your fields
Project project;
}
class Product
{
int Id;
//....... add your fields
}
I assume your service IConstructSecureAPI endpoint is:
#GET(...) // change based on your api GET/POST
Call<Response> addInspection(
#Header("Authorization") String accesstoken,
#Body Inspection request
);
and you can declare your desire Response.
Check this answer, it uses HashMap instead of class.
I kept getting this error when I upgraded to Java 17, still working fine on Java 11.
Here's what worked for me
To go deeper into the Exception I put a debug point in the Utils.java found in retrofit stack trace.
Doing so led me to the narrower cause being: java.lang.reflect.InaccessibleObjectException: Unable to make field private final byte java.time.LocalTime.hour accessible: module java.base does not "opens java.time" to unnamed module #35e2d654
Googling down further from here led me to https://github.com/mockk/mockk/issues/681#issuecomment-959646598 which in a nutshell suggests to add --add-opens java.base/java.time=ALL-UNNAMED as a JVM argument.
Boom, It worked.
In my case I simply forgot to apply the kotlinx.serialization plugin for Gradle, so no code for the serializers was generated. Fix it via:
plugins {
kotlin("plugin.serialization")
}
You can use an Interceptor to send Authorization Header in each request
class AuthorizationInterceptor implements Interceptor {
#Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
String authorizationToken = AuthenticationUtils.getToken();
Request authorizedRequest = originalRequest.newBuilder()
.header("Authorization", authorizationToken)
.build();
return chain.proceed(authorizedRequest);
}
}
I am using Moshi and Retrofit and my problem was I forgot to add #JsonSerializable annotation for the DTO class for #body.
you should add this annotation like this:
#JsonSerializable
data class RegisterDTO(
#field:Json(name = "device_id") val deviceId: String,
)
How do I pass Dynamic JSON file name using Retrofit
MainActivity.java:
final RestAdapter restadapter = new RestAdapter.Builder().setEndpoint("http://www.domain.com/").build();
api flowerapi = restadapter.create(api.class);
api.java:
public interface api {
#GET("/JSONS/flowers.json")
void getData(Callback<List<Flower>> response);
}
As you can see in my above code, I am using only single/one and only flowers.json
What If I would like to call dynamic json files based on some conditions, like in some cases I have to call flowers.json, in some cases roses.json and in some cases something.json
with the #Path annotation
#GET("/JSONS/{name}")
void getData(#Path("name") String name, Callback<List<Flower>> response);