Повторите запрос CXF в случае ошибки


У меня есть сервис OSGi, который я представил с помощью CXF как простой веб-сервис и для которого я создал клиент, который вызывает его методы. Методы этой службы принимают в качестве одного из своих аргументов подписанный билет, который идентифицирует клиента, выполняющего запрос. Чтобы внедрить этот билет во все запросы, поступающие от моего клиента, я создал перехватчик CXF out, который я привязал к фазе настройки и который отвечает за внедрение билета в исходящий сообщение.

В случае, если срок действия билета, введенного моим перехватчиком, истек, сервис выдаст исключение, которое я хотел бы поймать, получить новый билет и повторить запрос с этим новым билетом, чтобы полностью абстрагировать функциональность управления билетами от остальной части моего кода. Поэтому я создал перехватчик ошибок in, который я привязал к ПРЕДЛОГИЧЕСКОЙ фазе и в котором я могу определить, является ли конкретный тип исключения, который меня интересует был брошен. Однако я не уверен, как я могу повторить запрос и вернуть результат второго запроса вместо первого. CXF предлагает мне способ сделать это?

1 2
cxf

1 ответ:

Поскольку я не смог найти способ повторить запрос через перехватчик ошибок, я в конечном итоге использовал InvocationHandler, чтобы позволить мне контролировать запрос (эффективно оборачивая прокси, который я получаю от CXF, в другой прокси). В итоге я получил примерно следующее:

ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
// Configure factory
MyService serviceClient = (MyService) factory.create(MyService.class);
MyService  proxy = (MyService) Proxy.newProxyInstance(
        ServiceInvocationHandler.class.getClassLoader(), 
        new Class[] { MyService.class },
        new ServiceInvocationHandler(serviceClient));

Где ServiceInvocationHandler:

public class ServiceInvocationHandler implements InvocationHandler {
    private final Object proxied;
    private SignedTicket ticket;

    public ServiceInvocationHandler(Object proxied) {
        this.proxied = proxied;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object retVal = null;
        try {
            // Generate a ticket if the one held locally by this class is null
            // and inject it in the method arguments
            retVal = method.invoke(proxied, args);
        } catch (Throwable t) {
            if (t.getCause() instanceof InvalidTicketException) {
                // Get a fresh ticket and inject it in the method arguments
                retVal = method.invoke(proxied, args);
            }
        }    
        return retVal;
    }
}