I have a WS REST, that I need to consume by POST, which method "calculo" expects a XML as below in the key "xmlEntrada".
<xml>
<valor1/>
<valor2/>
<operacao/>
</xml>
I did the corresponding class to serialize, as expected by retrofit and SimpleXmlConverter
#Root(name="xml")
public class CalcRequest {
public CalcRequest(){
campo1 = campo2 = 0;
operacao = "";
}
#Element(name="valor1", required = false)
private float campo1;
#Element(name="valor2", required = false)
private float campo2;
#Element(name="operador", required = false)
private String operacao;
}
And I'm calling retrofit and all the stuff like this:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://server_name/wsRest/Project1.dll/")
.addConverterFactory(SimpleXmlConverterFactory.create())
.client(new OkHttpClient())
.build();
APIService API = retrofit.create(APIService.class);
Call<CalcResponse> call = API.EfetuaCalculo(calculo);
call.enqueue(new Callback<CalcResponse>() {
#Override
public void onResponse(Call<CalcResponse> call, Response<CalcResponse> response) {
AlertMessage(response.body().retorno());
}
#Override
public void onFailure(Call<CalcResponse> call, Throwable t) {
AlertMessage("Error. MSG: " + t.toString());
}
});
My method response serialization is fine, because I can read the error returned as XML, and it shows me that the request xml is arriving empty at the WS. I'm stucked on that by days, can anyone guess what's wrong?
Oh, here it's my APIService code:
public interface APIService {
#POST("calculo")
Call<CalcResponse> EfetuaCalculo(#Body CalcRequest xmlEntrada);
}
Related
i am making login function in android using retrofit. I have created an endpoint for login validation, then I have tested it using Postman using raw (json) and it worked. But when I enter the endpoint into android using retrofit I get an error message like this:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 39 path $.message
can anyone help me?
So here my source:
ApiClient
public class ApiClient {
public static final String BASE_URL = "";
public static Retrofit retrofit;
public static Retrofit getRetrofit() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
AuthInterface
public interface AuthInterface {
#Headers("Content-Type: application/json")
#POST("auth/login")
Call<AuthPost> authPostCall(#Body String body);
}
AuthPost
public class AuthPost {
#SerializedName("status")
private String status;
#SerializedName("error_code")
private int error_code;
#SerializedName("message")
private String message;
#SerializedName("token")
private String token;
...getter and setter
}
LoginActivity
JSONObject payload = new JSONObject();
try {
payload.put("login_username", loginUsernameText);
payload.put("login_password", loginPasswordText);
} catch (JSONException e) {
e.printStackTrace();
}
Call<AuthPost> authPostCall = authInterface.authPostCall(payload.toString());
authPostCall.enqueue(new Callback<AuthPost>() {
#Override
public void onResponse(Call<AuthPost> call, Response<AuthPost> response) {
if (response.code() == 200) {
} else {
}
}
#Override
public void onFailure(Call<AuthPost> call, Throwable t) {
t.printStackTrace();
}
});
Are you sure about:
#SerializedName("message")
private String message;
Usually this error appears if this field is Object.
Does your JSON looks like
"message":"test"
or something like:
"message":{"field":"value"}
If it is the second variant so you should simple change the field to necessary type.
i want fetch data from server, i have API URL like example : https://example.com/PlanController/getData/2/7k Plan, int his api url 2 is dynamic value and 7k plan is also dynamic Value. i want fetch data from retrofit method. give me some examples.
public interface APIService {
#GET("PlanController/getData")
Call<CoachListResponse> getAllData();
}
Retrofit clint
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl) {
Gson gson = new GsonBuilder().setLenient().create();
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
}
Define service after creating the retrofit
public interface APIService {
#GET("getData/{id}/{kid}")
Call<CoachListResponse> getAllData(#Path("id") Long id, #Path("kid") String kid);
}
public class RetrofitClient {
private static APIService service;
public static Retrofit getClient(String baseUrl) {
Gson gson = new GsonBuilder().setLenient().create();
if (retrofit == null) {
retrofit = new Retrofit.Builder().baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create(gson)).build();
}
service = retrofit.create(APIService.class);
return retrofit;
}
public static void getAllData(Callback<CoachListResponse> callback) {
Call<CoachListResponse> regionsCall = service.getAllData();
regionsCall.enqueue(callback);
}
}
, consume
RetrofitClient.getClient("https://example.com/PlanController/").getAllData(new Callback<CoachListResponse>() {
#Override
public void onResponse(Call<CoachListResponse> call, Response<CoachListResponse> response) {
CoachListResponse responseDto = response.body();
// logic
}
#Override
public void onFailure(Call<CoachListResponse> call, Throwable t) {
// logic
}
}, );
I wanted to replace only a part of the URL, and with this solution, I don't have to pass the whole URL, just the dynamic part and Your Retrofit client as it is no need to change:
public interface APIService {
#GET("PlanController/getData/{value}/{plan}")
Call<CoachListResponse> getAllData(#Path(value = "value", encoded = true) String value, #Path(value = "plan", encoded = true) String plan);
}
I know there are a lot of threads regarding this and i did go through them and also looked into the same Retrofit POST example,but i'm not sure what am i doing wrong in this,lemme know if any
#Multipart
#POST("api/customerdetail")
Call<Array> addUser(#Part("CustomerName") String CustomerName, #Part("CustomerId") String CustomerId, #Part("UserId") String UserId, #Part("VehicleCompanyName") String VehicleCompanyName, #Part("VehicleModelType")String VehicleModelType, #Part("VehicleNumber")String VehicleNumber, #Part("Location")String Location);
//METHOD USED TO CALL
private void simpleMethod() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://endpoint.net/")
.addConverterFactory(GsonConverterFactory.create())
.build();
GetDataService service = retrofit.create(GetDataService.class);
Call<Array> arrayListCall = service.addUser("Peter Jenkins", UUID.randomUUID().toString(),"user2","AUDI","R3","BVZ-009","-55,-93.23"); arrayListCall.enqueue(new Callback<Array>() {
#Override
public void onResponse(Call<Array> call, Response<Array> response) {
Log.e("RESPONSE",response.toString());
}
#Override
public void onFailure(Call<Array> call, Throwable t) {
Log.e("ERROR",t.toString());
} }); }
Works like a Charm in Postman,and uploading an image is not necessary,atleast from the api end
Any inputs would be deeply appreciated
I need to send an array of Strings using a Retrofit call. To do that I decided to create an object like this one:
public class SendEmailsList {
ArrayList<String> emails;
public SendEmailsList(ArrayList<String> emails) {
this.emails = emails;
}
}
And my JSON String must be like this:
{
"emails": ["email#server.com","email1#server.com","email2#server.com"]
}
This is the POST method defined in my interface:
#POST("/v2/companies/{companyId}/invite")
Call<ArrayList<String>> inviteMembers(#Path("companyId") String companyId, #Body SendEmailsList emails);
And this is the method that makes the Retrofit call:
public void SendNetworkRequest() {
OkHttpClient.Builder okhttpBuilder = new OkHttpClient.Builder();
okhttpBuilder.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder newRequest = request.newBuilder().header("Authorization", "Bearer " + token);
return chain.proceed(newRequest.build());
}
});
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(BuildConfig.ENDPOINT)
.client(okhttpBuilder.build())
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
CompanyService invite = retrofit.create(CompanyService.class);
Call<ArrayList<String>> call = invite.inviteMembers("5602eb7ce49c9cd70409f206", new SendEmailsList(invitedEmails));
call.enqueue(new Callback<ArrayList<String>>() {
#Override
public void onResponse(Call<ArrayList<String>> call, Response<ArrayList<String>> response) {
System.out.println("Internal Users: " + response.code());
}
#Override
public void onFailure(Call<ArrayList<String>> call, Throwable t) {
// Log error here since request failed
Log.e("Internal Users Activity", t.toString());
}
});
}
But I am getting this error:
12-21 14:36:49.953 27953-27953/com.construct.test E/Internal Users Activity: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
How can I figure out what is going on?
Can anyone please give me some example how we can use protobuf in retrofit - I tried but its failed with some error , let me give you a sample of my implementation on that.
I hope you guys will help me.
ApiInterface.java
public interface ApiInterface {
#GET
Call<CommonProto.Country> makeGetRequest(#Url String url);
}
ApiClient.java
public class ApiClient {
public static final String BASE_URL = "**************************";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(Proto3ConverterFactory.create())
.build();
}
return retrofit;
}
}
MainActivity.java
ApiInterface apiService =
ApiClient.getClient().create(ApiInterface.class);
Call<CommonProto.Country> call = apiService.makeGetRequest("Services/CountryServices/GetAllCountry");
call.enqueue(new Callback<CommonProto.Country>() {
#Override
public void onResponse(Call<CommonProto.Country> call, Response<CommonProto.Country> response) {
String bodyString = null;
try {
Log.e("RETROFIT ::::::: ", String.valueOf(response.body())+"TEST");
} catch (Exception e) {
Log.e("RETROFIT ERROR ::::::: ", e.getMessage()+"TEST");
e.printStackTrace();
}
}
#Override
public void onFailure(Call<CommonProto.Country> call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
}
);
when i run this way i got the error
java.lang.RuntimeException: com.google.protobuf.InvalidProtocolBufferException: Protocol message tag had invalid wire type.
my Proto.java file and also have Proto.proto file both are here in this link,
https://drive.google.com/folderview?id=0B4loQuzINvHCRUlNbk5LUXE1NXM&usp=sharing
Please let me know how to do this GET Req and also I was Struggling with POST Req.
you can create interface like this
public interface LoginInterface {
#FormUrlEncoded
#POST("url goes here")
Call<LoginResponseData> getUserLoginDeatail(#FieldMap Map<String, String> fields);
}
make an instance of retro file and call interface method something like this
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("base url")
.build();
webApis = retrofit.create(WebApis.class);
Call<LoginResponseData> call = webApis.getCurrentRide(keyValue);
call.enqueue(new Callback<LoginResponseData>() {
#Override
public void onResponse(Call<LoginResponseData> call, Response<LoginResponseData> response) {
try {
} catch (Exception e) {
// customizedToast.showToast(context.getResources().getString(
// R.string.exception));
e.printStackTrace();
}
}
#Override
public void onFailure(Call<LoginResponseData> call, Throwable t) {
}
});
for protocol buffer you can find a reference here