주석을 사용하여 json 데이터 유형 불일치 해결

  도시 정보 데이터를 얻기 위해 Amap의 인터페이스를 사용할 때, 수신되는 json을 java bean으로 변환하기 위해 gson을 사용해야 하며, bean 속성의 데이터 유형은 고유합니다. 그런데 실제로 json을 파싱해보면 데이터가 있는데, 데이터가 있으면 문자열 형태로 전달하고, 데이터가 없으면 [](list type), 데이터가 있으면 [](list)로 전달한다. type) , 데이터가 없으면 [[]] (객체 유형)이 전달됩니다. 일반적으로 구문 분석 중에 예외가 발생합니다.

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)

어댑터를 사용자 정의하고 주석을 달아 json에 전달된 데이터 유형을 Bean으로 캡슐화된 데이터 유형으로 수정할 수 있습니다.

1. 나열할 문자열

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. 객체를 문자열로 변환

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의 모든 속성을 빈으로 캡슐화할 필요는 없습니다.

Guess you like

Origin blog.csdn.net/m0_50408097/article/details/133384682