レトロフィット2を使用してAPIからストリングjsonを取得したいのですが、レトロフィット1を使用してこのjsonを取得しても問題ありませんが、レトロフィット2を使用するとnullが返されます。
これは私のJSONのようです
{"id":1,"Username":"admin","Level":"Administrator"}
これは私のAPIです
@FormUrlEncoded
@POST("/api/level")
Call<ResponseBody> checkLevel(@Field("id") int id);
これは私のコードがどのように見えるかです
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Config.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
Api api = retrofit.create(Api.class);
Call<ResponseBody> call = api.checkLevel(1);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
JsonObject post = new JsonObject().get(response.body().toString()).getAsJsonObject();
if (post.get("Level").getAsString().contains("Administrator")) {
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
私はretrofit 2を初めて使用し、上記のコードを使用すると、response.body().toString()
がnullを返すため、常にアプリがクラッシュします。
Json文字列を取得してJsonObjectに変換できるようにする方法を教えてください。
この リンク を使用して、下の画像で選択されている選択オプションを使用してJSONをPOJOに変換します
次のような応答のPOJOクラスを取得します
public class Result {
@SerializedName("id")
@Expose
private Integer id;
@SerializedName("Username")
@Expose
private String username;
@SerializedName("Level")
@Expose
private String level;
/**
*
* @return
* The id
*/
public Integer getId() {
return id;
}
/**
*
* @param id
* The id
*/
public void setId(Integer id) {
this.id = id;
}
/**
*
* @return
* The username
*/
public String getUsername() {
return username;
}
/**
*
* @param username
* The Username
*/
public void setUsername(String username) {
this.username = username;
}
/**
*
* @return
* The level
*/
public String getLevel() {
return level;
}
/**
*
* @param level
* The Level
*/
public void setLevel(String level) {
this.level = level;
}
}
そして次のようなインターフェースを使用します:
@FormUrlEncoded
@POST("/api/level")
Call<Result> checkLevel(@Field("id") int id);
そして次のように呼び出します:
Call<Result> call = api.checkLevel(1);
call.enqueue(new Callback<Result>() {
@Override
public void onResponse(Call<Result> call, Response<Result> response) {
if(response.isSuccessful()){
response.body(); // have your all data
int id =response.body().getId();
String userName = response.body().getUsername();
String level = response.body().getLevel();
}else Toast.makeText(context,response.errorBody().string(),Toast.LENGTH_SHORT).show(); // this will tell you why your api doesnt work most of time
}
@Override
public void onFailure(Call<Result> call, Throwable t) {
Toast.makeText(context,t.toString(),Toast.LENGTH_SHORT).show(); // ALL NETWORK ERROR HERE
}
});
gradleで依存関係を使用する
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.+'
注:エラーは、JSONをPOJOに変更したために発生します(後付けでaddConverterFactory(GsonConverterFactory.create())
を使用)。 JSONで応答する場合は、addConverterFactory(GsonConverterFactory.create())
をRetrofitから削除します。そうでない場合は、上記のソリューションを使用してください
JSON形式で全体の応答を取得する場合は、これを試してください:
モデルクラスを作成せずに、JSON形式でサーバーから応答全体を取得する新しい方法を試しました。 サーバーからデータを取得するためにモデルクラスを使用していません、どの応答を取得するかわからないか、要件に応じて変更される可能性があります。
これはJSONレスポンスです:
{"contacts": [
{
"id": "c200",
"name": "sunil",
"email": "[email protected]",
"address": "xx-xx-xxxx,x - street, x - country",
"gender" : "male",
"phone": {
"mobile": "+91 0000000000",
"home": "00 000000",
"office": "00 000000"
}
},
{
"id": "c201",
"name": "Johnny Depp",
"email": "[email protected]",
"address": "xx-xx-xxxx,x - street, x - country",
"gender" : "male",
"phone": {
"mobile": "+91 0000000000",
"home": "00 000000",
"office": "00 000000"
}
},
.
.
.
]}
APIインターフェースでパラメーターを変更します
public interface ApiInterface {
@POST("/index.php/User/login")//your api link
@FormUrlEncoded
Call<Object> getmovies(@Field("user_email_address") String title,
@Field("user_password") String body);
}
これを呼び出しているメインアクティビティで
ApiInterface apiService =
ApiClient.getClient().create(ApiInterface.class);
Call call = apiService.getmovies("[email protected]","123456");
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
Log.e("TAG", "response 33: "+new Gson().toJson(response.body()) );
}
@Override
public void onFailure(Call call, Throwable t) {
Log.e("TAG", "onFailure: "+t.toString() );
// Log error here since request failed
}
});
その後、通常はJSONオブジェクトとJSON配列を使用してパラメーターを取得できます
これを使用して文字列を取得します
String res = response.body().string();
の代わりに
String res = response.body().toString();
responsebodyを文字列に変換する前に常にnullのチェックを保持します
if(response.body() != null){
//do your stuff
}
retrofit2の依存関係を追加します
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
ベースURLのクラスを作成します
public class ApiClient
{
public static final String BASE_URL = "base_url";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
その後、クラスモデルを作成して値を取得します
public class ApprovalModel {
@SerializedName("key_parameter")
private String approvalName;
public String getApprovalName() {
return approvalName;
}
}
インターフェイスクラスを作成する
public interface ApiInterface {
@GET("append_url")
Call<CompanyDetailsResponse> getCompanyDetails();
}
その後メインクラスで
if(Connectivity.isConnected(mContext)){
final ProgressDialog mProgressDialog = new ProgressDialog(mContext);
mProgressDialog.setIndeterminate(true);
mProgressDialog.setMessage("Loading...");
mProgressDialog.show();
ApiInterface apiService =
ApiClient.getClient().create(ApiInterface.class);
Call<CompanyDetailsResponse> call = apiService.getCompanyDetails();
call.enqueue(new Callback<CompanyDetailsResponse>() {
@Override
public void onResponse(Call<CompanyDetailsResponse>call, Response<CompanyDetailsResponse> response) {
mProgressDialog.dismiss();
if(response!=null && response.isSuccessful()) {
List<CompanyDetails> companyList = response.body().getCompanyDetailsList();
if (companyList != null&&companyList.size()>0) {
for (int i = 0; i < companyList.size(); i++) {
Log.d(TAG, "" + companyList.get(i));
}
//get values
}else{
//show alert not get value
}
}else{
//show error message
}
}
@Override
public void onFailure(Call<CompanyDetailsResponse>call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
mProgressDialog.dismiss();
}
});
}else{
//network error alert box
}
このように使用できます。
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if (response.isSuccessful()) {
try {
JSONObject jsonObject = new JSONObject(new Gson().toJson(response.body()));
msg = jsonObject.getString("msg");
status = jsonObject.getBoolean("status");
msg = jsonObject.getString("msg");
status = jsonObject.getBoolean("status");
} catch (JSONException e) {
e.printStackTrace();
}
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
Log.e("cvbnop",response.body().toString());
} else {
Toast.makeText(MainActivity.this, "Some error occurred...", Toast.LENGTH_LONG).show();
}
}
より良いアプローチは、jsonからRetrofitにPOJOを生成させることです(gson
を使用)。まず、Retrofit
インスタンスを作成するときに.addConverterFactory(GsonConverterFactory.create())
を追加します。たとえば、jsonに対応するUser
Javaクラス(以下に示すような)がある場合、レトロフィットAPIはCall<User>
を返すことができます
class User {
private String id;
private String Username;
private String Level;
...
}
私は他の答えの組み合わせが機能することを発見しました:
interface ApiInterface {
@GET("/someurl")
Call<ResponseBody> getdata()
}
apiService.getdata().enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
val rawJsonString = response.body()?.string()
}
})
重要な部分は、応答タイプがResponseBody
であり、response.body()?.string()
を使用して生の文字列を取得することです。
APIからの応答が何であるかわからない場合。手順に従って、responsebodyの応答値をバイトに変換し、文字列形式で出力します。応答全体をコンソールに出力できます。
その後、文字列をJSONObjectに簡単に変換できます。
apiService.getFeeds(headerMap, map).enqueue(object : Callback, retrofit2.Callback<ResponseBody> {
override fun onFailure(call: Call<ResponseBody>?, t: Throwable?) {
}
override fun onResponse(call: Call<ResponseBody>?, response: Response<ResponseBody>?) {
val bytes = (response!!.body()!!.bytes())
Log.d("Retrofit Success : ", ""+ String(bytes))
}
})
だから、ここに取引があります:
作るとき
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Config.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ここでGsonConverterFactory.create()を渡します。このようにすると、Gsonはオブジェクト<ResponseBody>
に応答して取得したjsonオブジェクトを自動的に変換します。ここでは、ジャクソンなどの他のすべてのコンバーターを渡すことができます...