下面列出了怎么用com.fasterxml.jackson.databind.deser.DeserializationProblemHandler的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* This method creates a copy of the default ObjectMapper configuration and adds special Json schema compatibility handlers
* for supporting draft-03, draft-04 and draft-06 level at the same time.
*
* Auto converts "$id" to "id" property for draft-04 compatibility.
*
* In case the provided schema specification to read uses draft-04 and draft-06 specific features such as "examples" or a list of "required"
* properties as array these information is more or less lost and auto converted to draft-03 compatible defaults. This way we can
* read the specification to draft-03 compatible objects and use those.
* @return duplicated ObjectR
*/
public static ObjectReader reader() {
return JsonUtils.copyObjectMapperConfiguration()
.addHandler(new DeserializationProblemHandler() {
@Override
public Object handleUnexpectedToken(DeserializationContext ctxt, Class<?> targetType, JsonToken t,
JsonParser p, String failureMsg) throws IOException {
if (t == JsonToken.START_ARRAY && targetType.equals(Boolean.class)) {
// handle Json schema draft-04 array type for required field and resolve to default value (required=true).
String[] requiredProps = new StringArrayDeserializer().deserialize(p, ctxt);
LOG.warn("Auto convert Json schema draft-04 \"required\" array value '{}' to default \"required=false\" value for draft-03 parser compatibility reasons", Arrays.toString(requiredProps));
return null;
}
return super.handleUnexpectedToken(ctxt, ctxt.constructType(targetType), t, p, failureMsg);
}
})
.addMixIn(JsonSchema.class, MixIn.Draft6.class)
.reader()
.forType(JsonSchema.class);
}
@Test
public void testDateTimeExceptionIsHandled() throws Throwable
{
LocalDateTime now = LocalDateTime.now();
DeserializationProblemHandler handler = new DeserializationProblemHandler() {
@Override
public Object handleWeirdStringValue(DeserializationContext ctxt, Class<?> targetType,
String valueToConvert, String failureMsg) throws IOException {
if (LocalDateTime.class == targetType) {
if ("now".equals(valueToConvert)) {
return now;
}
}
return NOT_HANDLED;
}
};
ObjectMapper handledMapper = mapperBuilder().addHandler(handler).build();
assertEquals(now, handledMapper.readValue(quote("now"), LocalDateTime.class));
}
@Test
public void testUnexpectedTokenIsHandled() throws Throwable
{
LocalDateTime now = LocalDateTime.now();
DeserializationProblemHandler handler = new DeserializationProblemHandler() {
@Override
public Object handleUnexpectedToken(DeserializationContext ctxt, JavaType targetType,
JsonToken t, JsonParser p, String failureMsg) throws IOException {
if (targetType.hasRawClass(LocalDateTime.class)) {
if (t.isBoolean()) {
return now;
}
}
return NOT_HANDLED;
}
};
ObjectMapper handledMapper = mapperBuilder().addHandler(handler).build();
assertEquals(now, handledMapper.readValue("true", LocalDateTime.class));
}
@Test
public void testDateTimeExceptionIsHandled() throws Throwable
{
LocalDateTime now = LocalDateTime.now();
DeserializationProblemHandler handler = new DeserializationProblemHandler() {
@Override
public Object handleWeirdKey(DeserializationContext ctxt, Class<?> targetType,
String valueToConvert, String failureMsg) throws IOException {
if (LocalDateTime.class == targetType) {
if ("now".equals(valueToConvert)) {
return now;
}
}
return NOT_HANDLED;
}
};
Map<LocalDateTime, String> value = mapperBuilder().addHandler(handler)
.build()
.readValue(mapAsString("now", "test"), TYPE_REF);
assertEquals(asMap(now, "test"), value);
}
/**
* Create a DeserializationProblemHandler that may be added to an
* ObjectMapper, and will handle unknown properties by forwarding
* the error information to the given consumer, if it is not
* <code>null</code>
*
* @param jsonErrorConsumer The consumer for {@link JsonError}s
* @return The problem handler
*/
private static DeserializationProblemHandler
createDeserializationProblemHandler(
Consumer<? super JsonError> jsonErrorConsumer)
{
return new DeserializationProblemHandler()
{
@Override
public boolean handleUnknownProperty(
DeserializationContext ctxt, JsonParser jp,
JsonDeserializer<?> deserializer, Object beanOrClass,
String propertyName)
throws IOException, JsonProcessingException
{
if (jsonErrorConsumer != null)
{
jsonErrorConsumer.accept(new JsonError(
"Unknown property: " + propertyName,
jp.getParsingContext(), null));
}
return super.handleUnknownProperty(
ctxt, jp, deserializer, beanOrClass, propertyName);
}
};
}
public void testIssue987() throws Exception
{
ObjectMapper jsonMapper = afterburnerMapperBuilder()
.addHandler(new DeserializationProblemHandler() {
@Override
public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser p, JsonDeserializer<?> deserializer, Object beanOrClass, String propertyName) throws IOException, JsonProcessingException {
p.skipChildren();
return true;
}
})
.build();
String input = "[{\"aProperty\":\"x\",\"unknown\":{\"unknown\":{}}}]";
List<Bean987> deserializedList = jsonMapper.readValue(input,
new TypeReference<List<Bean987>>() { });
assertEquals(1, deserializedList.size());
}
protected XmlMapper getXmlMapper() {
final XmlMapper xmlMapper = new XmlMapper(
new XmlFactory(new InputFactoryImpl(), new OutputFactoryImpl()), new JacksonXmlModule());
xmlMapper.setInjectableValues(new InjectableValues.Std().addValue(Boolean.class, Boolean.FALSE));
xmlMapper.addHandler(new DeserializationProblemHandler() {
@Override
public boolean handleUnknownProperty(final DeserializationContext ctxt, final JsonParser jp,
final com.fasterxml.jackson.databind.JsonDeserializer<?> deserializer,
final Object beanOrClass, final String propertyName)
throws IOException, JsonProcessingException {
// skip any unknown property
ctxt.getParser().skipChildren();
return true;
}
});
return xmlMapper;
}
@PrepareForTest(HarParser.class)
@Test
public void testParseHarDeserializationProblemHandlers() throws Exception
{
ObjectMapper objectMapper = mock(ObjectMapper.class);
DeserializationProblemHandler problemHandler = mock(DeserializationProblemHandler.class);
PowerMockito.whenNew(ObjectMapper.class).withAnyArguments().thenReturn(objectMapper);
new HarParser(Arrays.asList(problemHandler, problemHandler));
verify(objectMapper, times(2)).addHandler(problemHandler);
}
private DeserializationConfig(DeserializationConfig src,
LinkedNode<DeserializationProblemHandler> problemHandlers)
{
super(src);
_deserFeatures = src._deserFeatures;
_problemHandlers = problemHandlers;
_nodeFactory = src._nodeFactory;
_parserFeatures = src._parserFeatures;
_parserFeaturesToChange = src._parserFeaturesToChange;
_formatReadFeatures = src._formatReadFeatures;
_formatReadFeaturesToChange = src._formatReadFeaturesToChange;
}
/**
* Method that can be used to add a handler that can (try to)
* resolve non-fatal deserialization problems.
*/
public DeserializationConfig withHandler(DeserializationProblemHandler h)
{
// Sanity check: let's prevent adding same handler multiple times
if (LinkedNode.contains(_problemHandlers, h)) {
return this;
}
return new DeserializationConfig(this,
new LinkedNode<DeserializationProblemHandler>(h, _problemHandlers));
}
/**
* Method for removing all configured problem handlers; usually done to replace
* existing handler(s) with different one(s)
*/
public DeserializationConfig withNoProblemHandlers() {
if (_problemHandlers == null) {
return this;
}
return new DeserializationConfig(this,
(LinkedNode<DeserializationProblemHandler>) null);
}
private GoogleGroupIndex readGoogleGroupIndex(final String group, final String url, int connectTimeout, int readTimeout) {
try {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_XML));
setTimeout(restTemplate, connectTimeout, readTimeout);
ObjectMapper mapper = Jackson2ObjectMapperBuilder.xml().build();
mapper = mapper.addHandler(new DeserializationProblemHandler() {
@Override
public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser p, JsonDeserializer<?> deserializer, Object beanOrClass, String propertyName) throws IOException {
if (beanOrClass instanceof GoogleGroupIndex) {
if ("versions".equals(propertyName)) {
if (((GoogleGroupIndex) beanOrClass).lastArtifactId != null) {
((GoogleGroupIndex) beanOrClass).downloaded.put(((GoogleGroupIndex) beanOrClass).lastArtifactId, p.getText());
((GoogleGroupIndex) beanOrClass).lastArtifactId = null;
}
} else {
((GoogleGroupIndex) beanOrClass).lastArtifactId = propertyName;
}
return true;
}
return false;
}
});
restTemplate.getMessageConverters().clear();
restTemplate.getMessageConverters().add(new MappingJackson2XmlHttpMessageConverter(mapper));
ResponseEntity<GoogleGroupIndex> response = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(requestHeaders), GoogleGroupIndex.class);
GoogleGroupIndex groupIndex = response.getBody();
groupIndex.group = group;
groupIndex.url = url;
return groupIndex.build();
} catch (Exception exception) {
Exceptions.printStackTrace(exception);
}
return null;
}
private GoogleMasterIndex readGoogleMasterIndex(int connectTimeout, int readTimeout) {
try {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_XML));
setTimeout(restTemplate, connectTimeout, readTimeout);
ObjectMapper mapper = Jackson2ObjectMapperBuilder.xml().build();
mapper = mapper.addHandler(new DeserializationProblemHandler() {
@Override
public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser p, JsonDeserializer<?> deserializer, Object beanOrClass, String propertyName) throws IOException {
if (beanOrClass instanceof GoogleMasterIndex) {
((GoogleMasterIndex) beanOrClass).getGroups().put(propertyName, BASE_URL + propertyName.replace(".", "/") + "/" + GROUP_INDEX);
return true;
}
return false;
}
});
restTemplate.getMessageConverters().clear();
restTemplate.getMessageConverters().add(new MappingJackson2XmlHttpMessageConverter(mapper));
ResponseEntity<GoogleMasterIndex> response = restTemplate.exchange(BASE_URL + MASTER_INDEX, HttpMethod.GET, new HttpEntity<>(requestHeaders), GoogleMasterIndex.class);
return response.getBody();
} catch (Exception exception) {
Exceptions.printStackTrace(exception);
}
return null;
}
public static void setObjectMapperLessStrict() {
mapper.addHandler(new DeserializationProblemHandler() {
@Override
public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser p, JsonDeserializer<?> deserializer, Object beanOrClass, String propertyName) throws IOException {
Collection<Object> propIds = (deserializer == null) ? null : deserializer.getKnownPropertyNames();
UnrecognizedPropertyException e = UnrecognizedPropertyException.from(p, beanOrClass, propertyName, propIds);
logger.warn(e.toString());
return e.toString().length() > 0;
}
});
}
public HarParser(List<DeserializationProblemHandler> deserializationProblemHandlers)
{
objectMapper = new ObjectMapper();
deserializationProblemHandlers.forEach(objectMapper::addHandler);
}
public ObjectReader withHandler(DeserializationProblemHandler h) {
return _with(_config.withHandler(h));
}
/**
* Method for getting head of the problem handler chain. May be null,
* if no handlers have been added.
*/
public LinkedNode<DeserializationProblemHandler> getProblemHandlers() {
return _problemHandlers;
}
/**
* Add a deserialization problem handler
*
* @param handler The deserialization problem handler
*/
public void addDeserializationProblemHandler(DeserializationProblemHandler handler);