Я использую класс Jackson ObjectMapper так:
objectMapper.treeToValue(jsonNode, MyClass.class)
где jsonNode - это экземпляр JsonNode.
Когда я звоню treeToValue(), я получаю MismatchedInputException с сообщением
Cannot deserialize instance of com.example.MyField` out of START_OBJECT token
потому что MyField определяется как строка внутри MyClass, но это объект JSON внутри переменной jsonNode. Я полностью согласен с jsonNode, имеющим несоответствующий тип для одного из его полей, но я бы предпочел, чтобы ObjectMapper просто не пытался сериализовать это поле и игнорировать его вместо того, чтобы бросать MismatchedInputException.
Я пробовал использовать
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
но это просто игнорирует отсутствующие поля, это не делает ничего, чтобы предотвратить MismatchedInputException для существующего поля.
@PerpetualJ Верно, я все еще хочу, чтобы все остальные поля были сериализованы. Похоже, если я поймаю MismatchedInputException, он просто пропустит весь процесс сериализации
см. этот вопрос и несколько хитрых ответов: stackoverflow.com/questions/4783421/…
@ user2121620 Я считаю, что он завершит процесс сериализации, если вы поймаете исключение.




В сообщении, на которое ссылается diginoise, вы должны взглянуть на этот ответ:
Вы можете рекурсивно удалить недопустимые поля и повторить попытку. Вот что я придумал (можно упростить в зависимости от ваших потребностей в ведении журнала и обработке исключений).
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);
Я не думаю, что вы можете игнорировать его с точки зрения функциональности, если вам не требуется поле; в этом случае вы мог
catchвMismatchedInputExceptionи ничего не делаете. Однако я не уверен, что это именно то, чего вы хотите достичь.