通过改造

时间:2016-11-28 22:06:51

标签: java android json http retrofit2

我正在尝试了解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信息:

"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?但我仍然不明白一切顺利,其他一些问题和例子对于我需要做的事情来说太复杂了。

1 个答案:

答案 0 :(得分:1)

好的,所以为了给任何试图这样做的人留下答案。默认情况下,改造带有许多实用程序,它们处理数据作为JSON的传递,但在这种情况下,我传递的是一个字符串,看起来像一个名为data的标签内的json ......我知道..

但是为了对面临类似问题的人们回答这个问题,为了传递字符串,我们需要导入一个标量转换器,就像我们需要导入gson转换器来处理我们的改造服务一样:

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

之后,我们的服务可以按以下方式处理:

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);
}

我将服务生成器写在一个单独的文件中,在这种情况下,整个事情可以这样使用:

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) {

            }
        });


    }

实例是传递给使用标量转换器的服务生成器,post请求的主体保存为一个简单的字符串(就像在界面中指定的那样),我们可以根据需要做任何响应。< / p>