Retrofit: multiple query parameters in #GET - java

I have problem with multiple parameters in #GET. If I have two, everything is working fine, but if I have three (i need three) it skipping onResponse method and onFailure is executed. Does anyone know why?
This is interface
#GET("CalendarJson")
Call<List<Raspored>> getKalendar(
#Query("department") String department,
#Query("semester") String semester,
#Query("year") int year);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(basicUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
KalendarService kalendarService = retrofit.create(KalendarService.class);
And this is where I call it
KalendarService.kalendarService.getKalendar(department,semester,year).enqueue(new Callback<List<Raspored>>() {
#Override
public void onResponse(Call<List<Raspored>> call, Response<List<Raspored>> response) {
if(response.isSuccessful()){
raspored = response.body();
//TODO
}
}
#Override
public void onFailure(Call<List<Raspored>> call, Throwable t) {
Toast.makeText(getApplicationContext(), "Failure", Toast.LENGTH_SHORT).show();
}
});

I think it has to do with the datatype of your third parameter

Related

How to make a void method with Retrofit return string?

So, here is the method in my adapter. Later on, in onBindViewHolder() method I want to perform such action: String pic_url = showJustProduct(product_name);, but the onResponse method can`t return anything except void. What should I do to put img_url to pic_url?
public void showJustProduct(String title){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://url")
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.build();
JustJsonPlaceHolderApi jsonPlaceHolderApi = retrofit.create(JustJsonPlaceHolderApi.class);
Call<JustProducts> call = jsonPlaceHolderApi.getProducts(title);
call.enqueue(new Callback<JustProducts>() {
#SuppressLint("SetTextI18n")
#Override
public void onResponse(#NotNull Call<JustProducts> call, #NotNull Response<JustProducts> response) {
if (response.isSuccessful()) {
assert response.body() != null;
List<JustProduct> justproducts = response.body().getProducts();
JustProduct justProduct = justproducts.get(0);
String img_url = justProduct.getImage();
Log.e("1", "it works!");
}
}
#Override
public void onFailure(#NotNull Call<JustProducts> call, #NotNull Throwable t) {
Log.e("failure", Objects.requireNonNull(t.getLocalizedMessage()));
}
});
}
You can use synchronized call.execute() method instead of call.enqueue().
This can lead to NetworkOnMainThreadException. So be sure to execute it on background thread not UI thread.
Example:
Response<JustProducts> response = jsonPlaceHolderApi.getProducts(title).execute();
if (response.isSuccessful()) {
...
}

Get NMEA data type through Retrofit

I am wondering how can I get NMEA data type. It would be best if I could achieve this with Retrofit. The IP address of this data is http://213.73.2.250:5018. It looks like this: data
I have tried this with retrofit with this code:
public void getRestDataListRetrofit(final ViewMvpTextViewLocation viewMvpTextViewLocation) throws IOException {
Call<String> result = Api.getClient().getString();
result.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
viewMvpTextViewLocation.dismissProgressDialogWithSuccess(response.body());
}
#Override
public void onFailure(Call<String> call, Throwable t) {
viewMvpTextViewLocation.dismissProgressDialogWithError(call.request().toString() + " " + t.toString());
}
});
}
where Api class is
public class Api {
public static ApiInterface getClient() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://213.73.2.250:5018/")
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(ApiInterface.class);
}
}
and getString() method is
public interface ApiInterface {
#GET("/")
Call<String> getString();
}
When I click the button to receive this data I get with error: "unexpected status line: $GPGGA, (...) ". What is wrong with this code? Thanks in advance.
I did a workaround by parsing an error message that contains a text I wanted to have.

whenever i acces data from network using retrofit it works fine but in 2nd time can't find data through network using retrofit

I am trying to access data from the network (data is in the form of gson and i am using WordPress rest API) using retrofit but can't access. it shows me an error like data is null looks like retrofit can't find data but everything is good... looks like code is good and i don't know how to solve this. please help me I am a new developer.. it takes my 3 days
whenever i call getRetrofit() method it works fine... but when i call getImageRetrofit() then looks like this method won't work...this method return null value as shown in the logcat :
ImageInfo: info: null
private void getRetrofit() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitArrayApi service = retrofit.create(RetrofitArrayApi.class);
Call<List<WPPost>> call = service.getPostInfo();
call.enqueue(new Callback<List<WPPost>>() {
#Override
public void onResponse(Call<List<WPPost>> call, Response<List<WPPost>> response) {
Log.e("Latest","response: "+response.body());
for (int i=0; i<response.body().size(); i++)
{
Log.e("main ","title "+response.body().get(i).getTitle().getRendered() + " " +
response.body().get(i).getId() );
String tempDate = response.body().get(i).getDate();
tempDate = tempDate.replace("T"," ");
String tempImageHref = response.body().get(i).getLinks().getWpFeaturedmedia().get(0).getHref();
Log.e("Href", "onResponse: "+tempImageHref);
String link = response.body().get(i).getLink();
Log.e("PostLink",link);
getImageRetrofit(tempImageHref);
list.add(new LatestModel(
response.body().get(i).getTitle().getRendered(),
tempDate,
tempImageHref,
LatestModel.IMAGE_TYPE,
response.body().get(i).getLink()
)
);
}
adapter.notifyDataSetChanged();
}
#Override
public void onFailure(Call<List<WPPost>> call, Throwable t) {
t.printStackTrace();
}
});
}
private void getImageRetrofit(String ImageHref) {
Log.e("getImageRetrofit","called "+ImageHref);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitArrayApi service = retrofit.create(RetrofitArrayApi.class);
Call<List<WPPostImage>> callImage = service.getImageInfo(ImageHref);
callImage.enqueue(new Callback<List<WPPostImage>>() {
#Override
public void onResponse(Call<List<WPPostImage>> call, Response<List<WPPostImage>> response) {
Log.e("ImageInfo","info: "+response.body());
}
#Override
public void onFailure(Call<List<WPPostImage>> call, Throwable t) {
Log.e("Link Failed: ",": t.printStackTrace()" );
}
});
}
here is my RetrofitArrayApi Interface.:
public interface RetrofitArrayApi {
#GET("wp-json/wp/v2/posts?per_page=4")
Call<List<WPPost>> getPostInfo();
#GET("{id}")
Call<List<WPPostImage>> getImageInfo(#Path("id") String ImageHref); }
You said at comments that temImageHref: mubashirsaddique.com/wp-json/wp/v2/media/1780 and also your base url is baseUrl = "mubashirsaddique.com". So you send a request to this address mubashirsaddique.com/mubashirsaddique.com/wp-json/wp/v2/media/1780 when call getImageInfo.
Change your getPostInfo service. It should return just id(1780 in your case) as href value and modify RetrofitArrayApi.
#GET("wp-json/wp/v2/media/{id}")
Call<List<WPPostImage>> getImageInfo(#Path("id") String ImageHref);

I get data using retrofit with post request give message Internal server error

I am using retrofit library with post request, but i did not found data. Give "Internal server error" message.
API_1 : http://www.fabgrad.com/dummy_api_1/
type : POST
data : { us_id:23 }
interface -
public interface FirstApi {
public static String URl = "http://www.fabgrad.com/";
#FormUrlEncoded
#POST("dummy_api_1")
Call<Titles> getData(#Field("us_id") String id);
}
Using retrofi in main activity -
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(FirstApi.URl)
.addConverterFactory(GsonConverterFactory.create())
.build();
FirstApi categoryMenuApi = retrofit.create(FirstApi.class);
String s="23";
Call<Titles> categoryMenuCall = categoryMenuApi.getData(s);
categoryMenuCall.enqueue(new Callback<Titles>() {
#Override
public void onResponse(Call<Titles> call, Response<Titles> response) {
Titles list = response.body();
}
#Override
public void onFailure(Call<Titles> call, Throwable t) {
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
I am new in retrofit So please help
You only have to add / at the end of your endpoint #POST("dummy_api_1")
Just like:
#POST("dummy_api_1/")

How to get string response from Retrofit2?

I am doing android, looking for a way to do a super basic http GET/POST request. I keep getting an error:
java.lang.IllegalArgumentException: Unable to create converter for class java.lang.String
Webservice:
public interface WebService {
#GET("/projects")
Call<String> jquery();
}
then in my java:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://jquery.org")
// .addConverterFactory(GsonConverterFactory.create())
.build();
WebService service = retrofit.create(WebService.class);
Call<String> signin = service.jquery();
Toast.makeText(this, signin.toString(), Toast.LENGTH_LONG).show();
I'm literally just trying to query jquery.org/projects with a GET request and return the String that it responds with. What is wrong?
If I try to implement a custom Converter (I've found a few examples online) it complains that I didn't implement the abstract method convert(F), which none of the examples do.
Thanks.
Add Retrofit2 and ScalarsConverterFactory to your Retrofit.Builder.
adapterBuilder = new Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create());
To use ScalarsCoverter add following dependency to your build graddle
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0' //Adding Retrofit2
For API Call use:
Call <String> *****
Android Code :
.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
Log.i("Response", response.body().toString());
//Toast.makeText()
if (response.isSuccessful()){
if (response.body() != null){
Log.i("onSuccess", response.body().toString());
}else{
Log.i("onEmptyResponse", "Returned empty response");//Toast.makeText(getContext(),"Nothing returned",Toast.LENGTH_LONG).show();
}
}
I take a look at Retrofit library and noticed that it parses response according to the type class inside Call<T>. So you have two option:
1st: create a class according to the response from the server.
2nd: get the response and handle it yourself (Not recommended Retrofit already handles it. So why do you use Retrofit as it is tailored for this job). Anyway instead of Call<String> use Call<ResponseBody> and Call<ResponseBody> signin = service.jquery(); after this put the following
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Response<ResponseBody> response, Retrofit retrofit) {
// handle success
String result = response.body().string();
}
#Override
public void onFailure(Throwable t) {
// handle failure
}
});
To get the response as a String, you have to write a converter and pass it when initializing Retrofit.
Here are the steps.
Initializing retrofit.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL_BASE)
.addConverterFactory(new ToStringConverterFactory())
.build();
return retrofit.create(serviceClass);
Converter class for converting Retrofit's ResponseBody to String
public class ToStringConverterFactory extends Converter.Factory {
private static final MediaType MEDIA_TYPE = MediaType.parse("text/plain");
#Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (String.class.equals(type)) {
return new Converter<ResponseBody, String>() {
#Override
public String convert(ResponseBody value) throws IOException
{
return value.string();
}
};
}
return null;
}
#Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations,
Annotation[] methodAnnotations, Retrofit retrofit) {
if (String.class.equals(type)) {
return new Converter<String, RequestBody>() {
#Override
public RequestBody convert(String value) throws IOException {
return RequestBody.create(MEDIA_TYPE, value);
}
};
}
return null;
}
}
And after executing service.jquery();, signin will contain JSON response.
You can try the following:
build.gradle file:
dependencies {
...
compile 'com.squareup.retrofit2:retrofit:2.0.1'
...
}
WebAPIService:
#GET("/api/values")
Call<String> getValues();
Activity file:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL_BASE)
.build();
WebAPIService service = retrofit.create(WebAPIService.class);
Call<String> stringCall = service.getValues();
stringCall.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
Log.i(LOG_TAG, response.body());
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.e(LOG_TAG, t.getMessage());
}
});
I have tested with my Web serivce (ASP.Net WebAPI):
public class ValuesController : ApiController
{
public string Get()
{
return "value1";
}
}
Android Logcat out: 04-11 15:17:05.316 23097-23097/com.example.multipartretrofit I/AsyncRetrofit2: value1
Hope it helps!
call.enqueue(new Callback<Object>() {
#Override
public void onResponse(#NonNull Call<Object> call, #NonNull Response<Object> response) {
if (response.isSuccessful()) {
Gson gson = new Gson();
String successResponse = gson.toJson(response.body());
Log.d(LOG_TAG, "successResponse: " + successResponse);
} else {
try {
if (null != response.errorBody()) {
String errorResponse = response.errorBody().string();
Log.d(LOG_TAG, "errorResponse: " + errorResponse);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(#NonNull Call<Object> call, #NonNull Throwable t) {
}
});
Just use log level BODY in intercepror:
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()....
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
clientBuilder.addNetworkInterceptor(httpLoggingInterceptor);
And you can see body in logcat like:
D/OkHttp: {"blablabla":1,.... }
D/OkHttp: <-- END HTTP (1756-byte body)
This solution for debug only, not for get String directly in code.
thought it might be late to answer just use response.body()?.string() and you'll have your response as a string.
I change the Response type, instead of adding ScalarsConverterFactory like this
interface YourApiService {
#GET("/endpoint")
fun getResponse(): Call<ResponseBody>
}
And then you can get the string object by
val str = response.body().toString()
String body = new String(((TypedByteArray) response.getBody()).getBytes());
if you found
java.lang.ClassCastException: retrofit.client.UrlConnectionClient$TypedInputStream cannot be cast to retrofit.mime.TypedByteArray
then put this in your RestAdapter
.setLogLevel(RestAdapter.LogLevel.FULL)
for Example:
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(Root_url)
.build();

Categories

Resources