Я разработал службу Java REST с использованием JSON-B для сопоставления входящей полезной нагрузки с POJO.
Теперь я хотел бы проверить входящую полезную нагрузку, возможно, по схеме JSON, но пока я не смог найти ничего в этом смысле ...
Можно ли переопределить процесс сопоставления JSON-B по умолчанию, чтобы перехватить любое исключение сопоставления и обработать его самостоятельно?




Для этого вы можете зарегистрировать своего собственного провайдера JAX-RS, который выполняет (де) сериализацию JSON и обрабатывает там любые ошибки.
Например:
@Consumes({ "*/*" })
@Provider
public class JsonBProvider implements MessageBodyReader<Object> {
private static final Jsonb jsonb = JsonbBuilder.create();
@Override
public boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations,
MediaType mediaType) {
return true;
}
@Override
public Object readFrom(Class<Object> clazz, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
InputStream entityStream)
throws IOException, WebApplicationException {
try {
return this.jsonb.fromJson(entityStream, clazz);
} catch (Exception e) {
// Do your custom handling here
}
}
}
Это переопределит десериализацию, которая происходит через JAX-RS и JSON-B.
ПРИМЕЧАНИЕ. Если вы хотите сделать то же самое и для сериализации, вы можете реализовать MessageBodyWriter<Object> аналогичным образом.
Проверка и десериализация - это разные задачи, поэтому я бы связал их вместе, только если мне это действительно нужно, например если вам действительно нужно использовать схемы JSON. Но если вы можете выбрать свой собственный способ объявления ограничений, я рекомендую валидацию bean-компонентов, например ресурс JAX-RS, подобный этому (обратите внимание на аннотацию @Valid):
@Path("ping")
public class PingBoundary {
@POST
public String ping(@NotNull @Valid Person addressee) {
return "Hi " + addressee.getName() + "!";
}
}
И такой класс полезной нагрузки (с использованием lombok @Data annotation):
@Data
public class Person {
private String name;
@Min(0)
private short age;
}
Передача недопустимого age из -2 дает вам 400 Bad Request с полезным телом ответа:
{
"classViolations": [],
"exception": null,
"fieldViolations": [],
"parameterViolations": [
{
"constraintType": "PARAMETER",
"message": "must be greater than or equal to 0",
"path": "ping.addressee.age",
"value": "-2"
}
],
"propertyViolations": [],
"returnValueViolations": []
}
Обратите внимание, что вы должны передать -parameters компилятору, иначе path будет ping.arg0.age.
Если вы действительно придерживаетесь схемы JSON, проверка документа JSON при его десериализации может быть достигнута с помощью Оправдывать. Существует пример Привязка, который показывает, как использовать валидатор JSON с JSON-B. Я надеюсь, что пример кода может вам помочь.
Полное раскрытие информации: я являюсь автором библиотеки.