0

我想禁止从外部完全访问 Solr 核心,并让它仅用于查询。因此,我在端口上的 Jetty servlet 容器(除了主 webapp)内启动带有连接器实例的辅助服务器,这是无法从 WWW 访问的。

liftweb应用程序有传入的 HTTP 请求时,我会使用RestHelper

object Dispatcher extends RestHelper {
  serve {
    case List("api", a @ _*) JsonGet _ => JString("API is not implemented yet. rest: " + a)
  }
}

将我的浏览器定位到http://localhost/api/solr/select?q=region我得到一个响应"API is not implemented yet. rest: List(solr, select)",所以它似乎有效。现在我想在内部端口(Solr 所在的位置)上进行连接,以便使用apiURL 的后半部分(即http://localhost:8080/solr/select?q=region)传递查询。我正在捕获 URL 的尾随 REST 部分(通过a @ _*),但是如何访问 URL 参数?最好将原始字符串(在api路径元素之后)传递给 Solr 实例,以防止多余的解析/构建步骤。所以适用于 Solr 的响应:我想避免解析构建 JsonResponse。

这似乎是做一些 HTTP 重定向的一个很好的例子,但是据我所知,我必须打开隐藏的 Solr 端口。

处理这项任务的最有效方法是什么?

编辑:

好吧,我错过了之后JsonGetReq价值,它包含所有需要的信息。但是有没有办法避免不必要的解析/组合 URL 到隐藏端口和 JSON 响应?

解决方案:

这就是我考虑戴夫的建议:

import net.liftweb.common.Full
import net.liftweb.http.{JsonResponse, InMemoryResponse}
import net.liftweb.http.provider.HTTPRequest
import net.liftweb.http.rest.RestHelper
import dispatch.{Http, url}

object ApiDispatcher extends RestHelper {
  private val SOLR_PORT = 8080

  serve { "api" :: Nil prefix {
    case JsonGet(path @ List("solr", "select"), r) =>
      val u = localApiUrl(SOLR_PORT, path, r.request)
      Http(url(u) >> { is =>
        val bytes = Stream.continually(is.read).takeWhile(-1 !=).map(_.toByte).toArray
        val headers = ("Content-Length", bytes.length.toString) ::
          ("Content-Type", "application/json; charset=utf-8") :: JsonResponse.headers
        Full(InMemoryResponse(bytes, headers, JsonResponse.cookies, 200))
      })
  }}

  private def localApiUrl(port: Int, path: List[String], r: HTTPRequest) =
    "%s://localhost:%d/%s%s".format(r.scheme, port, path mkString "/", r.queryString.map("?" + _).openOr(""))
}
4

1 回答 1

1

我不确定我是否理解您的问题,但如果您想返回从 solr 收到的 JSON 而不对其进行解析,您可以使用包含 JSON 的 byte[] 表示的 net.liftweb.http.InMemoryResponse。

于 2012-04-17T15:57:53.837 回答