2016-03-17 1 views
0

Bonjour mes collègues développeurs empilés,Android consommation API Web à l'aide Retrofit 2 avec une activité de connexion

Je dispose de plusieurs points de terminaison ASP.NET que je suis en train de consommer de l'aide Retrofit 2 méthodes Demande. J'essaye de créer une activité de connexion où, en entrant et soumettant les informations d'identification, déclenche un POST à ​​l'extrémité qui fournit alors l'information de jeton. Cette authentification est requise pour utiliser ensuite les appels GET pour les données auxquelles j'essaie d'accéder sur le backend.

J'ai actuellement l'activité de connexion, ainsi que l'adaptateur de repos et les interfaces pour les méthodes de demande - Il me manque comment je devrais transmettre les informations d'identification à l'adaptateur dans l'activité de connexion. En résumé, je voudrais entrer les informations de connexion, créer un POST pour le point de terminaison et recevoir le jeton, ce qui me conduit à la page suivante où je déclenche la requête GET pour les données réelles. S'il vous plaît reconnaissez que je suis un développeur .NET par le commerce, donc s'il me manque de grandes parties du puzzle s'il vous plaît n'hésitez pas à me le faire savoir. Toute aide est appréciée.

Voici le LoginActivity/MainActivity

import android.app.Activity; 
 
import android.content.Intent; 
 
import android.net.Uri; 
 
import android.os.Bundle; 
 
import android.view.View; 
 
import android.view.View.OnClickListener; 
 
import android.widget.Button; 
 
import android.widget.EditText; 
 
import android.widget.ProgressBar; 
 
import android.widget.TextView; 
 

 
import com.example.smcnary.insightv2.api.ServiceGenerator; 
 

 
public class MainActivity extends Activity { 
 
    //Set Error Status 
 

 
    static boolean errored = false; 
 
    Button b; 
 
    TextView statusTV; 
 
    EditText userNameET , passWordET; 
 
    ProgressBar webservicePG; 
 
    String editTextUsername; 
 
    boolean loginStatus; 
 
    String editTextPassword; 
 
    @Override 
 
    public void onCreate(Bundle savedInstanceState) { 
 
     super.onCreate(savedInstanceState); 
 
     setContentView(R.layout.main); 
 
     //Name Text control 
 
     userNameET = (EditText) findViewById(R.id.editText1); 
 

 
     passWordET = (EditText) findViewById(R.id.editText2); 
 
     //Display Text control 
 
     statusTV = (TextView) findViewById(R.id.tv_result); 
 
     //Button to trigger web service invocation 
 
     b = (Button) findViewById(R.id.button1); 
 
     //Display progress bar until web service invocation completes 
 
     webservicePG = (ProgressBar) findViewById(R.id.progressBar1); 
 
     //Button Click Listener 
 
     b.setOnClickListener(new OnClickListener() { 
 
      public void onClick(View v) { 
 
       //Check if text controls are not empty 
 
       if (userNameET.getText().length() != 0 && userNameET.getText().toString() != "") { 
 
        if(passWordET.getText().length() != 0 && passWordET.getText().toString() != ""){ 
 
         editTextUsername = userNameET.getText().toString(); 
 
         editTextPassword = passWordET.getText().toString(); 
 
         statusTV.setText(""); 
 
         Intent intent = new Intent(
 
           Intent.ACTION_VIEW, 
 
           Uri.parse(ServiceGenerator.API_BASE_URL + "/token" + "?client_id=" + userNameET)); 
 
          startActivity(intent); 
 

 
        } 
 
        //If Password text control is empty 
 
        else{ 
 
         statusTV.setText("Please enter Password"); 
 
        } 
 
        //If Username text control is empty 
 
       } else { 
 
        statusTV.setText("Please enter Username"); 
 
       } 
 
      } 
 
     }); 
 
    } 
 

 

 
}

L'adaptateur/ServiceGenerator:

import android.util.Base64; 
 
import com.example.smcnary.insightv2.model.User; 
 
import java.io.IOException; 
 
import okhttp3.Interceptor; 
 
import okhttp3.OkHttpClient; 
 
import okhttp3.Request; 
 
import okhttp3.Response; 
 
import retrofit.Callback; 
 
import retrofit2.Call; 
 
import retrofit2.Retrofit; 
 
import retrofit2.converter.gson.GsonConverterFactory; 
 
import retrofit2.http.Field; 
 
import retrofit2.http.FormUrlEncoded; 
 
import retrofit2.http.POST; 
 

 
public class ServiceGenerator { 
 

 
    public static final String API_BASE_URL = "http://figgg-identity.azurewebsites.net/token"; 
 

 
    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); 
 

 
    private static Retrofit.Builder builder = 
 
      new Retrofit.Builder() 
 
        .baseUrl(API_BASE_URL) 
 
        .addConverterFactory(GsonConverterFactory.create()); 
 

 
    public static <S> S createService(Class<S> serviceClass) { 
 
     return createService(serviceClass, null, null); 
 
    } 
 

 
    public static <S> S createService(Class<S> serviceClass, String username, String password) { 
 
     if (username != null && password != null) { 
 
      String credentials = username + ":" + password; 
 
      final String basic = 
 
        "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP); 
 

 
      httpClient.addInterceptor(new Interceptor() { 
 
       @Override 
 
       public Response intercept(Interceptor.Chain chain) throws IOException { 
 
        Request original = chain.request(); 
 

 
        Request.Builder requestBuilder = original.newBuilder() 
 
          .header("Authorization", basic); 
 
        requestBuilder.header("Accept", "application/json"); 
 
        requestBuilder.method(original.method(), original.body()); 
 

 
        Request request = requestBuilder.build(); 
 
        return chain.proceed(request); 
 
       } 
 
      }); 
 
     } 
 

 
     OkHttpClient client = httpClient.build(); 
 
     Retrofit retrofit = builder.client(client).build(); 
 
     return retrofit.create(serviceClass); 
 
    } 
 

 
    public interface LoginService { 
 
     @FormUrlEncoded 
 
     @POST("/token") 
 
     User Basiclogin(@Field("email") String email, @Field("password") String password, Callback<User> callback); 
 

 

 
    } 
 

 

 
}

EDIT: Voici mes objets JSON:

AuthToken:

package com.example.smcnary.insightv2.model; 
 

 
import java.util.HashMap; 
 
import java.util.Map; 
 

 

 

 
public class AuthToken { 
 

 
    private String accessToken; 
 
    private String tokenType; 
 
    private Integer expiresIn; 
 
    private String name; 
 
    private String title; 
 
    private String picImageBase64String; 
 
    private String Issued; 
 
    private String Expires; 
 
    private Map<String, Object> additionalProperties = new HashMap<String, Object>(); 
 

 
    /** 
 
    * 
 
    * @return 
 
    * The accessToken 
 
    */ 
 
    public String getAccessToken() { 
 
     return accessToken; 
 
    } 
 

 
    /** 
 
    * 
 
    * @param accessToken 
 
    * The access_token 
 
    */ 
 
    public void setAccessToken(String accessToken) { 
 
     this.accessToken = accessToken; 
 
    } 
 

 
    /** 
 
    * 
 
    * @return 
 
    * The tokenType 
 
    */ 
 
    public String getTokenType() { 
 
     return tokenType; 
 
    } 
 

 
    /** 
 
    * 
 
    * @param tokenType 
 
    * The token_type 
 
    */ 
 
    public void setTokenType(String tokenType) { 
 
     this.tokenType = tokenType; 
 
    } 
 

 
    /** 
 
    * 
 
    * @return 
 
    * The expiresIn 
 
    */ 
 
    public Integer getExpiresIn() { 
 
     return expiresIn; 
 
    } 
 

 
    /** 
 
    * 
 
    * @param expiresIn 
 
    * The expires_in 
 
    */ 
 
    public void setExpiresIn(Integer expiresIn) { 
 
     this.expiresIn = expiresIn; 
 
    } 
 

 
    /** 
 
    * 
 
    * @return 
 
    * The name 
 
    */ 
 
    public String getName() { 
 
     return name; 
 
    } 
 

 
    /** 
 
    * 
 
    * @param name 
 
    * The name 
 
    */ 
 
    public void setName(String name) { 
 
     this.name = name; 
 
    } 
 

 
    /** 
 
    * 
 
    * @return 
 
    * The title 
 
    */ 
 
    public String getTitle() { 
 
     return title; 
 
    } 
 

 
    /** 
 
    * 
 
    * @param title 
 
    * The title 
 
    */ 
 
    public void setTitle(String title) { 
 
     this.title = title; 
 
    } 
 

 
    /** 
 
    * 
 
    * @return 
 
    * The picImageBase64String 
 
    */ 
 
    public String getPicImageBase64String() { 
 
     return picImageBase64String; 
 
    } 
 

 
    /** 
 
    * 
 
    * @param picImageBase64String 
 
    * The picImageBase64String 
 
    */ 
 
    public void setPicImageBase64String(String picImageBase64String) { 
 
     this.picImageBase64String = picImageBase64String; 
 
    } 
 

 
    /** 
 
    * 
 
    * @return 
 
    * The Issued 
 
    */ 
 
    public String getIssued() { 
 
     return Issued; 
 
    } 
 

 
    /** 
 
    * 
 
    * @param Issued 
 
    * The .issued 
 
    */ 
 
    public void setIssued(String Issued) { 
 
     this.Issued = Issued; 
 
    } 
 

 
    /** 
 
    * 
 
    * @return 
 
    * The Expires 
 
    */ 
 
    public String getExpires() { 
 
     return Expires; 
 
    } 
 

 
    /** 
 
    * 
 
    * @param Expires 
 
    * The .expires 
 
    */ 
 
    public void setExpires(String Expires) { 
 
     this.Expires = Expires; 
 
    } 
 

 
    public Map<String, Object> getAdditionalProperties() { 
 
     return this.additionalProperties; 
 
    } 
 

 
    public void setAdditionalProperty(String name, Object value) { 
 
     this.additionalProperties.put(name, value); 
 
    } 
 

 
}

Objet utilisateur:

public class User { 
 
    @SerializedName("name") 
 
    String name; 
 
    @SerializedName("email") 
 
    String email; 
 
}

Répondre

0

Je ne sais pas si une bonne pratique, mais je sauve des titres de compétence de l'utilisateur dans SharedPreferences et conservez-le dans votre application (créer un singleton dans votre classe d'application ou à l'aide Dague pour le construire) jusqu'à ce que l'action signout eu lieu. Et j'utilise Authenticator: https://square.github.io/okhttp/3.x/okhttp/okhttp3/Authenticator.html. Par exemple, nous avons ces informations d'identification stockées en utilisant la classe UserCredentials, puis lorsque la construction du client OkHttp nous pouvons le passer via les paramètres.

OkHttpClient provideOkHttpClient(UserCredentials userCredentials) { 

     return new OkHttpClient.Builder() 
       .authenticator(new CustomAuthenticator(userCredentials)) 
       .build(); 
    } 

Avec le CustomAuthenticator ressemble à quelque chose comme ceci:

public class CustomAuthenticator implements Authenticator { 

    @NonNull 
    private final UserCredentials credentials; 

    public CustomAuthenticator(@NonNull UserCredentials credentials) { 
     this.credentials = credentials; 
    } 

    @Override 
    public Request authenticate(Route route, Response response) throws IOException { 
     String userToken = credentials.getToken(); 
     return response.request().newBuilder() 
       .header("Authorization", "Token " + userToken) 
       .build(); 
    } 
} 

méthodes de connexion Là de base aussi bien. Vous pouvez lire sur le lien et essayer.