使用注解的方式解决json数据类型不一致

  在使用高德的接口去获取城市信息的数据时,需要使用gson将传入的json转换成java bean,bean的属性的数据类型是唯一的。但是实际在解析json的时候,有的数据:有数据时是传入的是string类型,没有数据的时候,传入的是[](list类型);或者是有数据是[](list类型),没有数据的时候,传入的是[[]](object类型)。通常在解析的时候,会抛出异常。

09-26 18:29:58.735  2834  4082 W System.err: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 225 path $.data.city.addressComponent.streetNumber.number
09-26 18:29:58.735  2834  4082 W System.err: 	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)
09-26 18:29:58.735  2834  4082 W System.err: 	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
09-26 18:29:58.735  2834  4082 W System.err: 	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
09-26 18:29:58.735  2834  4082 W System.err: 	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
09-26 18:29:58.735  2834  4082 W System.err: 	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
09-26 18:29:58.735  2834  4082 W System.err: 	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
09-26 18:29:58.735  2834  4082 W System.err: 	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
09-26 18:29:58.735  2834  4082 W System.err: 	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
09-26 18:29:58.736  2834  4082 W System.err: 	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
09-26 18:29:58.736  2834  4082 W System.err: 	at com.google.gson.Gson.fromJson(Gson.java:932)
09-26 18:29:58.736  2834  4082 W System.err: 	at com.google.gson.Gson.fromJson(Gson.java:897)
09-26 18:29:58.736  2834  4082 W System.err: 	at com.google.gson.Gson.fromJson(Gson.java:846)
09-26 18:29:58.736  2834  4082 W System.err: 	at com.google.gson.Gson.fromJson(Gson.java:817)

可以通过自定义adapter结合注解的方式,将json传入的数据类型修改成bean封装的数据类型。

1、String转List

public class CityAdapter extends TypeAdapter<List<String>> {

    @Override
    public void write(JsonWriter out, List<String> value) throws IOException {

    }

    @Override
    public List<String> read(JsonReader in) throws IOException {
        List<String> cityList = new ArrayList<>();
        JsonToken token = in.peek();
        if (token == JsonToken.STRING) {
            String value = in.nextString();
            cityList.add(value);
        } else if (token == JsonToken.BEGIN_ARRAY) {
            in.beginArray();
            while (in.hasNext()) {
                String value = in.nextString();
                cityList.add(value);
            }
            in.endArray();
        }
        return cityList;
    }
}

2、object转String

public class BusinessAreaAdapter extends TypeAdapter<List<CityData.BusinessArea>> {
    @Override
    public void write(JsonWriter out, List<CityData.BusinessArea> value) throws IOException {

    }

    @Override
    public List<CityData.BusinessArea> read(JsonReader in) throws IOException {
        List<CityData.BusinessArea> businessAreas = new ArrayList<>();
        JsonToken token = in.peek();
        if (token == JsonToken.BEGIN_ARRAY) {
            in.beginArray();
            while (in.hasNext()) {
                JsonToken innerToken = in.peek();
                if (innerToken == JsonToken.BEGIN_OBJECT) {
                    CityData.BusinessArea businessArea = readBusinessArea(in);
                    businessAreas.add(businessArea);
                } else if (innerToken == JsonToken.BEGIN_ARRAY) {
                    in.skipValue();
                }
            }
            in.endArray();
        }
        return businessAreas;
    }

    private CityData.BusinessArea readBusinessArea(JsonReader in) throws IOException {
        CityData.BusinessArea businessArea = new CityData.BusinessArea();
        in.beginObject();
        while (in.hasNext()) {
            String name = in.nextName();
            if (name.equals("name")) {
                businessArea.setName(in.nextString());
            } else if (name.equals("location")) {
                businessArea.setLocation(in.nextString());
            } else if (name.equals("id")) {
                businessArea.setId(in.nextString());
            }
        }
        in.endObject();
        return businessArea;
    }
} 

在java bean中通过注解的方式来进行转换

public class AddressComponent {
        private String province;
        //哪个属性需要转换,就在哪个属性上加注解
        @JsonAdapter(CityAdapter.class)
        private List<String> city;
        private String district;

        // 构造器
        // getter && setter
        // ...
    }

以下是json转java bean的一些注意事项:

① bean中属性名必须和json中的一致,bean的类型可以不一致,否则转义失败

② 转义需要的属性即可,不需要将json中所有的属性都封装到bean中

猜你喜欢

转载自blog.csdn.net/m0_50408097/article/details/133384682