当前位置: 首页 > 面试题库 >

GSON忽略类型错误的元素

孔理
2023-03-14
问题内容

我正在使用Retrofit(与OkHttp和GSON结合使用)与在线Web服务进行通信。该Web服务的所有响应都有一个默认包装,类似于:

{  
  "resultCode":"OK",
  "resultObj":"Can be a string or JSON object / array",
  "error":"",
  "message":""
}

在此示例中,resultCode将为OKNO。此外errormessage仅在处理请求时发生错误时才包含任何内容。最后但并非最不重要的一点resultObj将包含调用的实际结果(示例中为字符串,但是某些调用返回JSON数组或JSON对象)。

为了处理此元数据,我创建了一个通用类,如下所示:

public class ApiResult<T> {

    private String error;
    private String message;
    private String resultCode;
    private T resultObj;

    // + some getters, setters etcetera
}

我还创建了代表有时给出的响应的类,resultObj并定义了与Retrofit一起使用的接口,看起来像这样:

public interface SomeWebService {

    @GET("/method/string")
    ApiResult<String> someCallThatReturnsAString();

    @GET("/method/pojo")
    ApiResult<SomeMappedResult> someCallThatReturnsAnObject();

}

只要请求有效,所有这些都可以正常工作。但是,当服务器端发生错误时,它仍然会返回resultObjString类型的。这会导致someCallThatReturnsAnObjectRetrofit
RestAdapter / GSON库内部崩溃,并显示以下消息:

retrofit.RetrofitError:com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:

预期为BEGIN_OBJECT,但位于第1行第110列的路径$ .resultObj

现在,最后,我的问题是:

  1. 有没有一种(简单的)方式告诉GSON如果它与期望的类型不匹配,就应该忽略(也就是“无效化”)一个属性?
  2. 我可以告诉GSON将空字符串视为null吗?

问题答案:

像这样定义模型:

public class ApiResult {

    private String error;
    private String message;
    private String resultCode;
    private MyResultObject resultObj;
}

然后,为 MyResultObject* 创建一个 TypeAdapterFactory*

public class MyResultObjectAdapterFactory implements TypeAdapterFactory {

    @Override
    @SuppressWarnings("unchecked")
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        if (type.getRawType()!= MyResultObject.class) return null;

        TypeAdapter<MyResultObject> defaultAdapter = (TypeAdapter<MyResultObject>) gson.getDelegateAdapter(this, type);
        return (TypeAdapter<T>) new MyResultObjectAdapter(defaultAdapter);
    }

    public class MyResultObjectAdapter extends TypeAdapter<MyResultObject> {

        protected TypeAdapter<MyResultObject> defaultAdapter;


        public MyResultObjectAdapter(TypeAdapter<MyResultObject> defaultAdapter) {
            this.defaultAdapter = defaultAdapter;
        }

        @Override
        public void write(JsonWriter out, MyResultObject value) throws IOException {
            defaultAdapter.write(out, value);
        }

        @Override
        public MyResultObject read(JsonReader in) throws IOException {
            /* 
            This is the critical part. So if the value is a string,
            Skip it (no exception) and return null.
            */
            if (in.peek() == JsonToken.STRING) {
                in.skipValue();
                return null;
            }
            return defaultAdapter.read(in);
        }
    }
}

最后,为 Gson* 注册 MyResultObjectAdapterFactory*

Gson gson = new GsonBuilder()
    .registerTypeAdapterFactory(new MyResultObjectAdapterFactory())
    .create();

现在,当使用该 Gson 对象反序列化 ApiResult* json时,如果 resultObjstring ,则将其设置为
null
* __

我希望这可以解决您的问题=)



 类似资料:
  • 问题内容: 我正在使用Retrofit(与OkHttp和GSON结合使用)与在线Web服务进行通信。该Web服务的所有响应都有一个默认包装,类似于: 在此示例中,将为或。此外,仅在处理请求时发生错误时才包含任何内容。最后但并非最不重要的一点,将包含调用的实际结果(示例中为字符串,但是某些调用返回JSON数组或JSON对象)。 为了处理此元数据,我创建了一个通用类,如下所示: 我还创建了代表有时给出

  • 像这种类型错误,发现是因为扩展版本的问题导致的错误,打算不去修复,想进行忽略,但是发现像 <!-- @ts-ignore --> 这样的注释没效果,这个怎么办好?

  • QueryList遵循将业务与错误分离的原则, HTTP请求传输过程中如果出现的错误,QueryList将会抛出异常。 QueryList的HTTP客户端基于GuzzleHttp,它提供了丰富的HTTP异常类型,用户可以自行设计根据不同的异常类型做不同的处理。 如果你觉得麻烦,并不想每次都去处理HTTP异常,选择直接忽略,让程序继续运行下去,做法可以参考下面方式: 对内置的get()进行封装: u

  • 我试图解析来自服务器的响应json。数据是一个对象数组,但有时服务器在数组的项之间发送一个布尔值。像这样: 正如你所看到的,他们之间有一个错误。 tnx提前。

  • 主要内容:自签名证书错误,Maven依赖关系,接受自签名证书通常,开发人员将在本地机器上或项目的开发阶段使用自签名证书。 默认情况下,HttpClient(和Web浏览器)不会接受不可信的连接。 但是,可以配置以允许不可信的自签名证书。 注意:这是一个可能存在安全风险,因为您将其用于生产时,基本上会禁用所有的认证检查,这可通导致受到攻击。 在这个例子中,我们演示了如何忽略Apache HttpClient 4.5中的SSL / TLS证书错误。 自签名证书

  • 通常看到定义一个 promise 的类型都采用 Promise<string> 的方式,表示 resolved 时返回一个 string 的类型值,但是会忽略 rejected 后应该返回什么类型,这是故意这么设计的吗?