JAX-RS 2.0 обеспечивает поддержку парадигмы асинхронного программирования, как на клиенте, так и на стороне сервера. Этот пост, в котором описывается функция времени ожидания при выполнении асинхронных запросов REST на стороне сервера с использованием API JAX-RS (2.0)
Не вдаваясь в подробности, приведу краткий обзор. Чтобы выполнить метод в асинхронном режиме, вы просто
- необходимо указать экземпляр интерфейса AsyncResponse в качестве одного из параметров метода
- аннотируйте его, используя аннотацию @Suspended (JAX-RS будет внедрять экземпляр AsyncResponse для вас всякий раз, когда обнаружит эту аннотацию)
- необходимо вызвать запрос в другом потоке — рекомендуемый способ сделать это в Java EE 7 — использовать Managed Service Executor
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
@GET @Produces ( "text/plain" ) public void execute( @Suspended AsyncResponse response){ System.out.println( "Initially invoked on thread - " + Thread.currentThread.getName() + ". This will free up soon !" ); new Thread(){ @Override public void run(){ response.resume( "executed asynchronously on thread - " + Thread.currentThread.getName()); } }.start(); } //JDK 8 version - passing a Runnable (in form of a Lambda Expression) to a thread @GET @Produces ( "text/plain" ) public void execute( @Suspended AsyncResponse response){ System.out.println( "Initially invoked on thread - " + Thread.currentThread.getName() + ". This will free up soon !" ); new Thread(() -> response.resume( "executed asynchronously on thread - " + Thread.currentThread().getName())).start(); } |
За кулисами ??
Базовое соединение ввода / вывода между сервером и клиентом остается открытым. Но есть сценарии, в которых вы бы хотели, чтобы клиент не ждал ответа вечно. В таком случае вы можете выделить время ожидания (порог)
Поведение по умолчанию в случае тайм-аута — ответ HTTP 503 . Если вы хотите переопределить это поведение, вы можете реализовать TimeoutHandler и зарегистрировать его в AsyncResponse. В случае, если вы используете Java 8, вам не нужно беспокоиться о отдельном классе реализации или даже анонимном внутреннем классе — вы можете просто предоставить лямбда-выражение, поскольку TimeoutHandler — это функциональный интерфейс с единственным абстрактным методом.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
@GET @Produces ( "text/plain" ) public void execute( @Suspended AsyncResponse response){ System.out.println( "Initially invoked on thread - " + Thread.currentThread.getName() + ". This will free up soon !" ); //just having this would result in HTTP 503 after 10 seconds response.setTimeout( 10 , TimeUnit.SECONDS); //client will recieve a HTTP 408 (timeout error) after 10 seconds response.setTimeoutHandler((asyncResp) -> asyncResp.resume(Response.status(Response.Status.REQUEST_TIMEOUT)).build()); new Thread(() -> { try { Thread.sleep( 11000 ); } catch (InterruptedException ex) { //ignoring } }).start(); } |
Ура!
Ссылка: | Обработка тайм-аутов в асинхронных запросах в JAX-RS от нашего партнера JCG Абхишека Гупты в блоге Object Oriented .. |