Quarkus中使用HttpServletRequest触发异常的解决方法咨询
问题:Quarkus中使用@Context注入HttpServletRequest触发UnsatisfiedResolutionException
我在使用Quarkus 2.13.8.Final开发Java应用时,编写了一个REST端点并尝试通过@Context注入HttpServletRequest实例,代码如下:
@RequestScoped @Path("/rest/user") @Slf4j public class UserRestAdapter { @GET @Path("/canAccess") public Boolean canAccess(@Context HttpServletRequest request){ log.info("canAccess, creating user context"); if(request == null){ log.info("canAccess, request is null"); } return true; } }
调用该端点时触发如下异常:
javax.ws.rs.WebApplicationException: HTTP 400 Bad Request at org.jboss.resteasy.reactive.server.handlers.ParameterHandler.handle(ParameterHandler.java:66) at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:111) at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:142) at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:576) at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478) at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29) at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: No bean found for required type [interface javax.ws.rs.container.ContainerRequestContext] and qualifiers [[]] at io.quarkus.arc.impl.InstanceImpl.bean(InstanceImpl.java:190) at io.quarkus.arc.impl.InstanceImpl.getInternal(InstanceImpl.java:211) at io.quarkus.arc.impl.InstanceImpl.get(InstanceImpl.java:97) at org.jboss.resteasy.reactive.server.core.parameters.ContextParamExtractor.extractParameter(ContextParamExtractor.java:100) at org.jboss.resteasy.reactive.server.handlers.ParameterHandler.handle(ParameterHandler.java:45)
解决方案
原因分析
你当前使用的是Quarkus默认的RESTEasy Reactive栈,而HttpServletRequest属于传统Servlet API范畴,RESTEasy Reactive默认不支持直接注入Servlet API对象,它更适配JAX-RS标准API或Quarkus原生的Reactive请求API。
方法1:切换到RESTEasy Classic栈
如果你的业务依赖Servlet API,可以修改项目依赖,替换为RESTEasy Classic:
Maven示例(修改pom.xml):
<!-- 移除原有RESTEasy Reactive依赖 --> <!-- <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-reactive</artifactId> </dependency> --> <!-- 添加RESTEasy Classic核心依赖 --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy</artifactId> </dependency> <!-- 如果需要JSON序列化支持,添加对应依赖 --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-jackson</artifactId> </dependency>
切换完成后,原有的@Context HttpServletRequest注入代码即可正常运行。
方法2:使用RESTEasy Reactive兼容的API替代
若想继续使用Reactive栈,推荐用JAX-RS标准的ContainerRequestContext或Quarkus提供的CurrentVertxRequest来获取请求信息:
示例1:注入ContainerRequestContext
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.core.Context; // ... @GET @Path("/canAccess") public Boolean canAccess(@Context ContainerRequestContext requestContext){ // 获取请求头示例 String userAgent = requestContext.getHeaderString("User-Agent"); log.info("User-Agent: {}", userAgent); return true; }
示例2:注入CurrentVertxRequest获取Vertx请求对象
import io.quarkus.vertx.http.runtime.CurrentVertxRequest; import io.vertx.ext.web.HttpServerRequest; import javax.inject.Inject; // ... @Inject CurrentVertxRequest currentVertxRequest; @GET @Path("/canAccess") public Boolean canAccess(){ HttpServerRequest request = currentVertxRequest.get(); // 获取远程地址示例 String remoteAddress = request.remoteAddress().toString(); log.info("Remote address: {}", remoteAddress); return true; }
内容的提问来源于stack exchange,提问作者A M
相关产品推荐
相关产品推荐

