Хобрук: Ваш путь к мастерству в программировании

Запись тела объекта с помощью Quarkus Resteasy Reactive

Я пытаюсь реализовать фильтр ведения журнала, чтобы регистрировать запрос и ответ конечным точкам API моего приложения Quarkus. Я использую Quarkus 1.13.3.Final и quarkus-resteasy-reactive. У меня проблема с попыткой записать тело запроса при вызове неблокирующей конечной точки. Это код, который я использую для регистрации запроса:

    @ServerRequestFilter(priority = 0)
    public void getFilter(UriInfo info,HttpServerRequest request,ContainerRequestContext ctx) {
        String uuid = UUID.randomUUID().toString();
        ctx.setProperty("log_id", uuid);
        String body = new BufferedReader(new InputStreamReader(ctx.getEntityStream())).lines().collect(Collectors.joining("\n"));
        ctx.setEntityStream(new ByteArrayInputStream(body.getBytes()));
        logger.info("Request: " + uuid + " Method: "+ ctx.getMethod() + " Path: " + info.getPath() + " Remote Address: " +  request.remoteAddress().toString() + " Body: " + body);
    }

Это отлично работает, когда я вызываю конечную точку API с аннотациями @Blocking, но когда я вызываю неблокирующий API, я получаю следующую ошибку:

2021-05-17 10:15:29,159 ERROR [org.jbo.res.rea.ser.cor.ExceptionMapping] (vert.x-eventloop-thread-10) Request failed : java.io.UncheckedIOException: java.io.IOException: Attempting a blocking read on io thread
        at java.base/java.io.BufferedReader$1.hasNext(BufferedReader.java:577)
        at java.base/java.util.Iterator.forEachRemaining(Iterator.java:132)
        at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
        at com.filters.LogginFilter.getFilter(LogginFilter.java:45)
        at com.filters.LogginFilter$GeneratedServerRequestFilter$getFilter.filter(LogginFilter$GeneratedServerRequestFilter$getFilter.zig:73)
        at com.filters.LogginFilter$GeneratedServerRequestFilter$getFilter_Subclass.filter$$superaccessor1(LogginFilter$GeneratedServerRequestFilter$getFilter_Subclass.zig:201)
        at com.filters.LogginFilter$GeneratedServerRequestFilter$getFilter_Subclass$$function$$3.apply(LogginFilter$GeneratedServerRequestFilter$getFilter_Subclass$$function$$3.zig:33)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
        at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:63)
        at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:49)
        at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(InvocationInterceptor_Bean.zig:521)
        at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
        at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)

Есть ли способ обойти это и прочитать тело запроса неблокирующим способом? или другой способ логировать тело запроса?

17.05.2021

Ответы:


1

Вам нужно будет принудительно активировать RESTEasy Reactive все методы JAX-RS в рабочем потоке, а не в цикле событий.

Для этого просто измените свой код на:

@io.smallrye.common.annotation.Blocking
public class MyApplication extends javax.ws.rs.core.Application {

}
17.05.2021
  • Я хотел бы сохранить неблокирующие конечные точки, есть ли способ сделать это, не заставляя все работать в рабочих потоках? принуждение всего к блокировке почти сводит на нет преимущества resteasy-reactive 17.05.2021
  • Нет, нет способа сделать это, если вы хотите прочитать все тело в фильтре запроса. 17.05.2021
  • Вы, конечно, можете открыть вопрос с просьбой о такой функции 17.05.2021
  • Новые материалы

    Основы принципов S.O.L.I.D, Javascript, Git и NoSQL
    каковы принципы S.O.L.I.D? Принципы SOLID призваны помочь разработчикам создавать надежные, удобные в сопровождении приложения. мы видим пять ключевых принципов. Принципы SOLID были разработаны..

    Как настроить Selenium в проекте Angular
    Угловой | Селен Как настроить Selenium в проекте Angular Держите свое приложение Angular и тесты Selenium в одной рабочей области и запускайте их с помощью Mocha. В этой статье мы..

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

    Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
    Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

    Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
    Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

    стройный-i18следующий
    Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..