【问题标题】:How to handle multiple type responses from a server through retrofit如何通过改造处理来自服务器的多种类型响应
【发布时间】:2018-01-01 21:18:58
【问题描述】:

我使用改造从 API 获得响应,但我从同一个 API 获得不同类型的响应,例如这些

  1. JsonObject
  2. 字符串类型
  3. 布尔类型

根据情况,它会从同一个 API 给出不同类型的响应。
我尝试使用此代码:

   serverUtilities.getBaseClassService(getApplicationContext(), "").forgotPasswordSecurityAnswerCheck(in, new Callback<JsonObject>() {
        @Override
        public void success(JsonObject s, retrofit.client.Response response) {
            Log.d("forgot_password_respons", "--->" + "" + s.toString());

           /* to retrieve the string or integer values*/

            if (s.toString().equals("5")) {
                utilities.ShowAlert("selected wrong question", "Forgot Password SecQues");

            }
            if (s.toString().equals("1")) {
                // some alert here

            }

           /* to retrieve the boolean  values*/

            if (s.toString().equals("false")) {
                utilities.ShowAlert(getResources().getString(R.string.otp_fail), "Forgot Password SecQues");

            }

            if (s.toString().equals("1")) {
                utilities.ShowAlert("Email already registered", "Social Registration");

            }
       /*to retrieve the Json object*/

         else
            if (s.toString().charAt(0) == '{') {
                Log.d("my_first_char", "" + s.toString().charAt(0));

                try {
                    if (s.toString().contains("memberId")) {
                        String MemberId = s.get("memberId").getAsString();
                        String optId = s.get("otpId").getAsString();
                        Log.d("Forgot_pass_ques_act", "" + MemberId + "--->" + optId);

                        Singleton.setSuccessId(MemberId);
                        Singleton.setOptId(optId);
                        Intent intent = new Intent(ForgotPasswordQuestionActivity.this, PasswordActivity.class);
                        startActivity(intent);
                        Toast.makeText(ForgotPasswordQuestionActivity.this, "congrats!! second step Success ", Toast.LENGTH_SHORT).show();

                    } else if (s.toString().contains("mId")) {

                    }
                } catch (Exception e) {
                    utilities.ShowAlert(e.getMessage(), "forgot passwordQues(catch)");

                    Log.d("forgot_password_error", "" + e.getMessage());
                }


                // Singleton.setSuccessId(s);
            }
        }

        @Override
        public void failure(RetrofitError error) {
            utilities.ShowAlert(error.getMessage(), "forgot passwordQues(server)");

            Log.d("forgot_passwo_secAnser", "--->" + error.getMessage());

        }
    });

这里我在回调中将返回类型保留为“jsonObject”并转换为 string 并检查它是 JsonObject 还是 boolean 或 String 并执行与此相关的操作。
但是我在处理响应时遇到了这个异常:

回复:

     com.google.gson.JsonSyntaxException:Expected a com.google.gson.JsonObject but was com.google.gson.JsonPrimitive

谁能建议我如何在改造中的单一回调类型中处理这些响应?

如果我像这样使用 String 类型作为回调:

server_utilities.getBaseClassService(getApplicationContext(), "").forgotPasswordResponse(in, new Callback<String>() {
        @Override
        public void success(String s, retrofit.client.Response response) {
            Log.d("forgot password resp", "--->" + "" + s.toString());

        }

        @Override
        public void failure(RetrofitError error) {


            Log.d("forgot_password_error", "--->" + error.getMessage());

        }
    });
}

我收到此错误:

 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 2 path $ 

【问题讨论】:

    标签: android gson retrofit


    【解决方案1】:

    服务器无法为您提供布尔对象,Retrofit 会自动为您将 String 转换为 JSONObject,因为这是您告诉它的类型

    要停止这种情况,只需请求一个字符串,然后再解析它

    new Callback<String>() 
    

    或许

    new Callback<JsonPrimitive>() 
    

    您还可以获得response.raw 属性(在Retrofit 2.x 中)

    【讨论】:

    • 如果我在想要 JsonObject 时使用 Callback:它会给出以下错误 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 2 路径 $ ....如果我在想要“字符串”时使用 Callback,它将给出 ---> com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 列 2 路径 $ ---->我不知道如何处理布尔响应
    • 只有在总是收到 JSON 响应时,才应使用带有 Gson 转换器的 Retrofit
    【解决方案2】:

    声明标签类型为Object

    @SerializedName("response") @Expose public Object response; 并在得到响应后检查类型并相应地转换为

    if (response.body().response!=null &&  response.body().response instanceof Collection<?>) {
                //if you find response type is collection then convert to json then json to real collection object
                String responseStr = new Gson().toJson(data.diagnosis.provisionalDiagnosis);
                Type type=new TypeToken<List<Response>>(){}.getType();
                List<Response> responseList=new Gson().fromJson(responseStr,type);
                if(responseList.size() > 0){
                    patientInfoBinding.phoneTv.setText(responseList.get(0).phnNo);
                }
            }else if (response.body() instanceof String){
                String res=response.body();
            }else {}
    

    像上面你可以检查instanceof String/instanceof Boolean

    【讨论】:

      猜你喜欢
      • 2015-06-10
      • 2020-05-13
      • 2019-05-02
      • 2014-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多