I try to call this Request with Retrofit
my code :
Map<String, String> parameters = new HashMap<>();
Clientn client = new Clientn();
final WaselJsonPlaceHolderApi apiService = client.getClient().create(WaselJsonPlaceHolderApi.class);
Call<TokenModel> call = apiService.getLoginToken( "password", "ec_user","EC_P#ssw0rd" , "0500344253", "1993");
call.enqueue(new Callback<TokenModel>() {
#Override
public void onResponse(Call<TokenModel> call, Response<TokenModel> response) {
Log.e("TAG-TAG", ""+response.errorBody());
Log.e("TAG-TAG", ""+response.body());
}
#Override
public void onFailure(Call<TokenModel> call, Throwable t) {
}
});
the Interface :
#FormUrlEncoded
#POST("api/CustomerAccount/LoginUserByMobile")
Call<TokenModel> getLoginToken( #Field("grant_type") String title,
#Field("app_username") String body,
#Field("app_password") String password,
#Field("mobile_number") String userId,
#Field("ver_code") String code );
the Client
public class Clientn {
public static final String BASE_URL = "http://192.168.1.230/MagicWord.ECommercPlatform.API/";
public static Retrofit retrofit = null;
public static Retrofit getClient(){
if (retrofit == null){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
but i get the null response and the ErrorBody is E/TAG-TAG: okhttp3.ResponseBody$1#aa2472e
I think android stopped response for normal http in latest API(29), You can try with https and check the same issue is coming or not.
i think the issue is in your "ver_code which is int or use are taking string.is it string or int?
onFailure callback could be very useful, try to add t.printStacktrace() on it.
Also, don't pass an object as is with a string on Log, because it will just print an address that you don't need.
Keep field name and variable name same
Example:
#Field("grant_type") String grant_type, #Field("app_username") String app_username,#Field("app_password") app_password
so that you cannot get confused.
I think the request method should be POST
Because in code the request method is POST but in screenshot the request method is GET
Related
I am using a REST API created by me using SpringBoot.When I tried tested using Postman I am getting a valid JSON,but Retrofit causes this issue.
I have checked the ModelClass and it is not causing an issue.
I have other POST methods which are working absolutely fine but an issue is occuring with GET method.
The Retrofit is as follows:
public class RetrofitService {
static Gson gson = new GsonBuilder()
.setLenient()
.create();
static OkHttpClient client = new OkHttpClient();
//addConverterFactory(GsonConverterFactory.create(gson))
private static Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://Location/api/v1/")
.client(client)
//.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
public static Retrofit createService() {
return retrofit;
}
}
The Repository is:
public class HomeFragRepository {
private Networking networking;
private MutableLiveData<EmployeeClass> mutableUserDetails;
public HomeFragRepository() {
networking= RetrofitService.createService().create(Networking.class);
}
public MutableLiveData<EmployeeClass> getUserHomeDetails(Long userId){
mutableUserDetails=new MutableLiveData<>();
networking.employeeHomeDetails(userId).enqueue(new Callback<EmployeeClass>() {
#Override
public void onResponse(Call<EmployeeClass> call, Response<EmployeeClass> response) {
if(response.isSuccessful()){
Log.i("Response",response.body().toString());
mutableUserDetails.setValue(response.body());
}
else{
try {
EmployeeClass employeeClass=new Gson().fromJson(response.errorBody().string(),
EmployeeClass.class);
Log.i("HelloLogin",employeeClass.getMessage());
mutableUserDetails.setValue(employeeClass);
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<EmployeeClass> call, Throwable t) {
t.printStackTrace();
}
});
return mutableUserDetails;
}
}
The Employee Model Class is same in Spring and Android so it is not causing any issue.
The GET Method in Spring is:
#RequestMapping(value = "/employee", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<EmployeeClass> getEmployee(#RequestParam(value="userId") Long userId){
EmployeeClass employeeClass=attendanceService.searchEmployee(userId);
return new ResponseEntity<>(employeeClass,HttpStatus.valueOf(employeeClass.getStatus()));
}
This is somehow producing a String instead of a JSON.
Thanks in Advance.
This usually happens when you're receiving something other than the expected response from the server.
It because because you mentioned EmployeeClass in Call so what happens is
the object block in your json response has no name so it is unable to find the object...
try to use
#RequestMapping(value = "/employee", method = RequestMethod.GET, produces =
MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseBody> getEmployee(#RequestParam(value="userId")
Long userId){
EmployeeClass employeeClass=attendanceService.searchEmployee(userId);
return new ResponseEntity<>
(employeeClass,HttpStatus.valueOf(employeeClass.getStatus()));
}
then parse json manually to get data and save it in your model
or you can try to add #Headers({"Accept: application/json"}) in Retrofit interface see if it works
#Headers({"Accept: application/json"})
I am trying to update databse record using Retrofit library. The postman works fine with same data. GET data is also working fine but PATCH operation is returning Error 500 Internal server error.
Interface:
//#Headers("Content-Type: application/json")
#PATCH("usersapi/{id}")
Call<UserBank> updateUserBank(#Path("id") int id, #Body UserBank post);
Main activity:
retrofit = new Retrofit.Builder()
.baseUrl("https://<website>/api/")
// .addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
jsonCofyBizApi = retrofit.create(jsonCofyBizApi.class);
UserBank post = new UserBank(user_id, txtbankname.getText().toString());
Call<UserBank> call = jsonCofyBizApi.updateUserBank(user_id, post);
call.enqueue(new Callback<UserBank>() {
#Override
public void onResponse(Call<UserBank> call, Response<UserBank> response) {
UserBank postResponse = response.body();
and rest of the code...
Class/ Constructor UserBank:
public class UserBank {
#SerializedName("user_id")
int user_id;
#SerializedName("bank_name")
String bank_name;
public UserBank(int user_id, String bank_name)
{
this.user_id = user_id;
this.bank_name = bank_name;
}
rest of the code...
I saw other threads with the same topic but none of the solution is working for me. The url is getting properly generated.
Any help appreciated.
Regards,
PD
The problem is solved. Added '/' at the end of the specified endpoint
#PATCH("usersapi/{id}")
Call<UserBank> updateUserBank(#Path("id") int id, #Body UserBank post);
#PATCH("usersapi/{id}/")
Call<UserBank> updateUserBank(#Path("id") int id, #Body UserBank post);
I send request but there is no response and no error. It passes callAsync.enqueue(new Callback<GetCheapestResponseType>() method without entering into it.
This is my Service.class:
public class Service {
String urlGetCheapest = "https://services-api.ryanair.com/farfnd/3/";
public void getCheapestFromToSpain() {
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(urlGetCheapest)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
httpClient.connectTimeout(5, TimeUnit.MINUTES) // connect timeout
.writeTimeout(5, TimeUnit.MINUTES) // write timeout
.readTimeout(5, TimeUnit.MINUTES); // read timeout
String outboundDepartureDateToString = "2021-12-31";
Date outboundDepartureDateFrom = new Date(System.currentTimeMillis());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String outboundDepartureDateFromString = sdf.format(outboundDepartureDateFrom);
Controller controller = retrofit.create(Controller.class);
Call<GetCheapestResponseType> callAsync = controller.getCheapest("SXF", outboundDepartureDateFromString, outboundDepartureDateToString);
callAsync.enqueue(new Callback<GetCheapestResponseType>() {
#Override
public void onResponse(Call<GetCheapestResponseType> call, Response<GetCheapestResponseType> response) {
if (response.isSuccessful()) {
GetCheapestResponseType apiResponse = response.body();
//API response
System.out.println(apiResponse);
} else {
System.out.println("Request Error : " + response.errorBody());
}
}
#Override
public void onFailure(Call<GetCheapestResponseType> call, Throwable throwable) {
System.out.println(throwable);
}
});
}
}
This is my Controller interface:
public interface Controller {
#GET("/oneWayFares")
public Call<GetCheapestResponseType> getCheapest(
#Query("departureAirportIataCode") String departureAirportIataCode,
#Query("outboundDepartureDateFrom") String outboundDepartureDateFrom,
#Query("outboundDepartureDateTo") String outboundDepartureDateTo);
}
I've came across this problem in the past, This problem usually comes when your retrofit client can't parse your response into your Java class. I suggest you to double check your output with your java class field.
I'm putting the answer here so it's more visible.
The issue was that in the #GET had beginning "/" while the baseUrl had a trailing "/".
I had same problem, and checked my return type of Callback and response, then edited. So it worked for me.
I have a json data to be sent using retrofit in android howerver it's not not getting sent to the server. I have used slim framework at the server side .
this is my interface in android client side
public interface RequestInterface
{
#Headers("Content-type: application/json")
#POST("/instituteRegister")
Call<InstRegServerResponse> sendInstRegData(#Body InstRegServerRequest
post);
}
this is the sign up method
> public void signup()
{
String regdName = _regdName.getText().toString();
String email = _email.getText().toString();
String password = _password.getText().toString();
Log.d("password", password);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RequestInterface requestInterface =
retrofit.create(RequestInterface.class);
InstRegServerRequest instRegServerRequest = new InstRegServerRequest();
instRegServerRequest.setiname(instituteName);
instRegServerRequest.setemail(email);
instRegServerRequest.setpassword(password);
Call<InstRegServerResponse> response =
requestInterface.sendInstRegData(instRegServerRequest);
response.enqueue(new Callback<InstRegServerResponse>()
{
#Override
public void onResponse(Call<InstRegServerResponse> call,
retrofit2.Response<InstRegServerResponse> response)
{
InstRegServerResponse resp = response.body();
Log.d("status:", "sign up success");
}
#Override
public void onFailure(Call<InstRegServerResponse> call, Throwable t)
{
Log.d(Constants.TAG,"signed up failed");
}
});
}
The error is the JSON data is not passed to the server
The api endpoint works correctly as i have tested it using postman
in the android logcat i get sign up success but at the server side I think the json is not passed correctly that's why i'm unable o write the data to the database
Try this.
#Headers("Content-Type: application/json; charset=UTF-8")
#POST("instituteRegister")
Call<InstRegServerResponse> sendInstRegData(#Body Map<String, Object> params);
Construct your JSON object using Map<String, Object>.
Example:
Map<String, Object> param = new HashMap<>();
param.put("YOUR_KEY", YOUR_VALUE);
I want to ask that do I need to create new Interfaces for every POST GET request I make which have different URL .
For ex
I made 1 interface for register and other for Login other for getting Friends. Cant I just make 1 general post and get method where I can send URL , params to send and record response?
No you don't need to create new interface or new client for each request!
Inside a interface you can create multiple method as you want and as your requirement.
For Login and fro Registration method name will be different, your parameter will not same. So you can create method as you need.
//When Base Url like "http://exmaple.com/"
#GET("Service/registration")
Call<RegResult> getRegistered(#Query("name") String name,
#Query("email") String email,
#Query("dob") String dob,
#Query("name") String name
);
#GET("Service/login")
Call<LoginResult> getLogin(#Query("username") String username,
#Query("pass") String pass
);
#GET("Service/profile")
Call<ProfileResult> getProfile(#Query("userid") String userid
);
You can also use same client because your base url is same.
If base url is diffrent you can also use same client like this..
public class ApiClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String base_url) {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(base_url)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
Now you can set different base url.
Creating object of interface...
String BASE_URL = "http://exmaple.com/";
ApiInterface apiService = ApiClient.getClient(BASE_URL).create(ApiInterface.class);
Calling method..
String user_id = "1";
Call< ProfileResult > call = apiService.getProfile(user_id);
Getting result
call.enqueue(new Callback< ProfileResult >() {
#Override
public void onResponse(Call< ProfileResult >call, Response< ProfileResult > response) {
Profile profile = response.body().getResults();
}
#Override
public void onFailure(Call< ProfileResult >call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});
Hop you got your answer .... for farther query fill free to ask...