#java #web-services #cxf
#java #веб-сервисы #cxf
Вопрос:
У меня есть служба OSGi, которую я предоставил с помощью CXF как простой веб-сервис и для которой я создал клиент, который вызывает его методы. Методы этой службы принимают в качестве одного из своих аргументов подписанный билет, который идентифицирует клиента, выполняющего запрос. Чтобы внедрить этот билет во все запросы, поступающие от моего клиента, я создал перехватчик CXF out, который я привязал к фазе УСТАНОВКИ и который отвечает за внедрение билета в исходящее сообщение.
В случае, если срок действия билета, введенного моим перехватчиком, истек, служба выдаст исключение, которое я хотел бы иметь возможность перехватить, получить новый билет и повторить запрос с этим новым билетом, чтобы полностью абстрагировать функциональность управления билетами от остальной части моего кода. Поэтому я создал перехватчик ошибок in, который я привязал к предварительной ЛОГИЧЕСКОЙ фазе и в котором я могу определить, был ли выброшен конкретный тип исключения, который меня интересует. Однако я не уверен, как я могу повторить запрос и вернуть результат второго запроса вместо первого. Предлагает ли мне CXF способ сделать это?
Ответ №1:
Поскольку я не смог найти способ повторить запрос через перехватчик ошибок, я закончил тем, что использовал обработчик вызовов, чтобы позволить мне управлять запросом (эффективно оборачивая прокси, который я получаю от 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;
}
}