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);
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 consume my own REST call using retrofit. My only clue on why it doesn't work is that it says that the type of information is "text/html" even though I am sure it's json. That being said I haven't found any answers that solve my problem.
Payload:
[
{
"user_id": "32",
"username": "Marko",
"last_activity": "2020-04-26 20:44:00",
"user_image": "slika2"
},
{
"user_id": "33",
"username": "dejan",
"last_activity": "2020-04-26 20:44:00",
"user_image": "slika3"
}
]
My chat class:
public class Chat {
#SerializedName("user_id")
private String userId;
private String username;
#SerializedName("last_activity")
private String lastActivity;
#SerializedName("user_image")
private String userImage;\
...constructor/getters
}
Api Interface:
#FormUrlEncoded
#POST("api_get_all_chats.php")
Call<List<Chat>> getChats(
#Field("id") String id
);
Api client:
public static Retrofit getClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.level(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
retrofit = new Retrofit.Builder()
.baseUrl("http://MYIP/emob%20projekat/api/")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
return retrofit;
}
And the whole request:
apiInterface = ApiClient.getClient().create(userApi.class);
Call<List<Chat>> call = apiInterface.getChats(u.getUserInfo().getUserId());
call.enqueue(new Callback<List<Chat>>() {
#Override
public void onResponse(Call<List<Chat>> call, Response<List<Chat>> response) {
chatList = new ArrayList<>(response.body());
chatAdapter = new ChatAdapter(getApplication().getApplicationContext(), R.layout.user_view, chatList);
listView.setAdapter(chatAdapter);
}
#Override
public void onFailure(Call<List<Chat>> call, Throwable t) {
Toast.makeText(getApplication().getApplicationContext(), "ne valja" , Toast.LENGTH_LONG).show();
}
});
Any type of a clue where I am messing up would be much appreciated.
You base url has space when I decoded it I got
http://MYIP/emob projekat/api/
i recommend you to put base URL without encoding
How about cleartextTrafficPermitted="true" on your AndroidManifest. I see you code is fine and I think maybe the problem about your URL with a http scheme.
You can try to specify what response your client expects with Accept:application/json either in you API Interface with:
#FormUrlEncoded
#Headers({"Accept:application/json"})
#POST("api_get_all_chats.php")
Call<List<Chat>> getChats(
#Field("id") String id
);
Either in your API client with new Retrofit.Builder().addHeader("Accept","application/json");.
This issue in square/retrofit is very similar to yours (only the inverse, since in the issue it is the server that does not accepts text/html while in your case it seems to be your client. Maybe, as in the issue, you are employing gson as well which cannot parse the text/html flavored response)
You need an interceptor like this.
public class CustomInterceptor extends Interceptor {
#override
public Response intercept(Interceptor.Chain chain) {
return chain.proceed(chain.request().newBuilder().addHeader("Content-Type", "application/json").addHeader("Accept", "application/json").build())
}
}
First try to log the request, to see exactly what is sent, with headers, url, body and response : https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor
Secondly, are you sure that you have to make a POST request, a GET seems better ?
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
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...