Я изучаю undertow, потому что я видел, что это хороший выбор, если вы хотите реализовать неблокирующий ввод-вывод и хотите иметь реактивный прослушиватель http.
Undertow использует обработчики для обработки http-запросов неблокирующим способом.
Если у меня есть какая-то логика, которая должна быть реализована между запросом и ответом, как сделать эту логику тоже неблокируемой внутри обработчика откатов?
Я имею в виду, если он вставлен (или вызван) в метод handleRequest () уже отправлен в рабочий поток и , то уже неблокирует или вам нужно использовать CompletableFuture или Rx Observable или любую другую реактивную библиотеку, чтобы гарантировать, что весь стек является реактивным?
Это мой класс Handler в качестве заголовка примера, я имитирую читать Json, который будет проанализирован в объекте Person.class и преобразован (бизнес-логика), а затем возвращен обратно как ответ Json.
Я написал две альтернативы, чтобы лучше понять, как сделать весь стек реагирующим и неблокирующим.
Какой из них мне нужно использовать?
public class DoBusinessLogicHandler implements HttpHandler {
JsonConverter json = JsonConverter.getInstance();
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
if (exchange.isInIoThread()) {
exchange.dispatch(this);
return;
}
Pooled<ByteBuffer> pooledByteBuffer = exchange.getConnection().getBufferPool().allocate();
ByteBuffer byteBuffer = pooledByteBuffer.getResource();
byteBuffer.clear();
exchange.getRequestChannel().read(byteBuffer);
int pos = byteBuffer.position();
byteBuffer.rewind();
byte[] bytes = new byte[pos];
byteBuffer.get(bytes);
byteBuffer.clear();
pooledByteBuffer.free();
String requestBody = new String(bytes, Charset.forName("UTF-8") );
/* FIRST ALTERNATIVE:
you can call the business logic directly because the whole body of handleRequest() is managed reactively
*/
Person person = (Person) json.getObjectFromJson(requestBody, Person.class);
Person p = transform(person);
sendResponse(exchange, json.getJsonOf(p));
/* SECOND ALTERNATIVE
you must wrap business logic within a reactive construction (RxJava, CompletableFuture, ecc.) in order to
have all the stack reactive
*/
CompletableFuture
.supplyAsync(()-> (Person) json.getObjectFromJson(requestBody, Person.class))
.thenApply(p -> transform(p))
.thenAccept(p -> sendResponse(exchange, json.getJsonOf(p)));
}
/* it could be also a database fetch or whatever */
private Person transform(Person p){
if(p!=null){
p.setTitle(p.getTitle().toUpperCase());
p.setName(p.getName().toUpperCase());
p.setSurname(p.getSurname().toUpperCase());
}
return p;
}
private void sendResponse(HttpServerExchange exchange, String response){
exchange.getResponseHeaders()
.put(Headers.CONTENT_TYPE, "application/json");
exchange.getResponseSender()
.send(response);
}
}