如何使用 ObjectMapper 将 json 属性 的值映射到对象,当我的对象有承包商设置此 属性 为 null
How to using ObjectMapper to map value of an json property to Object when my object have an contractor set this property is null
我正在使用 google DirectionsResul 对象
然后我想使用对象映射器将此 json 映射到 DirectionsResul 对象
{
"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": []
}
]
}
使用此代码
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
DirectionsResult result;
result = objectMapper.readValue(json, DirectionsResult.class.);
一切正常,但overview_polyline无法映射,点值为空
我在 EncodedPolyline 中看到有这样的承包商
public EncodedPolyline() {
this.points = null;
}
那么如何将点值映射到 DirectionsResul 对象
这是我得到的结果
这里是所有可以运行
的代码
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();
}
}
问题是 EncodedPolyline
上的 points
没有 setter。
解决此问题的一种方法是使用 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);
}
}
我删除了 objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
,因此当 Jackson 尝试设置 points
时会出现错误。然后我们反射性地设置它。
我正在使用 google DirectionsResul 对象
然后我想使用对象映射器将此 json 映射到 DirectionsResul 对象
{
"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": []
}
]
}
使用此代码
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
DirectionsResult result;
result = objectMapper.readValue(json, DirectionsResult.class.);
一切正常,但overview_polyline无法映射,点值为空 我在 EncodedPolyline 中看到有这样的承包商
public EncodedPolyline() {
this.points = null;
}
那么如何将点值映射到 DirectionsResul 对象
这是我得到的结果
这里是所有可以运行
的代码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();
}
}
问题是 EncodedPolyline
上的 points
没有 setter。
解决此问题的一种方法是使用 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);
}
}
我删除了 objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
,因此当 Jackson 尝试设置 points
时会出现错误。然后我们反射性地设置它。