我可以忽略 ObjectMapper 中的 MismatchedInputException 吗?
Can I ignore MismatchedInputException within ObjectMapper?
我正在使用 Jackson ObjectMapper class 像这样:
objectMapper.treeToValue(jsonNode, MyClass.class)
其中 jsonNode
是 JsonNode 的实例。
当我调用 treeToValue()
时,我收到 MismatchedInputException
消息
Cannot deserialize instance of com.example.MyField` out of START_OBJECT token
因为 MyField
被定义为 MyClass
内部的字符串,但它是 jsonNode
变量内部的 JSON 对象。我完全同意 jsonNode
的其中一个字段具有不匹配的类型,但我宁愿 ObjectMapper
只是不尝试序列化该字段并忽略它而不是抛出 MismatchedInputException
.
我试过使用
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
但这只是忽略了缺失的字段,它不会采取任何措施来防止现有字段的 MismatchedInputException
。
在 diginoise 提到的 post 中,你应该看看这个回复:
您可以递归地删除违规字段并重试。这是我想出的(可以根据您的日志记录和异常处理需求进行简化)。
public class YourClass {
private static final Logger LOGGER = Logger
.getLogger(YourClass.class.getName());
public final static ObjectMapper mapper = new ObjectMapper().configure(
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
public static <T> T toTypedObject(Class<T> type, JsonNode tree) {
return toTypedObject(type, tree, true);
}
private static <T> T toTypedObject(Class<T> type, JsonNode tree,
boolean topLevel) {
T object;
try {
object = mapper.treeToValue(tree, type);
} catch (MismatchedInputException e) {
String originalTree = tree.toString();
object = toTypedObject(type, tree, originalTree, e);
if (topLevel) {
LOGGER.log(Level.WARNING, "Failed to convert node tree to a "
+ type.getSimpleName()
+ " object without modifications: " + originalTree, e);
LOGGER.log(Level.INFO,
"Modified node tree was successfully converted to a "
+ type.getSimpleName() + " object: " + tree);
}
} catch (JsonProcessingException e) {
throw new YourException("Failed to convert node tree to a "
+ type.getSimpleName() + " object: " + tree, e);
}
return object;
}
private static <T> T toTypedObject(Class<T> type, JsonNode tree,
String originalTree,
MismatchedInputException mismatchedInputException) {
T object;
List<Reference> path = mismatchedInputException.getPath();
if (path != null && !path.isEmpty()) {
try {
ObjectNode subNode = (ObjectNode) tree;
for (int i = 0; i < path.size(); i++) {
String fieldName = path.get(i).getFieldName();
if (i + 1 < path.size()) {
subNode = (ObjectNode) tree.get(fieldName);
} else {
subNode.remove(fieldName);
}
}
object = toTypedObject(type, tree, false);
} catch (Exception e) {
throw new YourException("Failed to convert node tree to a "
+ type.getSimpleName() + " object: " + originalTree,
mismatchedInputException);
}
} else {
throw new YourException(
"Failed to convert node tree to a " + type.getSimpleName()
+ " object: " + originalTree,
mismatchedInputException);
}
return object;
}
}
通话方式:
YourObject yourObject = YourClass.toTypedObject(YourObject.class, tree);
我正在使用 Jackson ObjectMapper class 像这样:
objectMapper.treeToValue(jsonNode, MyClass.class)
其中 jsonNode
是 JsonNode 的实例。
当我调用 treeToValue()
时,我收到 MismatchedInputException
消息
Cannot deserialize instance of com.example.MyField` out of START_OBJECT token
因为 MyField
被定义为 MyClass
内部的字符串,但它是 jsonNode
变量内部的 JSON 对象。我完全同意 jsonNode
的其中一个字段具有不匹配的类型,但我宁愿 ObjectMapper
只是不尝试序列化该字段并忽略它而不是抛出 MismatchedInputException
.
我试过使用
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
但这只是忽略了缺失的字段,它不会采取任何措施来防止现有字段的 MismatchedInputException
。
在 diginoise 提到的 post 中,你应该看看这个回复:
您可以递归地删除违规字段并重试。这是我想出的(可以根据您的日志记录和异常处理需求进行简化)。
public class YourClass {
private static final Logger LOGGER = Logger
.getLogger(YourClass.class.getName());
public final static ObjectMapper mapper = new ObjectMapper().configure(
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
public static <T> T toTypedObject(Class<T> type, JsonNode tree) {
return toTypedObject(type, tree, true);
}
private static <T> T toTypedObject(Class<T> type, JsonNode tree,
boolean topLevel) {
T object;
try {
object = mapper.treeToValue(tree, type);
} catch (MismatchedInputException e) {
String originalTree = tree.toString();
object = toTypedObject(type, tree, originalTree, e);
if (topLevel) {
LOGGER.log(Level.WARNING, "Failed to convert node tree to a "
+ type.getSimpleName()
+ " object without modifications: " + originalTree, e);
LOGGER.log(Level.INFO,
"Modified node tree was successfully converted to a "
+ type.getSimpleName() + " object: " + tree);
}
} catch (JsonProcessingException e) {
throw new YourException("Failed to convert node tree to a "
+ type.getSimpleName() + " object: " + tree, e);
}
return object;
}
private static <T> T toTypedObject(Class<T> type, JsonNode tree,
String originalTree,
MismatchedInputException mismatchedInputException) {
T object;
List<Reference> path = mismatchedInputException.getPath();
if (path != null && !path.isEmpty()) {
try {
ObjectNode subNode = (ObjectNode) tree;
for (int i = 0; i < path.size(); i++) {
String fieldName = path.get(i).getFieldName();
if (i + 1 < path.size()) {
subNode = (ObjectNode) tree.get(fieldName);
} else {
subNode.remove(fieldName);
}
}
object = toTypedObject(type, tree, false);
} catch (Exception e) {
throw new YourException("Failed to convert node tree to a "
+ type.getSimpleName() + " object: " + originalTree,
mismatchedInputException);
}
} else {
throw new YourException(
"Failed to convert node tree to a " + type.getSimpleName()
+ " object: " + originalTree,
mismatchedInputException);
}
return object;
}
}
通话方式:
YourObject yourObject = YourClass.toTypedObject(YourObject.class, tree);