Gson解析空文字列異常の処理
5456 ワード
いくつかの規範的でないjsonに直面して、私たちのgson解析はいつも各種の異常を投げ出してappの崩壊を招くことができて、ここでいくつかの措置を取って避けることができます
11月9日更新:配列タイプのフィールド解析異常について、いくつかの案を試みたが、最後に問題があり、良い解決策があれば、以下に貼ってほしい.あまり感謝しない例外例=>通常json:
異常json:
Json異常状況
まず、バックグラウンドから戻ってきたjsonの通常のjsonを見てみましょう.
dataセクションに対応するエンティティクラス:
例外json:
このようにGsonは解析時に解析エラーの異常を投げ出し,appがクラッシュするのは,「」をintに変換できないためである.
json異常の処理
バックグラウンドで返されるjson異常の場合も解析に成功することを期待し、空の値に対応する変換はデフォルト値になります.例えば、newsId=0;ここではバックグラウンド開発者の出力を排除して矯正するのは、やはり自分でしなければなりません.
Gsonの
同理LongおよびDoubleタイプ
double=>
long=>
このように使用されています
バックグラウンドjsonフィールドが空の場合にクラッシュすることはありません
作者について簡書:uncochen github:ChenZhen 新浪微博:@Chen丶振 Email:[email protected]
11月9日更新:配列タイプのフィールド解析異常について、いくつかの案を試みたが、最後に問題があり、良い解決策があれば、以下に貼ってほしい.あまり感謝しない例外例=>通常json:
{
"code":0,
"msg":"ok",
"data":[ //
{
"id":5638,
"newsId":5638
}
]
}
異常json:
{
"code":0,
"msg":"ok",
"data":{} //
}
Json異常状況
まず、バックグラウンドから戻ってきたjsonの通常のjsonを見てみましょう.
{
"code":0,
"msg":"ok",
"data":{
"id":5638,
"newsId":5638
}
}
dataセクションに対応するエンティティクラス:
public class JsonBean {
private int id;
private int newsId;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getNewsId() {
return newsId;
}
public void setNewsId(int newsId) {
this.newsId = newsId;
}
}
例外json:
{
"code":0,
"msg":"ok",
"data":{
"id":5638,
"newsId":""
}
}
このようにGsonは解析時に解析エラーの異常を投げ出し,appがクラッシュするのは,「」をintに変換できないためである.
json異常の処理
バックグラウンドで返されるjson異常の場合も解析に成功することを期待し、空の値に対応する変換はデフォルト値になります.例えば、newsId=0;ここではバックグラウンド開発者の出力を排除して矯正するのは、やはり自分でしなければなりません.
Gsonの
JsonSerializer
インタフェースとJsonDeserializer
,すなわちシーケンス化と逆シーケンス化インタフェースを実現するためにint値のタイプ変換器を書くpublic class IntegerDefault0Adapter implements JsonSerializer, JsonDeserializer {
@Override
public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
if (json.getAsString().equals("") || json.getAsString().equals("null")) {// int , "" null, 0
return 0;
}
} catch (Exception ignore) {
}
try {
return json.getAsInt();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
@Override
public JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
}
}
同理LongおよびDoubleタイプ
double=>
public class DoubleDefault0Adapter implements JsonSerializer, JsonDeserializer {
@Override
public Double deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
if (json.getAsString().equals("") || json.getAsString().equals("null")) {// double , "" null, 0.00
return 0.00;
}
} catch (Exception ignore) {
}
try {
return json.getAsDouble();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
@Override
public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
}
}
long=>
public class LongDefault0Adapter implements JsonSerializer, JsonDeserializer {
@Override
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
if (json.getAsString().equals("") || json.getAsString().equals("null")) {// long , "" null, 0
return 0l;
}
} catch (Exception ignore) {
}
try {
return json.getAsLong();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
@Override
public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src);
}
}
このように使用されています
return new Retrofit.Builder()
.client(okHttpClient)//
.addConverterFactory(GsonConverterFactory.create(buildGson()))// json
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())// Retrofit RxJava
.baseUrl(baseUrl)
.build();
/**
* "" "null"
* 1.int=>0
* 2.double=>0.00
* 3.long=>0L
*
* @return
*/
public static Gson buildGson() {
if (gson == null) {
gson = new GsonBuilder()
.registerTypeAdapter(Integer.class, new IntegerDefault0Adapter())
.registerTypeAdapter(int.class, new IntegerDefault0Adapter())
.registerTypeAdapter(Double.class, new DoubleDefault0Adapter())
.registerTypeAdapter(double.class, new DoubleDefault0Adapter())
.registerTypeAdapter(Long.class, new LongDefault0Adapter())
.registerTypeAdapter(long.class, new LongDefault0Adapter())
.create();
}
return gson;
}
バックグラウンドjsonフィールドが空の場合にクラッシュすることはありません
作者について