JAX-RS: обработка исключений из вызова метода во время десериализации JSON с использованием сопоставителя исключений

Я разрабатываю RESTful API с использованием JAX-RS. Один из его интерфейсов служит для добавления новых сущностей в базу данных; сущности предоставляются как объекты JSON. Теперь JAX-RS поддерживает десериализацию этих объектов "на лету" перед вызовом метода, обрабатывающего запрос API, что позволяет получить объект реального класса Java, которому должен быть сопоставлен объект JSON:

@POST
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public City createCity(City city) {
    // persist city in some fashion and return it
}

Cityимеет атрибут, содержащий его имя. Имя по произвольным причинам не должно быть длиннее 32 символов. Установщик для этого атрибута проверяет это условие и выдает исключение, если условие не выполняется.

public void setName(String name) {
    if (name == null || name.length() > 32)
        throw new IllegalCityNameException();
    // set city name
}

Это исключение, в свою очередь, сопоставляется с ответом через ExceptionMapper:

@Provider
public class InvalidCityNameExceptionMapper implements ExceptionMapper<InvalidCityNameException> {
    @Override
    public Response toResponse(final InvalidCityNameException e) {
        // create and return appropriate response
    }
}

Я бы хотел, чтобы в случае, если объект JSON, предоставленный клиентом, нарушает ограничение длины названия города, InvalidCityNameException что брошено обрабатывается InvalidCityNameExceptionMapper. Это отлично работает, если исключение возникает при создании экземпляраCity "вручную" (например, после получения атрибутов в APPLICATION_FORM_URLENCODED request), но с указанным выше подходом к принятию JSON InvalidCityNameException обернут дальнейшими исключениями:

org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage An unexpected error occurred during error handling. No further error processing will occur.
    org.apache.cxf.interceptor.Fault
        <snip>
    Caused by: javax.json.bind.JsonbException
        <snip>
    Caused by: org.apache.johnzon.mapper.MapperException
        <snip>
    Caused by: java.lang.reflect.InvocationTargetException
        <snip>
    Caused by: com.example.City$InvalidCityNameException: City name is too long (max. 32 characters)
        <snip>

Я понимаю, почему это происходит (вызов метода через отражение работает так же, как и он), однако я хотел бы знать, есть ли способы обойти это более элегантно, чем явное копирование каждого отдельного атрибута из общего объекта JSON в City пример.

0 ответов

Другие вопросы по тегам