CompletableFuture в Java-сервлетах - PullRequest
0 голосов
/ 20 февраля 2019

Я пытался использовать Java 8 CompletableFuture в сервлете Java для асинхронной обработки http-запросов (а затем для создания своего рода варианта реализации сервлета 3.1 без использования AsyncContext.

Дело в том, что когда я использую CompletableFuture, я иногда получаю правильный ответ, иногда вообще не получаю ответа, даже если получаю httpCode как 200.

Когда я пытаюсь использовать RxJava Observable эквивалентноCompletableFuture работает нормально.

Это мой код сервлета, вы можете найти синхронный и рабочий код с комментариями:

public class CreateUserNioServlet extends HttpServlet {

  ExecutorService executor = Executors.newFixedThreadPool(10);

  private final UserService service = UserServiceImpl.inject();

  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    /* it works sometimes */
      CompletableFuture.supplyAsync( ()  -> request, executor)
                     .thenApply  (req  -> getJsonData(req))
                     .thenApply  (userData -> service.save(userData))
                     .thenApply  (user -> JsonConverter.getInstance().getJsonOf(user))
                     .thenAccept (jsonResp -> createResponse(request, response, jsonResp));

    /* this code is the synchronous equivalent which always works
      UserData userData = getJsonData(request);
      User user = service.save(userData);
      String jsonResponse = JsonConverter.getInstance().getJsonOf(user);
      createResponse(request, response, jsonResponse);
    */

  }


  private UserData getJsonData(HttpServletRequest req){
    try {
        return (UserData) JsonConverter.getInstance().getDataFromBodyRequest(req, UserData.class);
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
  }

 private void createResponse(HttpServletResponse, String jsonResponse){
    response.setContentType("application/json");
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST");
    response.getWriter().println(jsonResponse);
 }

}

Это команда curl, рабочий и не рабочий ответ.get:

○ → curl -v -i -X ​​POST 'http://localhost:8986/create/user/nio' -H' Тип содержимого: application / json; charset = utf-8 '-d' {"name ":" Alessandro "," фамилия ":" Argentieri "} 'Примечание: ненужное использование -X или --request, POST уже выведено. * Попытка :: 1 ... * TCP_NODELAY set * Подключено к localhost (:: 1) порт 8986 (# 0) POST / create / user / nio HTTP / 1.1 Хост: localhost: 8986 Пользователь-агент: curl / 7.54.0 Принимать: / Тип содержимого: application / json; charset = utf-8 Длина содержимого: 45

  • загрузка полностью отправлена: 45 из 45 байтов

{"id":"ea3b8828-98a1-44f3-a938-40e79043d9db", "name": "Giorgio", "surname": "Loreto"} * Соединение № 0 с хостом localhost осталось без изменений

А теперь следующееНулевой ответ:

○ → curl -v -i -X ​​POST 'http://localhost:8986/create/user/nio' -H' Тип содержимого: application / json; charset = utf-8 '-d'{"name": "Alessandro", "фамилия": "Argentieri"} 'Примечание: не нужноSE -X или --request, POST уже выведен.* Trying :: 1 ... * TCP_NODELAY установлен * Подключен к локальному хосту (:: 1) порт 8986 (# 0) POST / create / user / nio HTTP / 1.1 Хост: localhost: 8986 User-Agent: curl / 7.54.0Принять: / Тип содержимого: application / json; charset = utf-8 Длина содержимого: 45

  • загрузка полностью отправлена: 45 из 45 байт

  • Соединение № 0 с локальным хостом оставлено без изменений

Что не так с CompletableFuture?

...