JAX-RS(Quarkus)如何通过URL获取对应资源方法并调用?
问题
我需要从一个资源(资源A)调用另一个资源(资源B),但不知道资源B具体是哪个,仅能获取到一个URL字符串。请问在JAX-RS中,如何根据给定的URL匹配到对应的资源/方法?
示例场景:
收到如下URL作为参数传入资源方法(已做HTTP转义处理):
/bar?url=/foo/123
对应的资源方法代码:
@Path("/bar") public class Bar { public Response getURL(@QueryParam("url") String url) { // 希望调用 Foo.getOne(123) } }
同时存在另一个资源类:
@Path("/foo") public class Foo { @GET public Response getAll() { return Response.ok("ok"); } @GET @Path("/{id}") public Response getOne (@PathParam(name = "id") Long id) { return Response.ok("ok"); } }
使用的框架是Quarkus,如何在Bar的方法中获取getOne方法的引用及其参数,并执行该方法?
解决方案
经确认,JAX-RS没有公开的直接API支持根据URL匹配对应资源方法的逻辑,这涉及到框架内部未对外开放的路由解析代码,自行实现的难度极高。在Quarkus框架下,最简便可行的方案是向自身发起HTTP请求来间接调用目标资源。
具体实现示例
可以通过Quarkus提供的MicroProfile Rest Client发起内部请求:
import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.Response; import org.eclipse.microprofile.rest.client.RestClientBuilder; import java.net.URI; @Path("/bar") public class Bar { @Inject RestClientBuilder restClientBuilder; @GET public Response getURL(@QueryParam("url") String url) { // 基础URI建议从Quarkus配置中读取,避免硬编码 String baseUri = "http://localhost:8080"; URI targetUri = URI.create(baseUri + url); // 创建临时客户端调用目标资源 InternalSelfClient client = restClientBuilder.baseUri(targetUri).build(InternalSelfClient.class); return client.invokeTarget(); } // 定义内部调用的客户端接口 private interface InternalSelfClient { @GET Response invokeTarget(); } }
也可以直接使用Quarkus注入的HttpClient发起请求:
import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.Response; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; @Path("/bar") public class Bar { @Inject HttpClient httpClient; @GET public Response getURL(@QueryParam("url") String url) throws Exception { String baseUri = "http://localhost:8080"; HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(baseUri + url)) .GET() .build(); HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); return Response.status(response.statusCode()) .entity(response.body()) .build(); } }
内容的提问来源于stack exchange,提问作者Riccardo Cossu
相关产品推荐
相关产品推荐

