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

Я разрабатываю 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), но с вышеупомянутым подходом принятия 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>

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...