2015-07-09 45 views
1

我想提出一個Android應用程序連接到通過REST API的網絡服務,我有與內部結構的設計兩難境地。最佳的方式來建模的Android REST連接

現在我有類Client.java其purpouse是使連接服務器(ConnectionMethod是枚舉包含GET | POST值):

public class Client { 
private AsyncHttpClient client = new AsyncHttpClient(); //I use com.loopj.AsyncHttpClient to connect 
private ConnectionMethod method; 
private RequestParams params = new RequestParams(); 
private AsyncHttpResponseHandler responseHandler = new JsonHttpResponseHandler(){ 
    @Override 
    public void onSuccess(int statusCode, Header[] headers, JSONObject response) { 
     //Actions when connection success 
    } 
    @Override 
    public void onFailure(int statusCode, Header[] headers, JSONObject response, Throwable error) { 
     //Actions when connection fails 
    } 
}; 

public Client (RequestParams params, ConnectionMethod method) { 
    this.params = params; 
    this.method = method; 
} 

public void addParameters (Map<String, String> parameters) { 
    for (Map.Entry<String, String> entry : parameters.entrySet()) { 
     this.params.put(entry.getKey(), entry.getValue()); 
    } 
} 

public ServerResponse connect() { 
    RequestHandle handle; 

    if (this.method==ConnectionMethod.POST) { 
     handle = postRequest(); 
    } 
    else { 
     handle = getRequest(); 
    } 
    //How can I treat here different type of responses homogeneously? 
} 

private RequestHandle getRequest() { 
    return client.get(Constants.getEndpoint(), this.params, this.responseHandler); 
} 

private RequestHandle postRequest() { 
    return client.post(Constants.getEndpoint(), this.params, this.responseHandler); 
} 
} 

從服務器請求信息的樣品的方法是這樣的:

public static void login (String login, String password) { 
//This classes should be static or dynamic? 
    Map<String, String> map = new HashMap<String, String>(); 

    map.put("login", login); 
    map.put("password", password); 
    map.put("method", "site_login"); 

    Client c = new Client(); 
    c.addParameters(map); 
    c.getRequest(); 
} 

所有服務器響應是JSON:{狀態:0,結果是:陣列/ INT /串}當響應是正確的和{狀態:-1,消息:字符串}當響應不正確。

Additionaly我要讓類模型從JSON結果(User.java,Message.java ...)和用戶界面和API之間的中間部件的方法來實現應用程序和類的邏輯。

什麼是設計管理自動修正均勻的連接系統的最佳方式/失敗響應和獨立模式(用戶,消息)?

+3

不要打擾,請使用Retrofit http://square.github.io/retrofit/ –

回答

2

你所描述的是已經存在的工具。我最喜歡的是Retrofit,但也有其他人。改造可以處理成功和失敗的響應,甚至可以將JSON直接映射到POJO。

我的API客戶端

public class ApiClient { 

private static ApiInterface sApiInterface; 

public static ApiInterface getApiClient(Context context) { 

    //build the rest adapter 
    if (sApiInterface == null) { 
     final RestAdapter restAdapter = new RestAdapter.Builder() 
       .setEndpoint("example.com") 
       .build(); 
     sApiInterface = restAdapter.create(ApiInterface.class); 
    } 
    return sApiInterface; 
} 


public interface ApiInterface { 

    @GET("/program/{id}") 
    void getProgram(@Path("id") int id, RetrofitCallback<Program> callback); 

} 

我RetrofitCallback

public class RetrofitCallback<S> implements Callback<S> { 
private static final String TAG = RetrofitCallback.class.getSimpleName(); 


@Override 
public void success(S s, Response response) { 

} 

@Override 
public void failure(RetrofitError error) { 
    Log.e(TAG, "Failed to make http request for: " + error.getUrl()); 
    Response errorResponse = error.getResponse(); 
    if (errorResponse != null) { 
     Log.e(TAG, errorResponse.getReason()); 
     if (errorResponse.getStatus() == 500) { 
      Log.e(TAG, "Handle Server Errors Here"); 
     } 
    } 
} 
} 

我的模型

public class Program { 
@Expose 
private doublea.models.Airtime Airtime; 
@Expose 
private String id; 
@Expose 
private String title; 
@SerializedName("short_name") 
@Expose 
private String shortName; 
@SerializedName("full_description") 
@Expose 
private String fullDescription; 
@SerializedName("short_description") 
@Expose 
private String shortDescription; 
@Expose 
private doublea.models.Image Image; 
@SerializedName("image") 
@Expose 
private String imageName; 
@Expose 
private List<Host> hosts = new ArrayList<Host>(); 
@Expose 
private List<Category> categories = new ArrayList<Category>(); 
@Expose 
private List<Airtime> airtimes = new ArrayList<Airtime>(); 

/** Getters and Setters */ 

public Program() { 
} 

如何使用它。

private void executeProgramApiCall(int programId) { 
    ApiClient.getApiClient(this).getProgram(programId, new RetrofitCallback<Program>() { 

     @Override 
     public void success(Program program, Response response) { 
      super.success(program, response); 
      addDataToAdapter(program); 
     } 
    }); 
} 
5

有一堆的框架,它可以使整個過程變得更加容易。 例如Retrofit是用於映射Java類REST調用非常簡單的框架。它帶有gson,它會自動反序列化json對普通Java對象的響應。

它還允許使用回調以及rxJava觀測量。它也允許處理錯誤。

您可以查看示例應用程序:https://github.com/JakeWharton/u2020