the response is always raised ie Invalid response from server.
I've tried various ways but there was no response.and when I tried getCode 200 what happened was NPE
Before I used the same method with a different case I could get a response ... but in this case I didn't pay attention to the reposn. while the input and backend are correct in my opinion.
I hope my friends can help me, thank you
this function getresponse post.
HashMap<String, String> params = new HashMap<>();
params.put("id_member",sharedPrefManager.getSpIdMember() );
params.put("id_product_category", txt_id_product_category.getText().toString());
params.put("id_product", txt_id.getText().toString());
params.put("number", txt_number.getText().toString());
params.put("list_id_company", mitraStringBuilder.toString());
Call<ResponseCicilan> getCicilan = mApiService.getCicilanProduct(params);
getCicilan.enqueue(new Callback<ResponseCicilan>() {
#Override
public void onResponse(Call<ResponseCicilan> call, Response<ResponseCicilan> response) {
if(response.body()!=null){
ResponseCicilan responseCicilan = response.body();
String content ="";
if(response.body().getResponseCode()==200){
content+= responseCicilan.getData().getProductMeta().getIdProduct();
}else {
content+=responseCicilan.getMessage();
}
Log.d("jajal", "onResponse: login res"+content);
//
// Toast.makeText(TransactionSelectMitra.this, ""+response.message(), Toast.LENGTH_LONG).show();
// Log.d("bismillah", "onResponse: fail "+response.code());
// return;
}
Log.d("bismillah", "onResponse: success"+response.code()+" "+response);
if(response.body().getResponseCode()==200){
String content="";
// _loginButton.setEnabled(false);
ResponseCicilan responseCicilan = response.body();
content += "code:"+ response.code();
content += "token:"+ responseCicilan.getData().toString();
Log.d("bismillah", "onResponse: login res"+content);
} else {
Toast.makeText(TransactionSelectMitra.this, "Invalid response from server", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<ResponseCicilan> call, Throwable t) {
Toast.makeText(TransactionSelectMitra.this, "Invalid response from server", Toast.LENGTH_SHORT).show();
}
});
}
this api interface
#FormUrlEncoded
#POST("ApiMobile/getDatatenor")
Call<ResponseCicilan> getCicilanProduct(#FieldMap HashMap<String, String> params);
response.java
public class ResponseCicilan{
#SerializedName("response_code")
private int responseCode;
#SerializedName("data")
private Data data;
#SerializedName("message")
private String message;
public void setResponseCode(int responseCode){
this.responseCode = responseCode;
}
public int getResponseCode(){
return responseCode;
}
public void setData(Data data){
this.data = data;
}
public Data getData(){
return data;
}
public void setMessage(String message){
this.message = message;
}
public String getMessage(){
return message;
}
}
Related
I'm trying to post data to API in android which it's successful in postman with this body raw:
{
"phonenumber": "12345",
"username": "test",
"password": "1234",
"roles": 1
}
The response in successful is:
{
"message": "Registered successfully!"
}
And the response in error is:
{
"message": "Failed! this user already registered!"
}
So in android, I tried first the retrofit library and the post works perfectly if the user that I tried to register does not exist and I get the response correct
but if the user exist so the response return null 400 status code
So I tried to do it using volley in order to solve the problem but got the same result
This is my code:
private void userSignUp(){
//defining a progress dialog to show while signing up
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Signing Up...");
progressDialog.show();
String phonenumber = editTextPhonenumber.getText().toString().trim();
String username = editTextUsername.getText().toString().trim();
String password = editTextPassword.getText().toString().trim();
// url to post our data
String url = "http://xxxx/api/auth/signup";
// creating a new variable for our request queue
RequestQueue queue = Volley.newRequestQueue(SignUpActivity.this);
JSONObject object = new JSONObject();
try {
//input your API parameters
object.put("phonenumber", phonenumber);
object.put("username", username);
object.put("password", password);
object.put("roles", 1);
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, object,
new com.android.volley.Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Toast.makeText(getApplicationContext(), "String Response : "+ response.toString(), Toast.LENGTH_LONG).show();
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "String Response : "+ error.networkResponse.statusCode + "\nResponse Data " + error.networkResponse.data
+ "\nCause " + error.getCause()
+ "\nmessage" + error.getMessage(), Toast.LENGTH_LONG).show();
}
}){
#Override
public String getBodyContentType() {
return "application/json";
}
};
queue.add(jsonObjectRequest);
}
And this is the retrofit version:
private void userSignUp(){
//defining a progress dialog to show while signing up
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Signing Up...");
progressDialog.show();
String phonenumber = editTextPhonenumber.getText().toString().trim();
String username = editTextUsername.getText().toString().trim();
String password = editTextPassword.getText().toString().trim();
//building retrofit object
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(APIUrl.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
//Defining retrofit api service
APIService service = retrofit.create(APIService.class);
//Defining the user object as we need to pass it with the call
User user = new User(phonenumber, username, password, 1);
//defining the call
Call<Result> call = service.createUser(user);
//calling the api
call.enqueue(new Callback<Result>() {
#Override
public void onResponse(Call<Result> call, Response<Result> response) {
//hiding progress dialog
progressDialog.dismiss();
if(response.isSuccessful()) {
Log.d("TAG", "onResponse: " + response.body() + " " + response.errorBody());
}
//displaying the message from the response as toast
Toast.makeText(getApplicationContext(), response.body().getMessage(), Toast.LENGTH_LONG).show();
//if there is no error
if (response.body().getMessage() == "User was registered successfully!") {
Toast.makeText(getApplicationContext(), "response.body().getMessage()", Toast.LENGTH_LONG).show();
//starting profile activity
finish();
SharedPrefManager.getInstance(getApplicationContext()).userLogin(user);
startActivity(new Intent(getApplicationContext(), MainActivity.class));
}
else {
}
}
#Override
public void onFailure(Call<Result> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_LONG).show();
}
});
With it's apiservice:
public interface APIService {
//The register call
#POST("auth/signup")
Call<Result> createUser(#Body User user);
}
Request pojo:
public class User {
#SerializedName("id")
private int id;
#SerializedName("phonenumber")
private String phonenumber;
#SerializedName("username")
private String username;
#SerializedName("password")
private String password;
#SerializedName("roles")
private int roles;
public User(String phonenumber, String username, String password, int roles) {
this.phonenumber = phonenumber;
this.username = username;
this.password = password;
this.roles = roles;
}
public User(int id, String phonenumber, String username, int roles){
this.id = id;
this.phonenumber = phonenumber;
this.username = username;
this.roles = roles;
}
public User(int id, String phonenumber, String username, String password, int roles) {
this.id = id;
this.phonenumber = phonenumber;
this.username = username;
this.password = password;
this.roles = roles;
}
public int getId() {
return id;
}
public String getPhonenumber() {
return phonenumber;
}
public String getUsername() {
return username;
}
public String getPassword(){
return password;
}
public int getRoles() {
return roles;
}
}
Response pojo:
public class Result {
#SerializedName("message")
private String message;
public Result(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
Anyone can help me please? why I get this error if the user already registered?
How Can I display the error {"message": "Failed! this user already registered!"} itself just like the success response?
Actually the status code "400" is not an error code and because of that, you can create handling for that. I don't know if it'll work for you but as per your post, I think it's just the way you handle the response. Hope It'll help you :D
For example :
call.enqueue(new Callback<Result>() {
#Override
public void onResponse(Call<Result> call, retrofit2.Response<Result> response) {
mProgressDialog.dismiss();
if (response.isSuccessful()){
try {
if(response.body()!=null) {
Toast.makeText(SignUpActivity.this, "Welcome to our Apps", Toast.LENGTH_LONG).show();
} else if (response.errorBody() != null && response.code() == 400){
Toast.makeText(SignUpActivity.this, response.body(), Toast.LENGTH_LONG).show();
} else {
// If you want to add other handler
}
}catch (Exception e){
e.printStackTrace();
}
} else {
showCustomDialog2(response.errorBody().toString());
Toast.makeText(SignUpActivity.this, response.errorBody().toString(), Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<Result> call, Throwable t) {
Log.e("ERROR : ", t.getMessage());
mProgressDialog.dismiss();
}
});
But, if you have access to editing the server-side, I suggest you add a new field for the status code so that it'll make your app easier to check your user data so that your response JSON will look like this :
{
"status": "400",
"message": "Failed to sign up, user already exist !!"
}
I made a post request method with Retrofit2 but I encountered this problem on my response.
Expected a string but was BEGIN_OBJECT at line 3 column 4 path $.SUCCESS
The response should be
{
"SUCCESS" :
{
"200" : "access granted",
"ra" : "approved",
"la" : "approved",
"ch" : "approved"
}
}
I uses this code for the post request
#POST("login")
Call<Post> createPost(#Body Post post);
And for the POJO class
public class Post {
private String anthony;
private String SUCCESS;
public Post(String name) {
this.anthony = name;
}
public String getSUCCESS() {
return SUCCESS;
}
}
For the method I use the following code
private void createPost() {
Post post = new Post("mypassword");
Call<Post> call = jsonPlaceHolderApi.createPost(post);
call.enqueue(new Callback<Post>() {
#Override
public void onResponse(Call<Post> call, Response<Post> response) {
if (!response.isSuccessful()) {
textViewResult.setText("Code: " + response.code());
return;
}
Post postResponse = response.body();
String content = "";
content += "Code: " + response.code() + "\n";
content += "S" + postResponse.getSUCCESS();
textViewResult.setText(content);
}
#Override
public void onFailure(Call<Post> call, Throwable t) {
textViewResult.setText(t.getMessage());
}
});
}
Does anyone know what's wrong with my code? I expected to get the response inside the "SUCCESS" json object.
You expect SUCCESS to be an object in your wanted response but you have defined it as a String in your Post class. You should use an object for SUCCESS instead.
public class Post {
private String anthony;
private PostSuccess SUCCESS;
public Post(String name) {
this.anthony = name;
}
public PostSuccess getSUCCESS() {
return SUCCESS;
}
}
public class PostSuccess {
#JsonProperty("200")
private String _200;
private String ra;
private String la;
private String ch;
}
By This code, I am not able to get the error response as if I use same email id twice then I am getting the error response in postman but in my application, I am not getting the error response
So can you please help me to get out of this
My Interface
public interface SignupAPI {
#FormUrlEncoded
#POST("users")
Call<ResponseBody> createUser(
#Field("email") String email,
#Field("password") String password,
#Field("role") String role
);
}
My Java Code
public class SignupClient {
private static final String BASE_URL = "http://74.207.233.160/api/v1/";
private static SignupClient mInstance;
private Retrofit retrofit;
private SignupClient(){
retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
}
public static synchronized SignupClient getmInstance(){
if (mInstance == null){
mInstance = new SignupClient();
}
return mInstance;
}
public SignupAPI getApi(){
return retrofit.create(SignupAPI.class);
}
}
My Activity
Call<ResponseBody> call = SignupClient.getmInstance().getApi().createUser(email, password,role);
call.enqueue(new Callback<ResponseBody>()
{
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response)
{
if (response.isSuccessful()){
progressBar.setVisibility(View.GONE);
Toast.makeText(SignupActivity.this, "Account Sucessfully Created", Toast.LENGTH_SHORT).show();
}else {
try {
progressBar.setVisibility(View.GONE);
JSONObject jsonError = new
JSONObject(response.errorBody().string());
Toast.makeText(SignupActivity.this, jsonError.getString("errors"),Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
progressBar.setVisibility(View.GONE);
e.printStackTrace();
} catch (IOException e) {
progressBar.setVisibility(View.GONE);
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(SignupActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
make error pojo class..
public class Errors{
#SerializedName("email")
private List<String> email;
public void setEmail(List<String> email){
this.email = email;
}
public List<String> getEmail(){
return email;
}
}
make changes into response body class..
public class ResponseBody {
#SerializedName("errors")
private Errors errors;
public void setErrors(Errors errors){
this.errors = errors;
}
public Errors getErrors(){
return errors;
}
}
then after used into api response like
Errors errors=response.body().getErrors();
This question already has an answer here:
How to fix Expected BEGIN_OBJECT in Retrofit?
(1 answer)
Closed 4 years ago.
In my application i want use Retrofit for get some data from server.
I write below codes but when run application and call api show me below error :
E/socketLogResponse: Err : com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
Please see my above codes and help me
API response from server :
{
"status": "ok",
"time": 0.014972925186157227
}
ApiService interface :
#POST("api/log")
Call<SocketPingResponse> getSocketPingLog(#Header("jwt") String jwt, #Body SocketPingBodySendData socketPingBodySendData);
SocketPingResponse class :
public class SocketPingResponse {
#SerializedName("status")
#Expose
private String status;
#SerializedName("time")
#Expose
private Double time;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Double getTime() {
return time;
}
public void setTime(Double time) {
this.time = time;
}
}
SocketPingBodySendData class :
public class SocketPingBodySendData {
#SerializedName("auction_id")
#Expose
int auction_id;
#SerializedName("data")
#Expose
List<SocketPingEntity> data;
public int getAuction_id() {
return auction_id;
}
public void setAuction_id(int auction_id) {
this.auction_id = auction_id;
}
public List<SocketPingEntity> getData() {
return data;
}
public void setData(List<SocketPingEntity> data) {
this.data = data;
}
}
Api call codes in activity :
pingEntityList.addAll(socketPingDatabase.socketPingDao().getSocketPingEntityList());
SocketPingBodySendData pingBodySendData = new SocketPingBodySendData();
pingBodySendData.setAuction_id(auctionID);
pingBodySendData.setData(pingEntityList);
Toast.makeText(context, ""+pingEntityList.size(), Toast.LENGTH_SHORT).show();
Call<SocketPingResponse> pingResponseCall = apis.getSocketPingLog(jwtToken, pingBodySendData);
pingResponseCall.enqueue(new Callback<SocketPingResponse>() {
#Override
public void onResponse(Call<SocketPingResponse> call, Response<SocketPingResponse> response) {
if (response.body() != null) {
Toast.makeText(context, response.body().getStatus(), Toast.LENGTH_SHORT).show();
if (response.body().getStatus().equals("ok")) {
pingEntityList.clear();
socketPingDatabase.socketPingDao().deleteAll();
}
}
}
#Override
public void onFailure(Call<SocketPingResponse> call, Throwable t) {
Log.e("socketLogResponse", "Err : " + t.toString());
}
});
ApiClient class :
public class ApiClient {
private static final String BASE_URL = Constants.SERVER;
private static Retrofit retrofit = null;
private static Context context;
public static Retrofit getClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.interceptors().add(interceptor);
client.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("X-Client-Version", Constants.getAppVersionName()).build();
return chain.proceed(request);
}
});
client.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("uuid", Constants.getUUID(Constants.currentActivity)).build();
return chain.proceed(request);
}
});
client.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("agent", Constants.getAgent()).build();
return chain.proceed(request);
}
});
OkHttpClient client2 = client
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client2)
.build();
}
return retrofit;
}
}
How can i fix this issue?
I think the problem returns string when no data is returned. Backend can usually do such errors. this error had happened to me before. you should check the response json when no data is available
Retrofit is typesafe library. It means that it waits only particular (predefined) types of objects. If server sends something else - it crashes with error. This is your case. Just check raw server response and you'll see what's wrong.
Try changing your API call
from
#POST("api/log")
Call<SocketPingResponse> getSocketPingLog(#Header("jwt") String jwt, #Body SocketPingBodySendData socketPingBodySendData);
to
#POST("api/log")
Call<String> getSocketPingLog(#Header("jwt") String jwt, #Body SocketPingBodySendData socketPingBodySendData);
pingEntityList.addAll(socketPingDatabase.socketPingDao().getSocketPingEntityList());
SocketPingBodySendData pingBodySendData = new SocketPingBodySendData();
pingBodySendData.setAuction_id(auctionID);
pingBodySendData.setData(pingEntityList);
Toast.makeText(context, ""+pingEntityList.size(), Toast.LENGTH_SHORT).show();
Call<String> pingResponseCall = apis.getSocketPingLog(jwtToken, pingBodySendData);
pingResponseCall.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if (response.body() != null) {
//Convert here your string response to Other POJO format
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.e("socketLogResponse", "Err : " + t.toString());
}
});
{ "StatusCode": 200, "StatusDescription": "OK", "ErrorMessage":
"", "ErrorDetail": "", "Results": [
{
"Key": "AccessTokens",
"Value": "[{\"Key\":\"XXXXX",
\"Value\":\"BABABA\"},{\"Key\":\"DIDADIDA\",\"Value\":\"YYYYY"
} ]"}]}
This is the response i will get when i success call the API. The datatype of "Results" is List. Can anyone explain for me how to get the "Key" and the "Value".
My Object Classes
public class KeyValueItem {
private String Key;
private String Value;
public String getKey() {
return Key;
}
public void setKey(String key) {
Key = key;
}
public String getValue() {
return Value;
}
public void setValue(String value) {
Value = value;
}
}
Response Class
public class RestServiceResponse {
#SerializedName("StatusCode")
#Expose
public int StatusCode;
public int getStatusCode() {
return StatusCode;
}
#SerializedName("StatusDescription")
#Expose
public String StatusDescription;
public String getStatusDescription() {
return StatusDescription;
}
#SerializedName("ErrorMessage")
#Expose
public String ErrorMessage;
public String getErrorMessage() {
return ErrorMessage;
}
#SerializedName("ErrorDetail")
#Expose
public String ErrorDetail;
public String getErrorDetail() {
return ErrorDetail;
}
#SerializedName("Results")
#Expose
public List<KeyValueItem> Results;
public List<KeyValueItem> getResults() {
return Results;
}
}
Anyone help please =(
Some of my code:
public void onResponse(Call<RestServiceResponse> call, Response<RestServiceResponse> response) {
Log.i("ddsddsadsa", String.valueOf(response.code()));
RestServiceResponse restServiceResponse = response.body();
if(restServiceResponse.getStatusCode() == 200){
List<KeyValueItem> list = response.body().getResults();
JSONArray jsonArray = new JSONArray(list);
try {
JSONObject job = jsonArray.getJSONObject(1);
String testttt = job.getString("Key");
Log.i("dsadsadsadas", testttt);
} catch (JSONException e) {
e.printStackTrace();
}
}
2 things you have to understand first.
Your JSON data is not in valid format. It contains \ (slashes) to escape double quotes in key-value pair. To confirm whether the returned JSON data is valid or not please copy & paste your JSON response into JSON validator and Formatter. Maybe problem in server script.
If you're using GsonConvertorFactory with Retrofit, Retrofit will automatically converts JSON response data to POJO internally. So, you don't need parse it again inside onResponse() method. If you get proper JSON response from server side then use it like below.
public void onResponse(Call<RestServiceResponse> call, Response<RestServiceResponse> response) {
// code....
RestServiceResponse restServiceResponse = response.body();
if (restServiceResponse.getStatusCode() == 200) {
List<KeyValueItem> list = response.body().getResults();
for(int i = 0; i < list.size(); i++) {
KeyValueItem kvi = list.get(i);
// do whatever you want with kvi object
}
}
}
public void onResponse(Call<RestServiceResponse> call, Response<RestServiceResponse> response) {
Log.i("ddsddsadsa", String.valueOf(response.code()));
RestServiceResponse restServiceResponse = response.body();
if(restServiceResponse.getStatusCode() == 200){
List<KeyValueItem> list = response.body().getResults();
for(KeyValueItem keyValueItem : list) {
String key = keyValueItem.getKey();
String value = keyValueItem.getValue();
Log.i("Keykeykey", key);
}
try {
JSONArray jsonArray = new JSONArray(value);
for(int i = 0; i < jsonArray.length();i++) {
JSONObject obj = jsonArray.getJSONObject(i);
String keykey = obj.getString("Key");
String VAlll = obj.getString("Value");
Log.i("c1111",keykey);
Log.i("c222222", VAlll);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}else if(restServiceResponse.getErrorMessage() != null){
builder = new AlertDialog.Builder(LoginActivity.this);
builder.setTitle("Error");
builder.setMessage(restServiceResponse.getErrorMessage());
builder.setPositiveButton("Ok",null);
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
}
OK. Btw. i have try this to get my result. and it works!
To answer those about a invalid JSON format maybe because i have changed the value of the JSON so may have some mistake on it.
Below is the final log i get:
74/com.appandus.user.konnect I/Keykeykey: AccessTokens 07-12
17:14:38.177 6274-6274/com.appandus.user.konnect I/c1111: XXXXX 07-12
17:14:38.177 6274-6274/com.appandus.user.konnect I/c222222: BABABA
07-12 17:14:38.177 6274-6274/com.appandus.user.konnect I/c1111: NS/NH
: DIDAIDA 07-12 17:14:38.177 6274-6274/com.appandus.user.konnect
I/c222222: YYYYYY