我正在研究underwow,因为如果您想实现非阻塞IO并且想要使用响应式HTTP侦听器,那么我发现这是一个不错的选择。
Undertow使用处理程序以非阻塞方式处理http请求。
如果我在请求和响应之间要实现一些逻辑,那么如何在underwow处理程序内部使该逻辑也成为非阻塞性的?
我的意思是,如果将它插入(或调用)了 handleRequest() 方法中,并且该方法已经分派到工作线程中,并且则已经非阻塞< / em>还是需要使用 CompletableFuture或Rx Observable 或任何其他反应式库来确保所有堆栈都是反应式的?
这是我的Handler类,例如,我模拟读取一个Json,该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);
}
}