【问题标题】:Redirect to a different port keeping all the rest重定向到其他端口,保留所有其他端口
【发布时间】:2014-10-06 08:26:33
【问题描述】:

在服务器(嵌入式 Jetty)上,我需要重定向到另一个端口,而其他所有内容都保持不变,例如,从重定向

http://com.example.myserver:1234/whatever?with=params#and-hash?and=whoknowswhat

http://com.example.myserver:5678/whatever?with=params#and-hash?and=whoknowswhat

看起来我必须用我不知道的东西来组合生成的 URL:

  • 浏览器使用的服务器名称
  • URL 的剩余部分

【问题讨论】:

    标签: java embedded-jetty http-redirect


    【解决方案1】:

    开箱即用的重写处理程序

    http://wiki.eclipse.org/Jetty/Feature/Rewrite_Handler

    我快速浏览了 Jetty 提供的开箱即用的重写处理程序。从我从文档/示例中收集到的信息来看,它们似乎都只对 URL 的路径部分进行了实际重写(即端口之后的所有内容,不是我们想要的)(如果我错了,请纠正我! )。

    编写请求处理程序

    一个初步的例子让你开始,如果你只想使用嵌入式码头,你可以编写一个请求处理程序,将所有请求重定向到给定端口。

    它的工作方式是 PortRedirector 使用 handle 方法处理 HTTP 请求。它构建原始请求 URL,将端口更改为目标“to”端口,并将客户端重定向到新 URL。

    在下面的例子中,服务器监听 1234 端口,并将所有请求重定向到 8080 端口。

    import org.eclipse.jetty.server.Request;
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.server.handler.AbstractHandler;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class Redirector {
    
        public static void main(String[] args) throws Exception {
            Server server = new Server(1234);
            server.setHandler(new PortRedirector(8080));
            server.start();
            server.dumpStdErr();
            server.join();
        }
    
        static class PortRedirector extends AbstractHandler {
    
            int to;
    
            PortRedirector(int to) {
                this.to = to;
            }
    
            public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
                    throws IOException, ServletException {
                String uri = request.getScheme() + "://" +
                        request.getServerName() +
                        ":" + to +
                        request.getRequestURI() +
                        (request.getQueryString() != null ? "?" + request.getQueryString() : "");
                response.sendRedirect(uri);
            }
        }
    }
    

    参考资料:

    【讨论】:

    • 这是一个不错的技巧,但正确的答案应该是 Serge Ballesta 给出的答案,因为他给出了解释。
    • 我已经为这个问题添加了更多解释stackoverflow.com/questions/25278350/…
    【解决方案2】:

    如果通常不是应用程序服务器(jetty、tomcat、glassfish 等)的工作,而是在 JEE 容器的 servlet 之前添加到链上的反向代理,这种或重定向。其中最常见的是优秀的Apache HTTPservernginx

    例如,使用 Apache httpd,您将使用 mod_proxy 模块和虚拟主机:

    <VirtualHost *:1234>
        ServerName com.example.myserver
        RequestHeader set X-Forwarded-Proto "http"
        ProxyPass / http://com.example.myserver:5678/
        ProxyPassReverse / http://com.example.myserver:5678/
    </VirtualHost>
    

    这些反向代理目前用于保护应用服务器:只有代理可以从外部访问。

    【讨论】:

      【解决方案3】:

      在 Serge Ballesta 中添加更多内容,解释为什么您应该使用 VirtualHost。它总是归结为应用程序的责任,这将提高整个系统的效率。我推荐阅读What does architect know? 部分in this link。我想从该部分强调的一点是:

      • 系统中有哪些组件,它们的职责是什么

      所以在这个问题中,重定向请求的责任应该是服务器,并且您不希望您的应用程序在一台服务器需要重新启动的情况下拒绝所有请求(如果您有集群)。此外,您可能会考虑更改服务器,您可能会考虑添加负载均衡器,在这种情况下,在应用程序端处理它没有任何意义。

      This file 用于VirtualHost 的 apache 配置。根据上下文路径重定向请求,在这个文件中/splunk

      #LoadModule proxy_module modules/mod_proxy.so
      #LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
      #LoadModule proxy_http_module modules/mod_proxy_http.so
      # Uncomment these to proxy FTP or HTTPS
      #LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
      #LoadModule proxy_connect_module modules/mod_proxy_connect.so
      
      <VirtualHost *:80>
      
          DocumentRoot "/var/www"
      
          # Your domain name
          ServerName Domain_NAME_HERE
      
          ProxyPreserveHost On
      
          ProxyPass "/splunk" "http://localhost:8000/splunk"
          ProxyPassReverse "/splunk" "http://localhost:8000/splunk"
      
      </VirtualHost>
      

      因此,来自端口 80 且上下文路径为 /splunk 的请求将被重定向到 http://localhost:8080/splunk

      上述 apache2 配置将处理来自 DocumentRoot /var/www 的端口 80 上的请求[您可能在此位置有 PHP 文件]

      在这种情况下,您可能需要将您的应用程序连接到 apache 更改 Splunk splunk/etc/system/default/web.conf 配置:

      root_endpoint = /splunk
      

      如果是tomcat:

      <Connector port="<port_number>" enableLookups="false" redirectPort="<redirect_port>" protocol="AJP/1.3" />
      

      【讨论】:

        猜你喜欢
        • 2021-04-09
        • 2017-07-24
        • 1970-01-01
        • 2019-02-02
        • 1970-01-01
        • 2012-07-21
        • 1970-01-01
        • 2017-03-28
        • 2013-02-10
        相关资源
        最近更新 更多