Quarkus中如何将Mutiny Uni<Integer>转换为int基础类型
问题本质
Uni<T>是SmallRye Mutiny中代表异步返回结果的容器,不能直接同步转换为内部的T类型,你直接调用client.getMaxRequestId()拿到的只会是Uni实例,而非内部包装的Integer值。
方案1:同步阻塞获取(仅推荐低并发场景使用)
如果必须保留现有同步filter的写法,可以用await方法阻塞等待Uni返回结果,注意要设置超时时间避免请求挂死:
import io.smallrye.mutiny.Uni; import java.time.Duration; public void filter(ContainerRequestContext requestContext) throws IOException { // 阻塞等待结果,1秒超时可根据业务调整 int requestid = client.getMaxRequestId() .await() .atMost(Duration.ofSeconds(1)) .intValue(); rm.name = ConfigProvider.getConfig().getValue("quarkus.application.name", String.class); rm.server = requestContext.getUriInfo().getBaseUri().getHost(); rm.text = requestContext.getUriInfo().getPath(true); rm.requestid = requestid; }
⚠️ 注意:不要在Quarkus的IO事件循环线程中使用该方法,会阻塞线程导致服务吞吐量下降。
方案2:改用响应式过滤器(推荐)
Quarkus原生支持异步响应式过滤器,全程非阻塞不需要主动提取值,是响应式栈的标准实现方式:
import io.smallrye.mutiny.Uni; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.ext.Provider; @Provider public class RequestIdFilter implements ContainerRequestFilter { @Inject RequestIdServices client; @Override public Uni<Void> filter(ContainerRequestContext requestContext) { return client.getMaxRequestId() // Uni返回结果后自动执行后续逻辑,不会阻塞线程 .invoke(requestid -> { rm.name = ConfigProvider.getConfig().getValue("quarkus.application.name", String.class); rm.server = requestContext.getUriInfo().getBaseUri().getHost(); rm.text = requestContext.getUriInfo().getPath(true); rm.requestid = requestid; }) .replaceWithVoid(); } }
额外注意:你的日志服务代码存在查询错误
你当前查询MAX值用了getFirstResult(),该方法是分页查询用来设置偏移量的,无法拿到MAX聚合查询的结果,需要改为getSingleResult():
public Uni<Integer> getMaxRequestId() { Integer result = (Integer) em.createQuery("select MAX(request_id) from service_requests") .getSingleResult(); result = result == null ? 0 : result; return Uni.createFrom().item(result + 1); }
内容的提问来源于stack exchange,提问作者Paul Stoner
相关产品推荐
相关产品推荐

