泽西岛网络服务代理

时间:2013-12-04 00:22:49

标签: java web-services solr jersey jax-rs

我正在尝试实现一个Web服务,该服务代理我想要从API的外部用户隐藏的另一个服务。基本上我想扮演中间人,有能力为隐藏的api添加功能,这是solr。

我必须遵循以下代码:

@POST
@Path("/update/{collection}")
public Response update(@PathParam("collection") String collection,
        @Context Request request) {
      //extract URL params
      //update URL to target internal web service
      //put body from incoming request to outgoing request
      //send request and relay response back to original requestor
}

我知道我需要重写URL以指向内部可用的服务,添加来自URL或正文的参数。

我很困惑如何访问原始请求正文并将其传递给内部Web服务而无需解组内容?请求对象似乎没有给我执行这些操作的方法。

我正在寻找我应该使用的对象以及可能对我有帮助的潜在方法。如果有人知道我还没有发现任何针对类似或可移植行为的内容,我还想获得一些文档。

2 个答案:

答案 0 :(得分:3)

根据JSR-311规范的4.2.4节,所有JAX-RS实现都必须以byte [],String或InputStream的形式提供对请求体的访问。

您可以使用UriInfo获取有关查询参数的信息。它看起来像这样:

@POST
@Path("/update/{collection}")
public Response update(@PathParam("collection") String collection, @Context UriInfo info, InputStream inputStream) 
{
     String fullPath = info.getAbsolutePath().toASCIIString();
     System.out.println("full request path: " + fullPath);

     // query params are also available from a map.  query params can be repeated,
     // so the Map values are actually Lists.  getFirst is a convenience method
     // to get the value of the first occurrence of a given query param
     String foo = info.getQueryParameters().getFirst("bar");

     // do the rewrite...
     String newURL = SomeOtherClass.rewrite(fullPath);

     // the InputStream will have the body of the request.  use your favorite
     // HTTP client to make the request to Solr.
     String solrResponse = SomeHttpLibrary.post(newURL, inputStream);

     // send the response back to the client
     return Response.ok(solrResponse).build();

另一个想法。看起来你只是在重写请求并传递给Solr。还有其他一些方法可以做到这一点。

如果您的Java应用服务器或Servlet容器前面碰巧有Web服务器,您可以在不编写任何Java代码的情况下完成任务。除非重写条件非常复杂,否则我个人的偏好是尝试使用Apache mod_proxy和mod_rewrite执行此操作。

还有一些Java库可以在URL到达应用服务器之后但在它们到达您的代码之前重写URL。例如,https://code.google.com/p/urlrewritefilter/。有了类似的东西,你只需要编写一个调用Solr的非常简单的方法,因为URL会在它到达你的REST资源之前被重写。为了记录,我实际上没有尝试过使用泽西岛的特定图书馆。

答案 1 :(得分:1)

1 /对于网关taht的问题将隐藏数据库或索引,我宁愿使用配置了@Path({regex})的端点(而不是在端点中重建正则表达式分析器)。 直接在@path中使用这个正则表达式,这是一个很好的做法。

请查看与此相近的其他帖子:@Path and regular expression (Jersey/REST)

例如,你可以像这样的正则表达式:

@Path("/user/{name : [a-zA-Z][a-zA-Z_0-9]}")

2 /第二点为了处理来自一个端点的所有请求,您需要有一个动态参数。我会使用一个多值映射,使您可以在不修改端点的情况下为请求添加参数:

@POST
@Path("/search")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces({"application/json"})
public Response search( MultivaluedMap<String, String> params ) {
    // perform search operations
    return search( params);

}

3 /我的第三个建议是重复使用:让经济和经济减少错误。 为了执行solr搜索,重写一个rest api真是太可怜了。你可以隐藏params和端点,但是可以很好地保持solr uri Rest params的格式化,以便直接在你的api中重用solr的所有搜索逻辑。即使您将solr实例隐藏在REST GATEWAY SERVER后面,这也会使您在代码中实现经济效益。

在这种情况下你可以想象:  1.在搜索网关端点中接收查询  2.转换查询以添加参数,控件...  3.在solr上执行REST查询(在您的网关后面)。