2017-11-02 2 views
0

Ich bin ein neuer Android-Entwickler, und ich versuche, eine Antwort von meinem Server zurück zu bekommen, aber es trifft nur die onFailure, wenn ich es versuche. Ich habe ein Tutorial durchgelesen und versucht, meinen Code so zu ändern, dass er so funktioniert, wie ich es möchte. Mein Code sollte einen Benutzernamen und ein Passwort an die API senden, die ich auf meinem Server erstellt habe, und eine Antwort erhalten. Hier ist mein Code:Ich kann keine POST-Antwort mit Retrofit2

LoginPage.java (MainActivity):

package com.example.azo.loginapp; 

//Android packages 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.content.Intent; 
import android.text.TextUtils; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView; 
import android.widget.Toast; 

//Project packages 
import com.example.azo.loginapp.data.model.Post; 
import com.example.azo.loginapp.data.remote.APIService; 
import com.example.azo.loginapp.data.remote.ApiUtils; 

//Retrofit packages 
import org.json.JSONException; 
import org.json.JSONObject; 
import retrofit2.Call; 
import retrofit2.Callback; 
import retrofit2.Response; 

public class LoginPage extends AppCompatActivity{ 
    private EditText Name; 
    private EditText Password; 
    private TextView Info; 
    private Button Login; 
    private int counter = 5; 

    private APIService mAPIService; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.login_page); 
     mAPIService = ApiUtils.getAPIService(); 
     Name = findViewById(R.id.etName); 
     Password = findViewById(R.id.etPass); 
     Info = findViewById(R.id.tvInfo); 
     Login = findViewById(R.id.btnLogin); 

     Info.setText("No of attempts remaining: 5"); 

     Login.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       validate(Name.getText().toString(),Password.getText().toString()); 
      } 
     }); 
    } 

    public void sendPost(String username, String password) { 
     try { 
      JSONObject paramObject = new JSONObject(); 
      paramObject.put("username", username); 
      paramObject.put("password", password); 
      Call<Post> postCall = mAPIService.savePost(paramObject.toString()); 
      postCall.enqueue(new Callback<Post>(){ 
       @Override 
       public void onResponse(Call<Post> call,Response<Post> response) { 
        Toast.makeText(LoginPage.this, "It worked!",Toast.LENGTH_SHORT).show(); 
       } 

       @Override 
       public void onFailure(Call<Post> call, Throwable t) { 
        Toast.makeText(LoginPage.this, "Something went wrong :(", Toast.LENGTH_SHORT).show(); 
       } 
      }); 
     }catch(JSONException e){ 
      e.printStackTrace(); 
     } 
    } 

    private void validate(String userName, String userPass){ 
     if(!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(userPass)){ 
      sendPost(userName, userPass); 
     }else{ 
      counter--; 
      Info.setText("No of atttempts remaining: " + String.valueOf(counter)); 
      if(counter == 0) { 
       Login.setEnabled(false); 
      } 
     } 
    } 
} 

APIService.java:

package com.example.azo.loginapp.data.remote; 
import com.example.azo.loginapp.data.model.Post; 
import retrofit2.Call; 
import retrofit2.http.Body; 
import retrofit2.http.Headers; 
import retrofit2.http.POST; 
/** 
    * Created by azotherian on 11/1/17. 
*/ 

public interface APIService { 
    @Headers("Content-Type: application/json") 
    @POST("login") 
    Call<Post> savePost(@Body String body); 
} 

Post.java:

package com.example.azo.loginapp.data.model; 
/** 
* Created by azotherian on 11/1/17. 
*/ 
import com.google.gson.annotations.Expose; 
import com.google.gson.annotations.SerializedName; 

public class Post { 
    @SerializedName("username") 
    @Expose 
    private String username; 

    @SerializedName("password") 
    @Expose 
    private String password; 

    public String getUsername(){ 
     return username; 
    } 

    public void setUsername(String username){ 
     username = username; 
    } 

    public String getPassword(){ 
     return password; 
    } 

    public void setPassword(String password){ 
     password = password; 
    } 

    @Override 
    public String toString(){ 
     return "Post{" + 
      "username='" + username + '\'' + 
      ", password='" + password + '\'' + 
      '}'; 
    } 
} 

RetrofitClient.java:

package com.example.azo.loginapp.data.remote; 

import retrofit2.Retrofit; 
import retrofit2.converter.gson.GsonConverterFactory; 

/** 
* Created by azotherian on 11/1/17. 
*/ 

public class RetrofitClient { 
    private static Retrofit retrofit = null; 

    public static Retrofit getClient(String baseUrl) { 
     if (retrofit==null) { 
      retrofit = new Retrofit.Builder() 
       .baseUrl(baseUrl) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .build(); 
     } 
     return retrofit; 
    } 
} 

ApiUtils.java:

package com.example.azo.loginapp.data.remote; 

/** 
* Created by azotherian on 11/1/17. 
*/ 

public class ApiUtils { 
    private ApiUtils() {} 

    public static final String BASE_URL = "http://107.170.239.46/"; 

    public static APIService getAPIService() { 
     return RetrofitClient.getClient(BASE_URL).create(APIService.class); 
    } 
} 

Wenn es noch mehr Informationen benötigt wird, lassen Sie es mich wissen! Vielen Dank für Ihre Zeit!

+0

Setzen Sie einen Haltepunkt auf die Methode 'OnFailure' und sehen Sie, was der Fehler sagt. –

+0

Was ist das Ergebnis von t.getcause() und t.getmessage() in onFalure –

+0

@AnkurKhandelwal beide sagen "java.lang.illegalStateException: Erwartete BEGIN_OBJECT aber war NUMBER in Zeile 1 Spalte 4 Pfad $" – Azotherian

Antwort

0

Nach einigen Nachforschungen und Debugging (dank @AnkurKhandelwal und @JuanCruzSoler), habe ich herausgefunden, dass mein Code eine Antwort im Körper für Gson zu entschlüsseln erwartet. Da ich nichts von meinem Server in den Körper zurückgab, musste ich meinen Call ändern, um void zu verwenden. Dieser Code wurde innerhalb LoginPage.java:

Call<Void> voidCall = mAPIService.savePost(paramObject.toString()); 
voidCall.enqueue(new Callback<Void>(){ 
    @Override 
    public void onResponse(Call<Void> call, Response<Void> response) { 
     Toast.makeText(LoginPage.this, "It worked!", Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public void onFailure(Call<Void> call, Throwable t) { 
     Toast.makeText(LoginPage.this, "Something went wrong :(", Toast.LENGTH_SHORT).show(); 
     } 
    }); 

ich alle Post geändert in den <T> ‚s für ungültig zu erklären. Danke für die Hilfe!