【问题标题】:Java web service only responds on localhost, not by hostname (Apache Tika)Java Web 服务仅在 localhost 上响应,而不是通过主机名 (Apache Tika)
【发布时间】:2013-11-15 19:10:06
【问题描述】:

展示比讲述更容易。这是来自 Apache Tika 网络服务:

http://pastebin.com/jrCsVVtt

在该文件的第 89 行,localhost 是硬编码的:

sf.setProviders(providers);
sf.setAddress("http://localhost:" + TikaServerCli.DEFAULT_PORT + "/");
BindingFactoryManager manager = sf.getBus().getExtension(
                                BindingFactoryManager.class);

这意味着如果您在本地计算机上运行 Web 服务,则无法通过 http://hostname:9998/tikahttp://hostname.domain.net:9998/tika 访问它。它必须http://localhost:9998/tika访问。

我的 Java 非常生锈,但在谷歌搜索后,我添加了几行:

sf.setProviders(providers);
String hostname;
try
{
  InetAddress ia = InetAddress.getLocalHost();
  hostname = ia.getCanonicalHostName() + ":";
}
catch (Exception e)
{
  //I'll do something else with this later
  hostname = "http://localhost:";
}
sf.setAddress(hostname + TikaServerCli.DEFAULT_PORT + "/");
BindingFactoryManager manager = sf.getBus().getExtension(
                                BindingFactoryManager.class);

这允许我通过主机名和 FQDN 访问它,但不能通过 localhost。

有没有一种惯用的方式让 Web 服务以所有可能的形式响应?

  • 127.0.0.1(本地访问时)
  • localhost(本地访问时)
  • 主机名
  • FQDN
  • IP 地址
  • 我还缺少什么

我想我可以在运行时计算和或多或少完整的枚举,但似乎有更好的方法(?)。

【问题讨论】:

  • 您是否有理由不直接调用 JAXRS 服务器?只有它有一个真正简单易用的 RESTful API...
  • 这个 JAXRS 服务器。但它只能通过 localhost 地址访问。假设服务器在机器Foo 上运行。我无法从机器Bar 上击中它。只有调用 - 使用 localhost 作为地址 - 从 Foo 进行的才有效。 Bar 不能调用FooFoo 不能使用Foo 作为地址调用自己。它会失败。 localhost 被硬编码到作为 JAXRS 服务器的代码中。你可以在我的第 89 行的 pastebin 链接中看到这个硬编码。
  • 我向 Apache 提交了一个错误:issues.apache.org/jira/browse/TIKA-1196
  • 啊,对了,现在我明白你了!我认为问题在于它绑定到错误的接口,而不是它正在检查主机名。有关更多信息,请参阅我对错误的评论
  • 是的,我看到了,只是在调查它。我会把我的cmets放在那里。

标签: java web-services hostname apache-tika


【解决方案1】:

尝试将nginx 作为前端服务器,它将请求代理到 Tika (Jetty) 服务器。

  1. 在运行 Tika 服务器的同一台服务器上安装 nginx。

  2. 编辑 nginx 配置文件:

    vim /etc/nginx/conf.d/default.conf
    
  3. 设置:

    # The address or IP on which your Tika server is running. I choose port 9998.
    upstream your_domain_or_ip {
        server localhost:9998;
    }
    
    # The nginx server instance
    server {
       listen 80;
       server_name localhost;
    
       # Pass the request with corrent headers to the Tika server
       location / {
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host $http_host;
         proxy_set_header X-NginX-Proxy true;
         proxy_pass http://your_domain_or_ip/;
         proxy_redirect off;
       }
    }
    

【讨论】:

  • 我喜欢这个主意,但请问,为什么要把engine x 放在Tika 前面?
【解决方案2】:

我提交了一个补丁,其中添加了一个可选的命令行参数,并更改了默认行为以侦听所有有效的主机名和 IP。 (这种新的默认行为是否会保留还有待观察。)

更多细节以及补丁,可以在 Jira 票证上找到:

https://issues.apache.org/jira/browse/TIKA-1196

【讨论】:

    【解决方案3】:

    一个系统有多个网络接口——硬件(如以太网卡)和软件(如具有特殊 ip 127.0.0.1 的环回接口)。使用 localhost 时,您的服务器仅将您的端口绑定到环回接口,因此您只能从该接口上的机器访问它,并且环回接口在其网络上只有一台机器,那就是您的机器本身。

    现在,您可以选择要将端口绑定到的所有接口。您的服务器将可以从绑定接口连接到的网络中的所有机器访问。例如。如果您选择将服务器端口绑定到环回接口和以太网接口,那么您的服务器将只能从 LAN 上的机器和本地主机访问。如果你也有WIFI接口并且你的服务器端口没有绑定,那么wifi上的机器将无法访问你的服务器。

    现在,如果你想将你的服务器端口绑定到所有可用的接口,以便从任何地方都可以访问它,那么你需要指定一个特殊的 IP - 0.0.0.0 而不是 localhost 或 127.0.0.1。请参阅此以了解网络接口 - http://wilddiary.com/list-ip-addresses-in-java/

    【讨论】:

      猜你喜欢
      • 2014-01-15
      • 1970-01-01
      • 2021-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-06
      • 2020-04-26
      • 1970-01-01
      相关资源
      最近更新 更多