how to pass the value of parameter in android retrofit - java

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

Related

How to get String in response using Retrofit 2?

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

Retrofit 2 API Can I use local file path or json string instead of url?

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.

Retrofit: Unable to create #Body converter for class

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,
)

Prevent retrofit from encoding my http request body

I'm trying to pass a string of the format below as the body of a http post request.
param1=PARAM1&param2=PARAM2&param3=PARAM3
But retrofit encodes my body so that = becomes \u003d and & becomes \u0026. And I end up with a string which actually looks like this:
param1\u003dPARAM1\u0026param2\u003dPARAM2\u0026param3\u003dPARAM3
How can I prevent that?
My retrofit rest api is defined as follows.
public interface RestAPI {
#POST("/oauth/token")
public void getAccessToken(#Body String requestBody, Callback<Response> response);
}
If you have a serialized class (like a HashMap) in the request body and you want to prevent encoding that (like in vezikon's and my problem), you can create a custom Gson with disabled escaping using:
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
Pass this converter to your rest adapter:
yourRestAdapter = new RestAdapter.Builder()
.setEndpoint(.....)
.setClient(.....)
.setConverter(new GsonConverter(gson))
.build();
This way the "=" characters in the post body stay intact while submitting.
To answer the question directly, you can use TypedString as the method parameter type. The reason the value is being changed is because Retrofit is handing the String to Gson in order to encode as JSON. Using TypedString or any TypedOutput subclass will prevent this behavior, basically telling Retrofit you will handle creating the direct request body yourself.
However, that format of payload is called form URL encoding. Retrofit has native support for it. Your method declaration should actually look like this:
#FormUrlEncoded
#POST("/oauth/token")
void getAccessToken(
#Field("param1") String param1,
#Field("param2") String param2,
#Field("param3") String param3,
Callback<Response> callback);
Using Kotlin
For Retrofit 2 you can initialize retrofit with a Gson converter factory.
val builder = GsonBuilder().disableHtmlEscaping().create()
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(builder))
.client(monoOkHttpClient())
.build()
This builder should remove escaping from your json output.
Gradle file dependencies:
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.1.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
This issue can be fixed with below workaround.
#POST("yourString")
Call<YourResponseModel> yourCallMethod(#Query("yourKey") String yourValue,
#Query("yourKey") String yourValue,
#Query("yourKey") String yourValue);
Note : Don't use "#FormUrlEncoded" for this case.
Reference Here - https://github.com/square/retrofit/issues/1407

How to use retrofit library

I have downloaded the retrofit library and samples from https://github.com/square/retrofit.I want to do image and data caching.
But I am not getting how to use that in android.Can Somebody give me an example.I have checked the code
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer("")
.build();
ClientInterface service = restAdapter.create(ClientInterface.class);
Callback callback = new Callback() {
#Override
public void success(Object o, Response response) {
// Read response here
}
#Override
public void failure(RetrofitError retrofitError) {
// Catch error here
} };
service.findBuffet("sudhakar", callback);
But I am not getting anything.
Thanks for the help in advance...
You have to create an interface like below.
public interface MyService {
#GET("/getUser/{user}")
User getUserDetails(#Path("user") String userId);
}
Create your rest adapter
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("https://mybaseurl.com")
.build();
MyService service = restAdapter.create(MyService.class);
Get user details like this:
User user = service.getUserDetails("123456");
To get a successful result you have to define your pojos correctly.
You can use this link to create your pojos : http://www.jsonschema2pojo.org/
Retrofit is best to use. follow are the steps to use retrofit.
Please get details process here
Step 1- add dependency
Step 2 - init retrofit and add wrapper functions to call interface
Step 3 - Create POJO model using any online jsoneditor like jsoneditor.org
Step 4 - Create interface (URL from where you want to fetch date)
Step 5 - Call wrapper function from activity.

Categories

Resources