Undertow处理程序使所有堆栈成为非阻塞

时间:2019-01-11 07:44:56

标签: java wildfly reactive-programming nonblocking undertow

我正在研究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);
  }


}

0 个答案:

没有答案