【问题标题】:Best way to model Android REST connection建模 Android REST 连接的最佳方法
【发布时间】:2015-07-09 22:57:37
【问题描述】:

我正在制作一个通过 REST API 连接到 Web 服务的 Android 应用,但我对内部架构的设计感到两难。

现在我有了 Client.java 类,其目的是与服务器建立连接(ConnectionMethod 是包含 GET|POST 值的 Enum):

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:响应正确时为 {status:0, result:array/int/string},响应不正确时为 {status:-1, message:string}。

另外,我想从 JSON 结果(User.java、Message.java...)和 UI 和 API 之间的中间方法创建类来建模组件,以实现应用程序和类的逻辑。

设计一个可自动管理正确/失败响应且独立于模型(用户、消息...)的同构连接系统的最佳方法是什么?

【问题讨论】:

标签: java android json rest


【解决方案1】:

有很多框架可以让整个过程变得更容易。 例如Retrofit 是一个非常简单的框架,用于将 java 类映射到 REST 调用。它带有gson,它会自动将响应从json反序列化为普通的java对象。

它还允许使用回调以及 rxJava Observables。它也允许处理错误。

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

【讨论】:

    【解决方案2】:

    您正在描述已经存在的工具。我最喜欢的是Retrofit,但还有其他人。 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);
            }
        });
    }
    

    【讨论】:

      猜你喜欢
      • 2014-01-29
      • 1970-01-01
      • 2014-11-13
      • 1970-01-01
      • 2016-12-11
      • 1970-01-01
      • 2014-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多