Я пытался использовать 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
Что не так с CompletableFuture?