嵌入式码头与 Resteasy 的集成

Integration of embedded jetty with Resteasy

我正在尝试设置一个码头服务器,它应该:

  1. 在一个上下文中提供 html 个文件。
  2. 服务器 REST API 在另一个上下文中使用 RestEasy 进行的调用。

我已经提到 Integrating Jetty with RESTEasy 来集成 Resteasy 并且它有效。 我能够配置码头来服务 html 页面。 但我无法将两者结合起来。

我正在使用 XML IoC 格式来配置码头。 用于配置jetty服务器的jetty.xml如下:

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<Configure id="Server" class="org.eclipse.jetty.server.Server">



    <Get name="ThreadPool">
      <Set name="minThreads" type="int"><Property name="jetty.threadPool.minThreads" deprecated="threads.min" default="10"/></Set>
      <Set name="maxThreads" type="int"><Property name="jetty.threadPool.maxThreads" deprecated="threads.max" default="200"/></Set>
      <Set name="idleTimeout" type="int"><Property name="jetty.threadPool.idleTimeout" deprecated="threads.timeout" default="60000"/></Set>
      <Set name="detailedDump">false</Set>
    </Get>




    <Set name="handler">
      <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
        <Set name="handlers">
         <Array type="org.eclipse.jetty.server.Handler">
          <Item>
              <New class="org.eclipse.jetty.server.handler.ContextHandler">
                  <Set name="contextPath">/home</Set>
                  <Set name="handler">
                      <New class="org.eclipse.jetty.server.handler.ResourceHandler">
                          <Set name="directoriesListed">false</Set>
                          <Set name="welcomeFiles">
                            <Array type="String">
                                <Item>index.html</Item>
                            </Array>
                           </Set>
                          <Set name="resourceBase">/opt/myapp/web</Set>
                      </New>
                  </Set>
              </New>
          </Item>

          <Item>
             <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
           </Item>
         </Array>
        </Set>
      </New>
    </Set>

    <Set name="stopAtShutdown"><Property name="jetty.server.stopAtShutdown" default="true"/></Set>
    <Set name="stopTimeout">5000</Set>
    <Set name="dumpAfterStart"><Property name="jetty.server.dumpAfterStart" deprecated="jetty.dump.start" default="false"/></Set>
    <Set name="dumpBeforeStop"><Property name="jetty.server.dumpBeforeStop" deprecated="jetty.dump.stop" default="false"/></Set>

</Configure>

而web.xml如下:

<web-app xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
   <context-param>
      <param-name>resteasy.scan</param-name>
      <param-value>true</param-value>
   </context-param>

   <context-param>
    <param-name>resteasy.resources</param-name>
    <param-value>webapp.Resource</param-value>
   </context-param>
    <context-param>
      <param-name>javax.ws.rs.core.Application</param-name>
      <param-value>webapp.MyApplicationConfig</param-value>
   </context-param>

   <!-- set this if you map the Resteasy servlet to something other than 
   <context-param>
      <param-name>resteasy.servlet.mapping.prefix</param-name>
      <param-value>/resteasy</param-value>
   </context-param>
   -->
   <!-- if you are using Spring, Seam or EJB as your component model, remove the ResourceMethodSecurityInterceptor -->

    <context-param>
      <param-name>resteasy.resource.method-interceptors</param-name>
      <param-value>
         org.jboss.resteasy.core.ResourceMethodSecurityInterceptor
      </param-value>
   </context-param>


   <listener>
      <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
   </listener>

  <servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

启动服务器的函数是:

   public void start()
        {

           try
           {
               String serverCfgFile = Utils.getIstatsHome() + jettyConfig;
               File f = new File(serverCfgFile);
               if (!f.exists())
               {
                   throw new Exception("Jetty conf file " + serverCfgFile + " not found");
               }

               server = new Server(7070);

               XmlConfiguration configuration = new XmlConfiguration(new FileInputStream(f));
               configuration.configure(server);
               server.start();
           }
     catch (Exception ex)
       {
           System.out.println("Exception while configuring Jetty Server" + ex);
           ex.printStackTrace();

       }
        } 

使用 jetty 设置 resteasy 所需的代码是:

WebAppContext context = new WebAppContext();

context.setDescriptor("/opt/myapp/WEB-INF/web.xml");
context.setResourceBase("/opt/myapp/lib");
context.setContextPath("/stats");
context.setParentLoaderPriority(true);

server.setHandler(context);

我如何修改此 jetty.xml 以实现此代码通过 xml 执行的操作。 我试过这样修改 jetty.xml:

   <?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<Configure id="Server" class="org.eclipse.jetty.server.Server">



    <Get name="ThreadPool">
      <Set name="minThreads" type="int"><Property name="jetty.threadPool.minThreads" deprecated="threads.min" default="10"/></Set>
      <Set name="maxThreads" type="int"><Property name="jetty.threadPool.maxThreads" deprecated="threads.max" default="200"/></Set>
      <Set name="idleTimeout" type="int"><Property name="jetty.threadPool.idleTimeout" deprecated="threads.timeout" default="60000"/></Set>
      <Set name="detailedDump">false</Set>
    </Get>




    <Set name="handler">
      <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
        <Set name="handlers">
         <Array type="org.eclipse.jetty.server.Handler">
          <Item>
              <New class="org.eclipse.jetty.server.handler.ContextHandler">
                  <Set name="contextPath">/home</Set>
                  <Set name="handler">
                      <New class="org.eclipse.jetty.server.handler.ResourceHandler">
                          <Set name="directoriesListed">false</Set>
                          <Set name="welcomeFiles">
                            <Array type="String">
                                <Item>index.html</Item>
                            </Array>
                           </Set>
                          <Set name="resourceBase">/opt/myapp/web</Set>
                      </New>
                  </Set>
              </New>
          </Item>
          <Item>

                      <New class="org.eclipse.jetty.webapp.WebAppContext"/>
                        <Set name="contextPath">/stats</Set>
                        <Set name="resourceBase">/opt/myapp/lib</Set>
                        <Set name="descriptor">/opt/myapp/WEB-INF/web.xml</Set>

          </Item>
          <Item>
             <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
           </Item>
         </Array>
        </Set>
      </New>
    </Set>

    <Set name="stopAtShutdown"><Property name="jetty.server.stopAtShutdown" default="true"/></Set>
    <Set name="stopTimeout">5000</Set>
    <Set name="dumpAfterStart"><Property name="jetty.server.dumpAfterStart" deprecated="jetty.dump.start" default="false"/></Set>
    <Set name="dumpBeforeStop"><Property name="jetty.server.dumpBeforeStop" deprecated="jetty.dump.stop" default="false"/></Set>

</Configure>

但是以这种方式修改 jetty.xml 会导致码头中出现 java.lang.ArrayStoreException 没有异常的堆栈跟踪。在日志中只看到 java.lang.ArrayStoreException。 可以这样做还是我在这里遗漏了一些东西? 请帮忙!

我花了很多时间才弄明白这一点。所以我发布了解决此 issue.The 问题的代码,该问题在 jetty.xml 中。使用 GzipHandler 组合处理程序是解决方案。

jetty.xml:

    <?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<Configure id="Server" class="org.eclipse.jetty.server.Server">



    <Get name="ThreadPool">
      <Set name="minThreads" type="int"><Property name="jetty.threadPool.minThreads" deprecated="threads.min" default="10"/></Set>
      <Set name="maxThreads" type="int"><Property name="jetty.threadPool.maxThreads" deprecated="threads.max" default="200"/></Set>
      <Set name="idleTimeout" type="int"><Property name="jetty.threadPool.idleTimeout" deprecated="threads.timeout" default="60000"/></Set>
      <Set name="detailedDump">false</Set>
    </Get>



    <Set name="handler">
        <New id="gzip" class="org.eclipse.jetty.server.handler.gzip.GzipHandler">
              <Set name="handler">
                 <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerList">
                      <Set name="handlers">
                        <Array type="org.eclipse.jetty.server.Handler">
                            <Item>
                                <New class="org.eclipse.jetty.server.handler.ContextHandler">
                                  <Set name="contextPath">/home</Set>
                                  <Set name="handler">
                                      <New class="org.eclipse.jetty.server.handler.ResourceHandler">
                                          <Set name="directoriesListed">true</Set>
                                          <Set name="welcomeFiles">
                                            <Array type="String">
                                                <Item>index.html</Item>
                                            </Array>
                                           </Set>
                                          <Set name="resourceBase">/opt/myapp/web</Set>
                                      </New>
                                  </Set>
                                </New>
                            </Item>
                            <Item>
                                <New id="context" class="org.eclipse.jetty.webapp.WebAppContext">
                                    <Set name="contextPath">/stats</Set>
                                    <Set name="resourceBase">/opt/myapp/WEB-INF</Set>
                                    <Set name="descriptor">/opt/myapp/WEB-INF/web.xml</Set>
                                </New>
                            </Item>
                            <Item>
                                <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
                            </Item>
                        </Array>
                      </Set>
                 </New>
              </Set>
        </New>
    </Set>


    <Set name="stopAtShutdown"><Property name="jetty.server.stopAtShutdown" default="true"/></Set>
    <Set name="stopTimeout">5000</Set>
    <Set name="dumpAfterStart"><Property name="jetty.server.dumpAfterStart" deprecated="jetty.dump.start" default="false"/></Set>
    <Set name="dumpBeforeStop"><Property name="jetty.server.dumpBeforeStop" deprecated="jetty.dump.stop" default="false"/></Set>

</Configure>

Web.xml:

    web-app xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
   <context-param>
      <param-name>resteasy.scan</param-name>
      <param-value>true</param-value>
   </context-param>

   <context-param>
    <param-name>resteasy.resources</param-name>
    <param-value>webapp.Resource</param-value>
   </context-param>
    <context-param>
      <param-name>javax.ws.rs.core.Application</param-name>
      <param-value>webapp.MyApplicationConfig</param-value>
   </context-param>

   <!-- set this if you map the Resteasy servlet to something other than 
   <context-param>
      <param-name>resteasy.servlet.mapping.prefix</param-name>
      <param-value>/resteasy</param-value>
   </context-param>
   -->
   <!-- if you are using Spring, Seam or EJB as your component model, remove the ResourceMethodSecurityInterceptor -->

    <context-param>
      <param-name>resteasy.resource.method-interceptors</param-name>
      <param-value>
         org.jboss.resteasy.core.ResourceMethodSecurityInterceptor
      </param-value>
   </context-param>


   <listener>
      <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
   </listener>

  <servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

启动码头服务器的代码:

 public void start()
    {

       try
       {
           String serverCfgFile = Utils.getIstatsHome() + jettyConfig;
           File f = new File(serverCfgFile);
           if (!f.exists())
           {
               throw new Exception("Jetty conf file " + serverCfgFile + " not found");
           }

           server = new Server(7070);

           XmlConfiguration configuration = new XmlConfiguration(new FileInputStream(f));
           configuration.configure(server);
           server.start();
       }
 catch (Exception ex)
   {
        _logger.log(Constants.EXCEPTION_LEVEL, "", ex);
   }
    }