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