2016-11-28 35 views
1

我想了解Retrofit,因爲它似乎照顧了我目前與JSON請求和處理中遇到的很多問題。首先,我知道我們使用的方法是在接口內部定義的,同時做出簡單的請求來獲取數據,這很容易指定從url中檢索什麼以及基於所有必要的端點在着名的github示例中。通過改造提出最低限度的發佈請求

所以,如果我們在檢索信息形成GitHub的API,我們會首先創建所有必要的POJO模型,這樣的再定義的接口:

public interface GithubService { 
    @GET("users/{username}") 
    Observable<Github>getGithHubUser(@Path("username")String userName); 
} 

從上我們有一些主要活動像:

Retrofit retrofit = new Retrofit.Builder() 
       .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .baseUrl("https://api.github.com/") 
       .build(); 

     GithubService githubService = retrofit.create(GithubService.class); 
     Observable<Github> githubUser = githubService.getGithHubUser("usersName"); 
     githubUser.subscribeOn(Schedulers.newThread()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .map(user -> "Github Username: " + user.getName() + "\nUrl:" +user.getUrl() + "\nfollowing: "+ user.getHireable()) 
       .subscribe(userInfo -> Log.d("Output", userInfo)); 

這裏我的問題是如何發送JSON的信息,如果該URL需要是這樣的:

"data={\"process\":\"procesNumber\", \"phone\":\"123456\"}" 

基本上,爲了得到任何迴應形成我一直在做這個使用簡單okhttp服務器:

OkHttpClient client = new OkHttpClient(); 
     RequestBody body = RequestBody.create(CREATE_MEDIA_TYPE, "data={\"process\":\"procesNumber\", \"phone\":\"123456\"}"); 
     String ALLWAYS_API = "http://something something bla bla"; 
     Request request = new Request.Builder() 
       .url("https://blablabla") 
       .post(body) 
       .build(); 

     Call call = client.newCall(request); 
     call.enqueue(new Callback() { 
      @Override 
      public void onFailure(Call call, IOException e) { 
        ... etc etc etc 
      } 

據我瞭解,即使我需要創建一個表示需要爲數據的POJO類送到改造,沿着線的東西:發送請求

public class DataRequest { 
    final String proces; 
    final String phone; 

    DataRequest(String process, String phone) { 
     this.process = process; 
     this.phone = phone; 

    } 
} 

這將符合該信息,但如何將實際解析到接口的實現?

interface DataService { 
    @Post(not a clue what to place here) 
    DataRequest postJson(@Body how?) 

} 

我怎樣才能真正把它添加到改造的建設者?我使用的例子來自網絡上的不同論壇以及其他用戶提出的其他問題,這個例子特別有助於理解幾件事情:How to POST raw whole JSON in the body of a Retrofit request?但我仍然不明白事情的發展和一些事情其他問題和例子對於我需要做的事情來說太複雜了。

+0

如果這真的是你的api所期望的,那麼改變你的api。 – njzk2

+0

@ njzk2男子我希望我能......我希望......我......可以...... –

+0

第一件事就是你需要使用'@ Field'註釋來發送形狀中的東西'data = ...' – njzk2

回答

1

好吧,所以爲了給任何人試圖做到這一點留下一個答案。默認情況下,retrofit附帶了許多用於處理JSON數據傳遞的實用程序,但在這種情況下,我傳遞的是一個字符串,它看起來像一個名爲data的標記中的json ......我知道..

但爲了回答這個問題,爲了解決類似問題,爲了傳遞字符串,我們需要導入一個標量轉換器,這與我們需要導入一個gson轉換器來處理我們的改進服務:

public interface CreateService { 
    @Headers({ "Content-Type: application/x-www-form-urlencoded;charset=UTF-8"}) 
    @POST("your/post/path/goes/here") 
    Call<String> getStringScalar(@Body String body); 
} 

我寫我的服務生成一個單獨的文件,在這種情況下,整個事情可以以這種方式被使用:

compile 'com.squareup.retrofit2:converter-scalars:2.0.2' 

在那之後,我們的服務可以爲處理

public class ServiceGeneratorWithScalarConvertor { 
    private static final String API_BASE_URL = "your/base/url/goes/here"; 

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

    // basically, this code is the same as the one from before with the added instance of creating and making use of the scalar converter factory.....scratch that i took it off 
    private static Retrofit.Builder builder = 
      new Retrofit.Builder() 
        .baseUrl(API_BASE_URL) 
        .addConverterFactory(ScalarsConverterFactory.create()) 
        .addConverterFactory(GsonConverterFactory.create()); 



    public static <S> S createService(Class<S> serviceClass) { 
     builder.client(httpClient.build()); 
     Retrofit retrofit = builder.build(); 
     return retrofit.create(serviceClass); 
    } 
} 

從這裏,我們可以用這種特殊的方法(我用我的主要活動在此方法中訪問結果:

public void retroFitCreateAPIExample() { 


     CreateService service = ServiceGeneratorWithScalarConvertor.createService(CreateService.class); 
     String body = "data={\"process\":\"process1\",\"phone\":\"12345\"}"; 
     Call<String> call = service.getStringScalar(body); 
     call.enqueue(new Callback<String>() { 
      @Override 
      public void onResponse(Call<String> call, Response<String> response) { 
       if(response.isSuccessful()){ 
        Log.d("Response Body>>>>>", response.body()); 
        createR = new Gson().fromJson(response.body().toString(), CreateModels.class); 
        Log.d("CREATED RESPONSE",createR.getCreate().getStops().get(0).getCity()); 

       } 
      } 

      @Override 
      public void onFailure(Call<String> call, Throwable t) { 

      } 
     }); 


    } 

實例是這樣傳遞到使用標轉換器的服務產生,發佈請求的主體被保存爲一個簡單的字符串(如在接口中指定的那樣),我們可以根據需要使用響應。

+0

我認爲你可以將你的調用聲明爲'Call '並跳過'fromJson'部分。 – njzk2