简体   繁体   中英

Why return an empty object when gson.toJSon

I'm trying to parse a geojson file using streaming of file, because the file could be a huge file. 1KB, 20MG or 1 TB.

I parse all file use streaming as you can see in ParseGeojsonStream class.

But when I try to parse to json using gson to storeit in postgressql database, the field property is an empty object.

But I do a log before cast to json as in not empty.

I hope you understand me.

The flux is next:

  • First I received from a post string properties and an inputStream from my controller.
  • Next, my service call ParseGeojosnStream to Stream the content of file.
  • Next, I pass the name and list of features and insert into table.
  • Finally, I create scheme with string properties and name of table as Id.

So, Why return an empty object of properties when cast to json to store it on database??

Here is the code:

public class ParseGeojsonStream {

    private static List<Feature> features = new ArrayList<Feature>();

    public static List<Feature> parseJson(InputStream is) throws IOException {

        // Create and configure an ObjectMapper instance
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        // Create a JsonParser instance
        try (JsonParser jsonParser = mapper.getFactory().createParser(is)) {

            // Check the first token
            if (jsonParser.nextToken() != JsonToken.START_OBJECT) {
                throw new IllegalStateException("Expected content to be an object");
            }

            JsonParser featureJson = findFeaturesToken(jsonParser);

            if (featureJson == null) {
                throw new IOException("Expected content to be not null");
            }

            if (featureJson.nextToken() != JsonToken.START_ARRAY) {
                throw new IOException("Expected content to be an array");
            }

            // Iterate over the tokens until the end of the array
            while (featureJson.nextToken() != JsonToken.END_ARRAY) {
                // Read a contact instance using ObjectMapper and do something with it
                Feature feature = mapper.readValue(featureJson, Feature.class);
                features.add(feature);
            }
            return features;
        }
    }


    private static JsonParser findFeaturesToken(JsonParser jsonParser) throws IOException {
        JsonParser json = jsonParser;
        while(json.nextToken() != JsonToken.END_OBJECT) {
            String text = json.getText();
            if ( text.equalsIgnoreCase(GEOJSONConstants.ApiJSON.FEATURES) ) {
                return json;
            }
        }
        return null;
    }

}

This store all features, and here is a log of one item: Feature: Feature(properties={ELEMENTO=null}, geometry={type=MultiPolygon, coordinates=[-3.691344883619331, 40.424004164131894] })

Feature Class:

@Data 
public class Feature {

    private Object properties;
    private Object geometry;
}

Method from TableGeojsonStream:

public String createTable(final String name, final List<Feature> features) {
        Gson gson = new Gson();
        checkedNameTable= nameTable(name);

        jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS " + checkedNameTable + " ( table_id SERIAL, properties jsonb not null, geom geometry(GeometryZ,4326), primary key (table_id));");
        for (int i=0; i<1; i++ ) {
            Object geometry = features.get(i).getGeometry();
            Object property = features.get(i).getProperties();

            log.info("property: " + property);
            String jsonGeometry = gson.toJson(geometry);
            String jsonProperty = gson.toJson(property);
            log.info("jsonGeometry: " + jsonGeometry); 
            log.info("jsonProperty: " + jsonProperty); 

            String SQL = "INSERT INTO " + checkedNameTable + " ( properties, geom ) VALUES ( '" + property + "', ST_Force3D(ST_SetSRID(ST_GeomFromGeoJSON('" + geometry + "'), 4326) ));";
            jdbcTemplate.batchUpdate(SQL);
        }

        return checkedNameTable;
    }

log.info("property: " + property) -> shows: property: {ELEMENTO=null}

log.info("jsonGeometry: " + jsonGeometry) -> shows: jsonGeometry: {"type":"MultiPolygon","coordinates":[-3.691344883619331, 40.424004164131894] }

log.info("jsonProperty: " + jsonProperty) -> shows: jsonProperty: {}

Here is a part of geojson:

{
    "type": "FeatureCollection",
    "features": [{
        "type": "Feature",
        "properties": {
            "ELEMENTO": null
        },
        "geometry": {
            "type": "MultiPolygon",
            "coordinates": [
                [
                    [
                        [-3.721150157449075, 40.41560855514652],
                        [-3.721148651840721, 40.41557793380572],
                        [-3.721118017962975, 40.41557902578145],
                        [-3.721113597363736, 40.41549617019551],
                        [-3.7211442312040024, 40.415495078221284],
                        [-3.721143913813499, 40.41546535037238],
                        [-3.72119576233073, 40.41546412605902],
                        [-3.721195464155001, 40.41543619989809],
                        [-3.7213085995073105, 40.415434593222656],
                        [-3.7213088881096974, 40.41546161853896],
                        [-3.721313602485271, 40.415461589126885],
                        [-3.7213206932891425, 40.41546334669616],
                        [-3.721326615119707, 40.415466012462055],
                        [-3.7213313679771427, 40.41546958642474],
                        [-3.7213372994291647, 40.41547315303393],
                        [-3.721340883314031, 40.41547763519334],
                        [-3.7213444671993554, 40.41548211735267],
                        [-3.721346882111449, 40.415487507709095],
                        [-3.7213975616676365, 40.415487191502386],
                        [-3.721400871367978, 40.41557636033541],
                        [-3.7213490227697066, 40.41557758474146],
                        [-3.7213478922770142, 40.415582096314125],
                        [-3.721345583188133, 40.415586615240166],
                        [-3.721343274098946, 40.415591134166164],
                        [-3.7213397767926453, 40.415594759601625],
                        [-3.7213351008897226, 40.415598392390244],
                        [-3.721330415365877, 40.415601124334835],
                        [-3.7213245416249427, 40.41560296278854],
                        [-3.7213186678836525, 40.41560480124199],
                        [-3.721316310690866, 40.415604815948214],
                        [-3.7213165896778255, 40.41563094041987],
                        [-3.7211999566810587, 40.41563617253719],
                        [-3.7211996585017926, 40.41560824637715],
                        [-3.721150157449075, 40.41560855514652]
                    ],
                    [
                        [-3.721260835104088, 40.41548714363045],
                        [-3.7212219511090683, 40.41548828710062],
                        [-3.7212160966125767, 40.415491927236594],
                        [-3.721188031570835, 40.41551282309202],
                        [-3.721190898542824, 40.41556055311452],
                        [-3.721222980337708, 40.41558467739598],
                        [-3.7212866245246525, 40.41558428036298],
                        [-3.7212912908093743, 40.41557974673244],
                        [-3.7213158296797295, 40.41555977375542],
                        [-3.72131649840387, 40.41551202167758],
                        [-3.721282040182673, 40.41548611043945],
                        [-3.721260835104088, 40.41548714363045]
                    ]
                ]
            ]
        }
    }]
}

By default Gson does not serialize null values. Since "ELEMENTO": null , it is excluded by default. That is the reason for the empty output.

To force the serialization of null values, use the following code:

GsonBuilder builder = new GsonBuilder();
builder.serializeNulls();
Gson gson = builder.create();
String property = gson.toJson(property);

The GsonBuilder creates a Gson that serializes null values just as you want to have it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM