How to using ObjectMapper to map value of an json property to Object when my object have an contractor set this property is null

Viewed 331

I am usng google DirectionsResul Object

And then I want to using Object mapper to mapping this json to DirectionsResul Object

{
  "geocoded_waypoints": [],
  "routes": [
    {
      "bounds": {},
      "legs": [
        {
          "distance": {
            "human_readable": "13 km",
            "in_meters": 13175
          },
          "duration": {
            "human_readable": "37 phút",
            "in_seconds": 2206
          },
          "steps": []
        }
      ],
      "overview_polyline": {
        "points": "aaaa"
      },
      "warnings": [],
      "waypoint_order": []
    }
  ]
}

Using this code

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

DirectionsResult result;
result = objectMapper.readValue(json, DirectionsResult.class.);

All is ok but overview_polyline can't mapping, the points value is null and I see in the EncodedPolyline have a contractor like this

public EncodedPolyline() {
        this.points = null;
    }

So how can I mapping the points value to the DirectionsResul Object

Here is my result I got Result

Here is all the code that can run

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.maps.model.DirectionsResult;
public void testGetDirections() throws NetworkException {
String json = "{\n" +
                "  \"geocoded_waypoints\": [],\n" +
                "  \"routes\": [\n" +
                "    {\n" +
                "      \"bounds\": {\n" +
                "        \"northeast\": {\n" +
                "          \"lat\": 34.1358593,\n" +
                "          \"lng\": -117.922066\n" +
                "        },\n" +
                "        \"southwest\": {\n" +
                "          \"lat\": 33.815582,\n" +
                "          \"lng\": -118.3516983\n" +
                "        }\n" +
                "      },\n" +
                "      \"legs\": [\n" +
                "        {\n" +
                "          \"distance\": {\n" +
                "            \"human_readable\": \"13 km\",\n" +
                "            \"in_meters\": 13175\n" +
                "          },\n" +
                "          \"duration\": {\n" +
                "            \"human_readable\": \"37 phút\",\n" +
                "            \"in_seconds\": 2206\n" +
                "          },\n" +
                "          \"steps\": [\n" +
                "            {\n" +
                "              \"distance\": {\n" +
                "                \"human_readable\": \"10 ft\",\n" +
                "                \"in_meters\": 3\n" +
                "              },\n" +
                "              \"duration\": {\n" +
                "                \"human_readable\": \"1 min\",\n" +
                "                \"in_seconds\": 0\n" +
                "              }\n" +
                "            }\n" +
                "          ]\n" +
                "        }\n" +
                "      ],\n" +
                "      \"overview_polyline\": {\n" +
                "        \"points\": \"{ashdasda}\"\n" +
                "      },\n" +
                "      \"warnings\": [],\n" +
                "      \"waypoint_order\": []\n" +
                "    }\n" +
                "  ]\n" +
                "}";

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        DirectionsResult goongMapsDirectionResult;


        try {
            goongMapsDirectionResult = objectMapper.readValue(json, DirectionsResult.class.);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
1 Answers

The problem is that there is no setter for points on EncodedPolyline.

One way to work around this is to use a DeserializationProblemHandler:

public class SO69242058 {

    public static void main(String args[]) throws JsonProcessingException {
        String json = "{\n" +
                      "  \"geocoded_waypoints\": [],\n" +
                      "  \"routes\": [\n" +
                      "    {\n" +
                      "      \"bounds\": {\n" +
                      "        \"northeast\": {\n" +
                      "          \"lat\": 34.1358593,\n" +
                      "          \"lng\": -117.922066\n" +
                      "        },\n" +
                      "        \"southwest\": {\n" +
                      "          \"lat\": 33.815582,\n" +
                      "          \"lng\": -118.3516983\n" +
                      "        }\n" +
                      "      },\n" +
                      "      \"legs\": [\n" +
                      "        {\n" +
                      "          \"distance\": {\n" +
                      "            \"human_readable\": \"13 km\",\n" +
                      "            \"in_meters\": 13175\n" +
                      "          },\n" +
                      "          \"duration\": {\n" +
                      "            \"human_readable\": \"37 phút\",\n" +
                      "            \"in_seconds\": 2206\n" +
                      "          },\n" +
                      "          \"steps\": [\n" +
                      "            {\n" +
                      "              \"distance\": {\n" +
                      "                \"human_readable\": \"10 ft\",\n" +
                      "                \"in_meters\": 3\n" +
                      "              },\n" +
                      "              \"duration\": {\n" +
                      "                \"human_readable\": \"1 min\",\n" +
                      "                \"in_seconds\": 0\n" +
                      "              }\n" +
                      "            }\n" +
                      "          ]\n" +
                      "        }\n" +
                      "      ],\n" +
                      "      \"overview_polyline\": {\n" +
                      "        \"points\": \"{ashdasda}\"\n" +
                      "      },\n" +
                      "      \"warnings\": [],\n" +
                      "      \"waypoint_order\": []\n" +
                      "    }\n" +
                      "  ]\n" +
                      "}";

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        //objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper.addHandler(new DeserializationProblemHandler() {

            @Override
            public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser p,
                                                 JsonDeserializer<?> deserializer, Object beanOrClass,
                                                 String propertyName) throws IOException {
                EncodedPolyline encodedPolyline = (EncodedPolyline)beanOrClass;
                try {
                    Field f = EncodedPolyline.class.getDeclaredField("points");
                    f.setAccessible(true);
                    f.set(encodedPolyline, p.readValueAs(String.class));
                } catch (NoSuchFieldException | IllegalAccessException e) {
                   throw new RuntimeException(e);
                }
                return true;
            }
        });

        DirectionsResult goongMapsDirectionResult;

        goongMapsDirectionResult = objectMapper.readValue(json, DirectionsResult.class);
    }
}

I've removed objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) so that the error occurs when Jackson tries to set points. Then we set it reflectively.

Related