You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为其他包中的Java类添加无参构造器?解决GeoJsonMultiPolygon无参构造缺失引发的Jackson反序列化异常

How to Deserialize GeoJsonMultiPolygon with Jackson (No No-Arg Constructor)

Got it, this is a classic Jackson deserialization problem when dealing with third-party classes that don't expose a no-arg constructor. Since you can't modify the org.springframework.data.mongodb.core.geo.GeoJsonMultiPolygon code, here are two reliable workarounds to get your deserialization working properly:

Option 1: Custom Jackson Deserializer

We can create a custom JsonDeserializer to manually parse the JSON structure and build the GeoJsonMultiPolygon object ourselves.

Step 1: Create the Custom Deserializer

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.data.mongodb.core.geo.GeoJsonMultiPolygon;
import org.springframework.data.mongodb.core.geo.GeoJsonPolygon;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class GeoJsonMultiPolygonDeserializer extends JsonDeserializer<GeoJsonMultiPolygon> {

    @Override
    public GeoJsonMultiPolygon deserialize(JsonParser parser, DeserializationContext ctx) throws IOException {
        JsonNode rootNode = parser.getCodec().readTree(parser);
        JsonNode coordinatesNode = rootNode.get("coordinates");

        List<GeoJsonPolygon> polygons = new ArrayList<>();

        // Traverse each Polygon in the MultiPolygon
        for (JsonNode polygonNode : coordinatesNode) {
            List<List<GeoJsonPoint>> polygonCoords = new ArrayList<>();

            // Traverse each ring (outer + inner rings) in the Polygon
            for (JsonNode ringNode : polygonNode) {
                List<GeoJsonPoint> ringPoints = new ArrayList<>();

                // Parse each latitude/longitude point
                for (JsonNode pointNode : ringNode) {
                    double longitude = pointNode.get(0).asDouble();
                    double latitude = pointNode.get(1).asDouble();
                    ringPoints.add(new GeoJsonPoint(longitude, latitude));
                }

                polygonCoords.add(ringPoints);
            }

            polygons.add(new GeoJsonPolygon(polygonCoords));
        }

        return new GeoJsonMultiPolygon(polygons);
    }
}

Step 2: Attach the Deserializer to Your Model Field

Update your CountryBoundaries class to use the custom deserializer on the geometry field:

@Getter @Setter @ToString @EqualsAndHashCode @Builder 
@AllArgsConstructor @NoArgsConstructor 
@JsonIgnoreProperties(ignoreUnknown = true) 
@Document(collection = "country-boundaries")
public class CountryBoundaries {
    @Id
    private String id;
    @EqualsAndHashCode.Exclude
    private String type;
    @EqualsAndHashCode.Exclude
    private CountryBoundariesProperties properties;
    @EqualsAndHashCode.Exclude
    @JsonDeserialize(using = GeoJsonMultiPolygonDeserializer.class) // Add this annotation
    private GeoJsonMultiPolygon geometry;
}

Your existing deserialization code will now work as expected, since Jackson will use your custom logic to build the GeoJsonMultiPolygon instance.

Option 2: Use Spring Data MongoDB's Built-In Jackson Module

If you're already using Spring Data MongoDB in your project, you can leverage its pre-built MongoJackson2Module which handles serialization/deserialization for all Spring Data GeoJSON types out of the box.

Update Your Deserialization Code

Modify your ObjectMapper setup to register the module:

ObjectMapper mapper = new ObjectMapper();
// Register the MongoDB Jackson module to handle GeoJSON types
mapper.registerModule(new MongoJackson2Module());

InputStream is = Country.class.getResourceAsStream("/country-boundaries.json");
List<CountryBoundaries> countryBoundaries = mapper.readValue(is, new TypeReference<>(){});
countryBoundariesRepository.saveAll(countryBoundaries);

Verify Dependency

Make sure your project includes the Spring Data MongoDB dependency (for Maven):

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-mongodb</artifactId>
    <version>your-version-here</version>
</dependency>

This is the cleaner option for Spring-based projects, as it eliminates the need for custom deserialization code.


内容的提问来源于stack exchange,提问作者daph111

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 18:58:10