【问题标题】:Forward a servlet request to another server将 servlet 请求转发到另一台服务器
【发布时间】:2012-06-07 07:15:10
【问题描述】:

Java Servlet API 可以将请求转发到同一服务器中的另一个路径(相同的主机:端口)。但是,转发到不同的主机:端口——就像代理一样——是另一回事。

我尝试使用 Jersey Client 来做到这一点,将 ServletRequest(方法、标头、媒体类型和正文)调整为 Jersey ClientRequest具有不同的基本 uri),使调用,并将 Jersey ClientResponse — 方法、标头、媒体类型和正文 — 改编回 ServletResponse

手动调整这些对我来说似乎是错误的。

难道没有纯 Servlet API 解决方案吗? 还是能够在更改主机:端口时来回调整请求的 HTTP 客户端?

【问题讨论】:

    标签: http servlets jersey portforwarding


    【解决方案1】:

    HTTP-Proxy-Servlet 完全满足您的需求。

    快速配置

    pom.xml

    <dependency>
        <groupId>org.mitre.dsmiley.httpproxy</groupId>
        <artifactId>smiley-http-proxy-servlet</artifactId>
        <version>1.7</version>
    </dependency>
    

    web.xml

    <servlet>
        <servlet-name>solr</servlet-name>
        <servlet-class>org.mitre.dsmiley.httpproxy.ProxyServlet</servlet-class>
        <init-param>
            <param-name>targetUri</param-name>
            <param-value>http://solrserver:8983/solr</param-value>
        </init-param>
        <init-param>
            <param-name>log</param-name>
            <param-value>true</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>solr</servlet-name>
        <url-pattern>/solr/*</url-pattern>
    </servlet-mapping>
    

    Spring 集成

    另见:HTTP-Proxy-Servlet Issue #15

    pom.xml

    <dependency>
        <groupId>org.mitre.dsmiley.httpproxy</groupId>
        <artifactId>smiley-http-proxy-servlet</artifactId>
        <version>1.7</version>
    </dependency>
    

    ServletWrappingControllerExt.java

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.ServletWrappingController;
    
    public class ServletWrappingControllerExt extends ServletWrappingController
    {
        private String  pathToStrip;
    
        public void setPathToStrip(String pathToStrip)
        {
            this.pathToStrip = pathToStrip;
        }
    
        @Override
        protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
                throws Exception
        {
            final HttpServletRequest wrapper = new HttpServletRequestWrapper(request)
            {
                @Override
                public String getPathInfo()
                {
                    //Please note that getPathInfo returns null if DispatcherServlet is configured to track url-pattern "/"
                    //It should be configured to track url-pattern "/*". Below is a sample DispatcherServlet configuration
                    /*
                        <servlet>
                            <servlet-name>spring</servlet-name>
                            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                            <load-on-startup>1</load-on-startup>
                        </servlet>
                        <servlet-mapping>
                            <servlet-name>spring</servlet-name>
                            <url-pattern>/*</url-pattern>
                        </servlet-mapping>
                     */
                    String path = super.getPathInfo();                  
                    if (path.startsWith(pathToStrip))
                    {
                        final int length = pathToStrip.length();
                        path = path.substring(length);
                    }
                    return path;
                }
                
                @Override
                public String getServletPath()
                {
                    return super.getServletPath();
                }
            };
    
            return super.handleRequestInternal(wrapper, response);
        }
    }
    

    Beans 配置

    <bean id="myServletWrapper" class="ServletWrappingControllerExt">
        <property name="pathToStrip" value="/solr"/>
        <property name="servletClass" value="org.mitre.dsmiley.httpproxy.ProxyServlet" />
        <property name="servletName" value="solr" />
        <property name="initParameters">
            <props>
                <prop key="targetUri">http://solrserver:8983/solr</prop>
                <prop key="log">true</prop>
            </props>
        </property>
    </bean>
    
    <bean id="myServletUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="urlMap">
        <map>
            <entry key="/solr/**" value-ref="myServletWrapper" />
        </map>
        </property>
        <property name="order" value="1" />
    </bean>
    

    【讨论】:

      【解决方案2】:

      你应该使用javax.net.HttpURLConnection

      这是它的伪代码:

      URL url = new URL("http://otherserver:otherport/url");
      HttpURLConnection connection = (HttpURLConnection)url.openConnection();
      
      // set http method if required
      connection.setRequestMethod("POST");
      
      // set request header if required
      connection.setRequestProperty("header1", "value1");
      
      // check status code
      if(connection.getResponseCode() == 200) {
      
         InputStream is = connection.getInputStream();
         //transfer is to the required output stream
      } else {
         //write error
      }
      

      【讨论】:

      • 我试过了,只是复制粘贴了相同的代码,但我得到响应代码 = -1 并且 IOException 的详细消息为“无效的 Http 响应”,你能帮我吗?
      【解决方案3】:

      据我了解,您需要从 Servlet 发送 requests 并从其他服务器获取 response 到您的服务器,可能您需要 HTTP Client (Overview)。
      @987654323 @question 也可能对您有所帮助。

      【讨论】:

        猜你喜欢
        • 2012-04-23
        • 2012-12-27
        • 1970-01-01
        • 2022-12-10
        • 1970-01-01
        • 2017-10-26
        • 1970-01-01
        • 2015-08-28
        • 2012-11-22
        相关资源
        最近更新 更多