Akka http с помощью Java - получить строку из RequestEntity

java asynchronous akka unmarshalling akka-http

1317 просмотра

2 ответа

85207 Репутация автора

Я пытаюсь получить тело запроса http, но кажется, что это не так просто, как может показаться, если, конечно, я что-то упустил.

У меня есть экземпляр HttpRequest(из akka.http.javadsl.model), и из этого я могу получить RequestEntity, но я не могу понять, как извлечь строку из сущности.
Я хочу сделать это синхронно, просто простая операция по извлечению строки.

Я пробовал два разных пути:

(1)

Source<ByteString, Object> source = RequestEntity.getDataBytes();

Я не уверен, что я должен делать с этим source, у него много методов, и неясно, как их использовать, и может ли какой-нибудь из них действительно помочь мне.

(2)

Unmarshaller<HttpEntity, String> unmarshaller = Unmarshaller.entityToString();
CompletionStage<String> result = unmarshaller.unmarshall(entity, ExecutionContext, Materializer);

Вызов unmarshaller.unmarshallтребует не только экземпляра, RequestEntityно ExecutionContextи a и a, Materializerкоторого у меня нет в части демаршаллинга, также он возвращает a, CompletionStage<String>который является полностью избыточным, поскольку я хочу, чтобы это было синхронизировано.

Документация и примеры для java не очень помогают, поскольку они очень короткие и краткие, если они вообще существуют, например, в разделе Marshalling & Unmarshalling :

Используйте предопределенные Unmarshaller.entityToString, Unmarshaller.entityToByteString, Unmarshaller.entityToByteArray, Unmarshaller.entityToCharArray для преобразования в эти основные типы

Как видите, это не очень информативно.

Есть идеи?

Автор: Nitzan Tomer Источник Размещён: 18.07.2016 08:22

Ответы (2)


0 плюса

9751 Репутация автора

Документация по Java в значительной степени находится в стадии разработки, и это одна из областей, где отсутствуют образцы.

Чтобы ответить на ваш конкретный вопрос, используя entityдирективу с одним из предопределенных маршаллеров, выглядело бы так:

path("example", () ->
  entity(Unmarshaller.entityToString(), (string) -> {
    System.out.println("request body: " + string);
    return complete("ok");
  })
)

Обратите внимание, что он прочитает все тело запроса в память JVM, что может потребовать некоторых мыслей. Существует ограничение по умолчанию в 8M для запроса органов , которые могут быть изменены конфигурации или переопределены для конкретного пути , используя withSizeLimitи withoutSizeLimitдирективы.

Я открыл билет Akka 21001 для отслеживания добавления этого в документы.

Автор: johanandren Размещён: 20.07.2016 01:23

2 плюса

4013 Репутация автора

Вы можете использовать глобальные ExecutionContextи те же, которые Materializerиспользуются для запуска akka-http. Вам нужно будет составить тот, Futureкоторый делает HTTP-запрос, с запросом, предоставленным Unmarshaller:

    import akka.actor.ActorSystem;
    import akka.dispatch.ExecutionContexts;
    import akka.http.javadsl.Http;
    import akka.http.javadsl.model.HttpRequest;
    import akka.http.javadsl.model.HttpResponse;
    import akka.http.javadsl.model.ResponseEntity;
    import akka.http.javadsl.unmarshalling.Unmarshaller;
    import akka.stream.ActorMaterializer;
    import akka.stream.Materializer;

    ActorSystem system = ActorSystem.create();
    Materializer materializer = ActorMaterializer.create(system);

    Http.get(system).
        singleRequest(HttpRequest.create("http://stackoverflow.com/"), materializer).
        thenCompose(response -> Unmarshaller.entityToString().unmarshal(response.entity(), ExecutionContexts.global(), materializer)).
        thenAccept(System.out::println);
Автор: UnclickableCharacter Размещён: 28.04.2017 06:29
Вопросы из категории :
32x32