首页 > 代码库 > Jetty开发指导:Maven和Jetty

Jetty开发指导:Maven和Jetty

使用Maven

Apache Maven是一种软件项目管理和综合工具。基于项目对象模型(POM)的概念,Maven能从核心信息管理一个项目的构建、报告和文档。
他是用于构建一个web应用项目的理想工具,这些项目能用jetty-maven-plugin轻松的运行web应用,从而节省开发时间。你也能用Maven构建、测试和运行一个嵌入Jetty的项目。
首先我们将看一个很简单嵌入Jetty的HelloWorld Java应用,然后看一个简单的webapp怎么使用jetty-maven-plugin加速开发周期。

使用Maven

Maven在配置之上使用惯例,因此最好的方式是使用Maven推荐的项目结构。你能用archetypes快速设置Maven项目,但这里我们为这个简单的指导性例子手动地设置结构:

> mkdir JettyMavenHelloWorld
> cd JettyMavenHelloWorld
> mkdir -p src/main/java/org/example

创建HelloWorld类

用编辑器创建src/main/java/org/example/HelloWorld.java类,包含如下内容:

package org.example;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
 
public class HelloWorld extends AbstractHandler
{
    public void handle(String target,
                       Request baseRequest,
                       HttpServletRequest request,
                       HttpServletResponse response) 
        throws IOException, ServletException
    {
        response.setContentType("text/html;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        baseRequest.setHandled(true);
        response.getWriter().println("<h1>Hello World</h1>");
    }
 
    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);
        server.setHandler(new HelloWorld());
  
        server.start();
        server.join();
    }
}

创建POM描述符

pom.xml文件描述项目名称和它的依赖。用编辑器创建文件pom.xml,包含如下内容:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>hello-world</artifactId>
  <version>0.1-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>Jetty HelloWorld</name>
 
  <properties>
      <!-- Adapt this to a version found on
           http://central.maven.org/maven2/org/eclipse/jetty/jetty-maven-plugin/
        -->
      <jettyVersion>9.0.2.v20130417</jettyVersion>
  </properties>
 
  <dependencies>
    <dependency>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-server</artifactId>
      <version>${jettyVersion}</version>
    </dependency>
  </dependencies>
 
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.1</version>
        <executions>
          <execution><goals><goal>java</goal></goals></execution>
        </executions>
        <configuration>
          <mainClass>org.example.HelloWorld</mainClass>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

构建和执行嵌入的HelloWorld

你现在能编译和执行HelloWorld类,使用下面的命令:

mvn clean compile exec:java

你能打开你的浏览器在http://localhost:8080看hello world页。你能通过mvn dependency:tree命令观察Maven正在后台为你做什么,包含了依赖的解析和下载:

> mvn dependency:tree
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'dependency'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Jetty HelloWorld
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree {execution: default-cli}]
[INFO] org.example:hello-world:jar:0.1-SNAPSHOT
[INFO] \- org.eclipse.jetty:jetty-server:jar:9.0.0:compile
[INFO]    +- org.eclipse.jetty:javax.servlet:jar:3.0.0.v201112011016:compile
[INFO]    +- org.eclipse.jetty:jetty-continuation:jar:9.0.0:compile
[INFO]    \- org.eclipse.jetty:jetty-http:jar:9.0.0:compile
[INFO]       \- org.eclipse.jetty:jetty-io:jar:9.0.0:compile
[INFO]          \- org.eclipse.jetty:jetty-util:jar:9.0.0:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Thu Jan 24 16:19:08 EST 2013
[INFO] Final Memory: 11M/68M
[INFO] ------------------------------------------------------------------------    

用Jetty和Maven开发一个标准WebApp

先前的例子演示怎么通过Maven在应用中使用嵌入Jetty。现在我们将测试看怎么使用Maven和Jetty开发一个标准webapp。首先创建Maven结构(你也能用maven webapp archetype代替):

> mkdir JettyMavenHelloWarApp
> cd JettyMavenHelloWebApp
> mkdir -p src/main/java/org/example
> mkdir -p src/main/webapp/WEB-INF

创建一个Servlet

用编辑器创建文件src/main/java/org/example/HelloServlet.java,包含下面的内容:

package org.example;
 
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class HelloServlet extends HttpServlet
{
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        response.setContentType("text/html");
        response.setStatus(HttpServletResponse.SC_OK);
        response.getWriter().println("<h1>Hello Servlet</h1>");
        response.getWriter().println("session=" + request.getSession(true).getId());
    }
}

你需要在部署描述符中宣称这个servlet,编辑文件src/main/webapp/WEB-INF/web.xml,增加下面的内容:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app
   xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   metadata-complete="false"
   version="3.0">
 
  <servlet>
    <servlet-name>Hello</servlet-name>
    <servlet-class>org.example.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Hello</servlet-name>
    <url-pattern>/hello/*</url-pattern>
  </servlet-mapping>
 
</web-app>

创建POM描述符

pom.xml文件描述项目的名称和它的依赖。用编辑器创建pom.xml,包含下面的内容,特别注意jetty-maven-plugin的定义:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>hello-world</artifactId>
  <version>0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>Jetty HelloWorld WebApp</name>
 
  <properties>
      <jettyVersion>9.0.2.v20130417</jettyVersion> /// Adapt this to a version found on http://repo.maven.apache.org/maven2/org/eclipse/jetty/jetty-maven-plugin/
  </properties>
 
  <dependencies>
    <dependency>
      <groupId>org.eclipse.jetty.orbit</groupId>
      <artifactId>javax.servlet</artifactId>
      <version>3.0.0.v201112011016</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
 
  <build>
    <plugins>
      <plugin>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>${jettyVersion}</version>
      </plugin>
    </plugins>
  </build>
 
</project>

构建和运行Web应用

通过使用jetty-maven-plugin,现在你能构建和运行web应用不需要打包到war,只需使用下面的命令:

> mvn jetty:run

你能在http://localhost:8080/hello看到静态和动态的内容。
jetty-maven-plugin中有大量的配置选项可用,帮助你构建和运行你的webapp。具体看下一节“配置Jetty Maven插件”。

构建一个WAR文件

你能创建一个Web Application Archive(WAR)文件,用如下命令:

> mvn package

生成的war文件能够部署在任何标准servlet server,包括Jetty。

配置Jetty Maven插件

Jetty Mven插件对于快速开发和测试是非常有用的。你能增加它到任何Maven构建的webapp项目。插件能周期地扫描你的项目,如果发现任何改变,将自动的重新部署webapp。这使开发周期变得更加快速:你通过IDE改变项目,运行中的web容器自动的替换他们,你立即就能测试改变。
注意:使用该插件必须使用Maven 3和Java 1.7。

快速开始:启动并运行

首先,增加jetty-maven-plugin到你的pom.xml:

<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <version>9.2.2-SNAPSHOT</version>
</plugin>

然后,从你的根pom.xml目录,执行:

mvn jetty:run

这将启动Jetty并且部署你的项目在http://localhost:8080/。
Jetty持续运行直到你停止它。当它运行时,它周期地扫描你的项目文件的改变,如果你保存了改变并且重编译你的class文件,jetty将重新部署你的webapp,你能立即测试这些你做的改变。
你能在命令行中通过ctrl-c终止插件。

支持的目标

Jetty Maven插件有许多不同的Maven目标。无可争议的最有用的是run目标,用于运行未打包的webapp。有其它目标帮助你完成不同的任务。例如,你可能需要运行你的webapp在一个Jetty的分支实例,而不是在运行Maven的实例内;或者你可能需要更细粒度的控制mavne的生命周期阶段。有不同的目标用于完成这些任务,以及其它的任务。
为了看所有Jetty Maven插件支持的目标,输入:

mvn jetty:help

为了看参数的详细列表,外加它的描述信息,输入:

mvn jetty:help -Ddetail=true -Dgoal= goal-name

配置Jetty容器

这些配置元素设置你的webapp执行的Jetty环境。它们适用于大部分目标:

httpConnector

可选。如果没有指定,Jetty将创建一个ServerConnector实例,监听端口8080。你能改变这个默认端口,通过在命令行使用系统属性jetty.port,例如,mvn -Djetty.port=9999 jetty:run。另外,你能用这个配置元素为ServerConnector设置信息。下面是有效的配置子元素:
 1)port:连接器的端口。默认是8080.
 2)host:连接器监听的特定主机。默认是所有。
 3)name:连接器名,在配置上下文对应特定连接器时使用。
 4)idleTimeout:连接器的最大空闲时间。
 5)soLinger:套接字逗留时间。
你能配置连接器在一个标准的Jetty xml配置文件,然后用它的路径配置到jettyXml参数。注意由于jetty 9.0不再能在pom.xml中直接地配置https connector:你需要用jetty xml配置文件做它。

jettyXml

可选。一个逗号分隔的jetty xml文件路径列表,用于配置插件配置参数。参考$JETTY_HOME/etc/jetty.xml。

scanIntervalSeconds
扫描webapp变化的间隔,单位秒,当扫描到变化后,将执行自动热重部署。默认是0,表示停止热部署扫描。配置值大于0激活它。

reload
默认值“automatic”,与scanIntervalSeconds联合使用,表示当改变发生时,自动热重部署。设置到“manual”,表示你需要在控制台执行换行来触发插件执行扫描。这有时候是有用的,当你一次做一系列的改变,你想忽略中间的改变时,就可以使用reload参数。

loginServices
可选。一个org.eclipse.jetty.security.LoginService实现的列表。注意没有默认域。你在web.xml中使用的域,也能够在这里指定。你能在一个jetty xml文件中配置login service,将文件位置指定到jettyXml参数。

requestLog
可选。org.eclipse.jetty.server.RequestLog请求日志接口的一个实现。遵守NCSA格式的实现( org.eclipse.jetty.server.NCSARequestLog)是可用的。有三种其它方式用于配置RequestLog:
 1)在一个Jetty xml配置文件中,指定文件路径到jettyXml参数;
 2)在一个上下文配置文件中,指定文件路径到contextXml参数;
 3)在webApp元素中。
更多信息参考“Jetty日志”。

stopPort
可选。端口用于监听停止命令。运行stop或者run-forked目标时使用。

stopKey
可选。用于和stopPort联合使用,用于停止jetty。运行stop或者run-forked目标时使用。

systemProperties
可选。允许你配置System属性,用于运行插件。

systemPropertiesFile
可选。一个包含System属性的文件。默认,你在这里做的设置不重载任何已经在命令行、JVM、POM(通过systemProperties)中设置的系统属性。

skip
默认是false。如果true,插件的执行退出。等同于设置SystemProperty  -Djetty.skip在命令行。这是非常有用的,当配置Jetty为综合测试而你想略过测试代码时。

useProvidedScope
默认值false。如果true,<scope>provided</scope>的依赖被放置到容器classpath。注意这不是webapp的classpath,“provided”表示这些依赖通常被期望由容器提供。你应该很少需要用到这。相反,你应该拷贝provided依赖作为插件直接的依赖。

excludedGoals
可选。jetty插件目标名的列表,插件将打印信息然后退出。当你想阻止用户执行项目无法支持的目标时使用。

配置一个Https连接器

为了配置一个https连接器,你需要用jetty xml配置文件。这个例子用的文件直接从jetty发布的etc/目录拷贝过来,你也可以自己实现。我们将用下面这些文件:

jetty.xml
设置the org.eclipse.jetty.server.Server的几个特性,供插件使用。主要是配置org.eclipse.jetty.server.HttpConfiguration元素供配置连接器时使用。下面是相关配置:

<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
  <Set name="secureScheme">https</Set>
  <Set name="securePort"><Property name="jetty.secure.port" default="8443" /></Set>
  <Set name="outputBufferSize">32768</Set>
  <Set name="requestHeaderSize">8192</Set>
  <Set name="responseHeaderSize">8192</Set>
  <Set name="sendServerVersion">true</Set>
  <Set name="sendDateHeader">false</Set>
  <Set name="headerCacheSize">512</Set>
 
  <!-- Uncomment to enable handling of X-Forwarded- style headers
  <Call name="addCustomizer">
    <Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
  </Call>
  -->
</New>

jetty-ssl.xml
设置同https连接器使用的ssl。下面是来自jetty发布的jetty-ssl.xml文件:

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
 
<!-- ============================================================= -->
<!-- Configure a TLS (SSL) Context Factory                         -->
<!-- This configuration must be used in conjunction with jetty.xml -->
<!-- and either jetty-https.xml or jetty-spdy.xml (but not both)   -->
<!-- ============================================================= -->
<Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
  <Set name="KeyStorePath"><Property name="jetty.base" default="." />/<Property name="jetty.keystore" default="etc/keystore"/></Set>
  <Set name="KeyStorePassword"><Property name="jetty.keystore.password" default="OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"/></Set>
  <Set name="KeyManagerPassword"><Property name="jetty.keymanager.password" default="OBF:1u2u1wml1z7s1z7a1wnl1u2g"/></Set>
  <Set name="TrustStorePath"><Property name="jetty.base" default="." />/<Property name="jetty.truststore" default="etc/keystore"/></Set>
  <Set name="TrustStorePassword"><Property name="jetty.truststore.password" default="OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"/></Set>
  <Set name="EndpointIdentificationAlgorithm"></Set>
  <Set name="NeedClientAuth"><Property name="jetty.ssl.needClientAuth" default="false"/></Set>
  <Set name="WantClientAuth"><Property name="jetty.ssl.wantClientAuth" default="false"/></Set>
  <Set name="ExcludeCipherSuites">
    <Array type="String">
      <Item>SSL_RSA_WITH_DES_CBC_SHA</Item>
      <Item>SSL_DHE_RSA_WITH_DES_CBC_SHA</Item>
      <Item>SSL_DHE_DSS_WITH_DES_CBC_SHA</Item>
      <Item>SSL_RSA_EXPORT_WITH_RC4_40_MD5</Item>
      <Item>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</Item>
      <Item>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</Item>
      <Item>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</Item>
    </Array>
  </Set>
 
  <!-- =========================================================== -->
  <!-- Create a TLS specific HttpConfiguration based on the        -->
  <!-- common HttpConfiguration defined in jetty.xml               -->
  <!-- Add a SecureRequestCustomizer to extract certificate and    -->
  <!-- session information                                         -->
  <!-- =========================================================== -->
  <New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
    <Arg><Ref refid="httpConfig"/></Arg>
    <Call name="addCustomizer">
      <Arg><New class="org.eclipse.jetty.server.SecureRequestCustomizer"/></Arg>
    </Call>
  </New>
 
</Configure>

jetty-https.xml
设置https连接器,用jetty.xml的HttpConfiguration和jetty-ssl.xml的ssl配置:

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
 
<!-- ============================================================= -->
<!-- Configure a HTTPS connector.                                  -->
<!-- This configuration must be used in conjunction with jetty.xml -->
<!-- and jetty-ssl.xml.                                            -->
<!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
 
  <!-- =========================================================== -->
  <!-- Add a HTTPS Connector.                                      -->
  <!-- Configure an o.e.j.server.ServerConnector with connection   -->
  <!-- factories for TLS (aka SSL) and HTTP to provide HTTPS.      -->
  <!-- All accepted TLS connections are wired to a HTTP connection.-->
  <!--                                                             -->
  <!-- Consult the javadoc of o.e.j.server.ServerConnector,        -->
  <!-- o.e.j.server.SslConnectionFactory and                       -->
  <!-- o.e.j.server.HttpConnectionFactory for all configuration    -->
  <!-- that may be set here.                                       -->
  <!-- =========================================================== -->
  <Call id="httpsConnector" name="addConnector">
    <Arg>
      <New class="org.eclipse.jetty.server.ServerConnector">
        <Arg name="server"><Ref refid="Server" /></Arg>
          <Arg name="factories">
            <Array type="org.eclipse.jetty.server.ConnectionFactory">
              <Item>
                <New class="org.eclipse.jetty.server.SslConnectionFactory">
                  <Arg name="next">http/1.1</Arg>
                  <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
                </New>
              </Item>
              <Item>
                <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                  <Arg name="config"><Ref refid="sslHttpConfig"/></Arg>
                </New>
              </Item>
            </Array>
          </Arg>
          <Set name="host"><Property name="jetty.host" /></Set>
          <Set name="port"><Property name="https.port" default="443" /></Set>
          <Set name="idleTimeout"><Property name="https.timeout" default="30000"/></Set>
          <Set name="soLingerTime"><Property name="https.soLingerTime" default="-1"/></Set>
        </New>
    </Arg>
  </Call>
</Configure>

接下来你需要让插件知道应用上面的文件:

<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <configuration>
    <jettyXml>jetty.xml,jetty-ssl.xml,jetty-https.xml</jettyXml>
  </configuration>
</plugin>

注意:就像已安装的Jetty发布版本,xml文件的顺序是必要的。

你也能用jetty xml文件配置一个http连接器供插件使用。这儿同样用来自jetty发布版本的jetty-http.xml文件:

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
 
<!-- ============================================================= -->
<!-- Configure the Jetty Server instance with an ID "Server"       -->
<!-- by adding a HTTP connector.                                   -->
<!-- This configuration must be used in conjunction with jetty.xml -->
<!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
 
  <!-- =========================================================== -->
  <!-- Add a HTTP Connector.                                       -->
  <!-- Configure an o.e.j.server.ServerConnector with a single     -->
  <!-- HttpConnectionFactory instance using the common httpConfig  -->
  <!-- instance defined in jetty.xml                               -->
  <!--                                                             -->
  <!-- Consult the javadoc of o.e.j.server.ServerConnector and     -->
  <!-- o.e.j.server.HttpConnectionFactory for all configuration    -->
  <!-- that may be set here.                                       -->
  <!-- =========================================================== -->
  <Call name="addConnector">
    <Arg>
      <New class="org.eclipse.jetty.server.ServerConnector">
        <Arg name="server"><Ref refid="Server" /></Arg>
        <Arg name="factories">
          <Array type="org.eclipse.jetty.server.ConnectionFactory">
            <Item>
              <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                <Arg name="config"><Ref refid="httpConfig" /></Arg>
              </New>
            </Item>
          </Array>
        </Arg>
        <Set name="host"><Property name="jetty.host" /></Set>
        <Set name="port"><Property name="jetty.port" default="80" /></Set>
        <Set name="idleTimeout"><Property name="http.timeout" default="30000"/></Set>
        <Set name="soLingerTime"><Property name="http.soLingerTime" default="-1"/></Set>
      </New>
    </Arg>
  </Call>
 
</Configure>

接下来为插件添加配置列表:

<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <configuration>
    <jettyXml>jetty.xml,jetty-http.xml,jetty-ssl.xml,jetty-https.xml</jettyXml>
  </configuration>
</plugin>

配置你的WebApp

这些配置参数应用到你的webapp。他们对几乎所有目标都适用。

webApp
类org.eclipse.jetty.webapp.WebAppContext的一个扩展。你能用对象的setter方法配置你的webapp。下面是常用的一些:
 1)contextPath:你的webapp的上下文路径。默认是/。
 2)descriptor:web.xml文件的路径。
 3)defaultsDescriptor:webdefault.xml的路径,在web.xml之前使用。如果你不提供,Jetty用一个默认文件,在jetty-webapp.jar中。
 4)overrideDescriptor:web.xml文件路径,在你的web.xml之后应用。你能用这重载或者添加配置。
 5)tempDirectory:当你的webapp运行时,Jetty用于解压和拷贝jar包和jsp编译结果的文件夹。默认是${project.build.outputDirectory}/tmp。
 6)baseResource:Jetty提供静态资源的路径,默认是src/main/webapp。
 7)resourceBases:用于代替baseResource提供静态资源,是一个数组,可以提供多个提供静态资源的文件夹。
 8)baseAppFirst:默认“true”。

contextXml
一个上下文xml文件的路径,在webApp之后应用到你的webapp。

jetty:run

run目标不必构建webapp到WAR。取而代之,Jetty从它的源头部署webapp。它在Maven项目中查找webapp的组件部分,虽然你能在插件的配置中重载他们。例如,默认它查找:
 1)在${project.basedir}/src/main/webapp中的资源;
 2)在${project.build.outputDirectory}中的类;
 3)在${project.basedir}/src/main/webapp/WEB-INF/中的web.xml。
在部署前,插件自动的确认类被重建和更新。如果你改变了类的源代码,你的IDE会在后台自动的编译它,插件挑选改变的类。
你不需要打包webapp到WAR,节省部署周期时间。你能配置插件持续执行,扫描项目的改变并在需要的时候自动热部署。你做的任何改变会立即反应到运行中的Jetty实例中,让你能快速的从编码跳转到测试,而不是:编码、编译、打包、重部署、测试。
下面是一个简单的例子,每10秒执行一次改变扫描,并设置上下文路径到/test:

<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <configuration>
    <scanIntervalSeconds>10</scanIntervalSeconds>
    <webApp>
      <contextPath>/test</contextPath>
    </webApp>
  </configuration>
</plugin>

配置

除了webApp元素之外,jetty:run目标支持:
 1)classesDirectory:你的webapp编译后的类的位置。你应该很少需要设置这个参数。取而代之,你应该设置你的pom.xml中的build outputDirectory。
 2)testClassesDirectory:你的webapp的编译后的测试类的位置。默认是 ${project.build.testOutputDirectory}。
 3)useTestScope:如果true,testClassesDirectory中的类和“test”范围的依赖首先被放置在classpath。默认是false。
 4)webAppSourceDirectory:默认,这被设置到 ${project.basedir}/src/main/webapp。如果你的静态资源在不同的位置,相应地设置该参数。
 5)jettyEnvXml:可选。jetty-env.xml文件的位置。
 6)scanTargets:可选。文件和文件夹的列表,除了那些插件自动扫描的目录和文件,插件增加对这些配置的周期扫描。
 7)scanTargetPatterns:可选。如果你需要额外扫描的文件列表过长,你可以通过匹配表达式来指定它们。
下面是一个更详细的配置的例子:

<project>
... 
  <plugins>
... 
    <plugin>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-maven-plugin</artifactId>
      <configuration>
        <webAppSourceDirectory>${project.basedir}/src/staticfiles</webAppSourceDirectory>
        <webApp>
          <contextPath>/</contextPath>
          <descriptor>${project.basedir}/src/over/here/web.xml</descriptor>
          <jettyEnvXml>${project.basedir}/src/over/here/jetty-env.xml</jettyEnvXml>
        </webApp>
        <classesDirectory>${project.basedir}/somewhere/else</classesDirectory>
        <scanTargets>
          <scanTarget>src/mydir</scanTarget>
          <scanTarget>src/myfile.txt</scanTarget>
        </scanTargets>
        <scanTargetPatterns>
          <scanTargetPattern>
            <directory>src/other-resources</directory>
            <includes>
              <include>**/*.xml</include>
              <include>**/*.properties</include>
            </includes>
            <excludes>
              <exclude>**/myspecial.xml</exclude>
              <exclude>**/myspecial.properties</exclude>
            </excludes>
          </scanTargetPattern>
        </scanTargetPatterns>
      </configuration>
    </plugin>
  </plugins>
</project>

如果在某些情况下,你不能运行在未打包webapp上,可以考虑使用run-war和run-exploded目标。

jetty:run-war

这个目标首先将你的webapp打包为WAR,然后部署它到Jetty。如果你设置非0的scanInterval,Jetty监视你的pom.xml和WAR文件;如果改变,它重部署war。

配置

war:WAR文件的位置。默认是${project.build.directory}/${project.build.finalName}.war。如果需要,设置你的自定义路径。
下面是配置的例子:

<project>
... 
  <plugins>
...
    <plugin>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>jetty-maven-plugin</artifactId>
      <configuration>
        <war>${project.basedir}/target/mycustom.war</war>
      </configuration>
    </plugin>
  </plugins>
</project>

jetty:run-exploded

run-exploded目标首先打包你的webapp到一个分解的WAR文件,然后部署它到Jetty。如果你设置了非0的scanInterval,Jetty监视你的pom.xml、WEB-INF/lib、WEB-INF/中的类和WEB-INF/web.xml,发现改变后在必要的时候重新部署。

配置

war:分解的WAR的位置。默认是 ${project.build.directory}/${project.build.finalName},你可以通过设置该参数覆盖该值。
下面是配置的例子:

<project> 
... 
  <plugins>
... 
    <plugin>
      <groupId>org.eclipse.jetty</groupId>
      <artifactId>maven-jetty-plugin</artifactId>
      <configuration>
        <war>${project.basedir}/target/myfunkywebapp</war>
      </configuration>
    </plugin>
  </plugins>
</project>

jetty:deploy-war

这个基本上和jetty:run-war相同,除了没有装配当前模块的WAR。不想run-war,插件不必执行到"package"阶段。例如,你可以启动jetty在"test-compile"阶段,停止jetty在"test-phase"阶段。

配置

war:WAR文件的位置。默认 ${project.build.directory}/${project.build.finalName},你能通过设置该参数覆盖该值。
下面是配置的例子:

<project>
... 
  <plugins>
... 
  <plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <configuration>
      <war>${project.basedir}/target/mycustom.war</war>
    </configuration>
    <executions>
      <execution>
        <id>start-jetty</id>
        <phase>test-compile</phase>
        <goals>
          <goal>deploy-war</goal>
        </goals>
        <configuration>
          <daemon>true</daemon>
          <reload>manual</reload>
        </configuration>
      </execution>
      <execution>
        <id>stop-jetty</id>
        <phase>test</phase>
        <goals>
          <goal>stop</goal>
        </goals>
      </execution>
     </executions>
    </plugin>
  </plugins>
</project>

jetty:run-forked

这个目标允许你在一个新的JVM中启动webapp,随意地传递参数到新的JVM。

配置

注意:不幸的是,不想大部分其它目标,这个不支持webApp参数。因此,如果你的webapp要求许多配置,则不能使用该目标。
下面是可用的配置参数:
 1)jettyXml:jetty xml配置文件的位置,用于在新的JVM中配置容器。
 2)contextXml:可选。上下文文件的位置,用于在新的JVM中配置webapp。
 3)contextPath:可选。新JVM中webapp的上下文路径。默认 /${project.artifactId}。
 4)webAppSourceDirectory:可选。你的webapp的静态资源位置。默认src/main/webapp。
 5)resourceBases:可选。包含你的webapp静态内容的文件夹数组,与webAppSourceDirectory一起。也看baseAppFirst。
 6)baseAppFirst:默认“true”。控制webAppSourceDirectory或者resourceBases是否第一个在资源列表上。
 7)webXml:web.xml文件的位置。默认src/main/webapp/WEB-INF/web.xml。
 8)tmpDirectory:临时文件夹。默认 ${project.build.directory}/tmp。
 9)classesDirectory:编译后的类文件位置。默认 ${project.build.outputDirectory}。
 10)testClassesDirectory:编译后测试类位置。默认 ${project.build.testOutputDirectory}。
 11)useTestScope:默认“false”。如果true,范围"provided"的依赖被放置到jetty容器的classpath。
 12)stopPort:强制的。一个端口号,jetty用于监听stop命令。如果配置,stopKey被用于认证接收的stop命令。
 13)stopKey:强制的。一个String,用于认证stop命令。
 14)skip:可选。默认false。如果true,插件的执行被略过。
 15)jvmArgs:可选。一个String,表示传递到新JVM的任意参数。
为了部署你的未装配的web应用到运行在新JVM中的Jetty:

mvn jetty:run-forked

Jetty将持续执行直到:
 1)在终端窗口执行ctrl+c,同时也停止另一个JVM。
 2)用jetty:stop停止另一个JVM,也停止插件。
注意:如果你想设置一个自定义端口,你需要指定它在jetty.xml文件中,而不是设置连接器和端口标签。你能使用jettyXml参数执行jetty.xml的位置。

jetty:start

这个目标类似于jetty:run目标,然而它直到"test-compile"才执行构建,以确保所有webapp需要的类和文件已经被产生。当你想控制Jetty的start和stop时这是非常有用的。
例如,你能配置插件在你的单元测试开始的时候启动,在单元测试结束时停止。为了做这,你需要为Jetty插件设置一套execution方案,用<daemon>true</daemon>配置选项使Jetty仅当Maven运行时执行。你用pre-integration-test和post-integration-test Maven构建阶段触发Jetty的执行和终止:

<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <configuration>
    <scanIntervalSeconds>10</scanIntervalSeconds>
    <stopKey>foo</stopKey>
    <stopPort>9999</stopPort>
  </configuration>
  <executions>
    <execution>
      <id>start-jetty</id>
      <phase>pre-integration-test</phase>
      <goals>
        <goal>start</goal>
      </goals>
      <configuration>
        <scanIntervalSeconds>0</scanIntervalSeconds>
        <daemon>true</daemon>
      </configuration>
    </execution>
    <execution>
      <id>stop-jetty</id>
      <phase>post-integration-test</phase>
       <goals>
         <goal>stop</goal>
       </goals>
     </execution>
  </executions>
</plugin>

当然你也可以在命令行中使用该目标,但你你需要确保你的webapp需要的所有类和文件已经被产生。

jetty:stop

stop目标用于停止Jetty。为了使用它,你需要使用一个特殊的端口号和key来配置插件。这个端口号和key也将用于start目标。
 1)stopPort:Jetty用于接收stop命令的端口号。
 2)stopKey:用于验证stop命令。
下面是配置的例子:

<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <configuration>
    <stopPort>9966</stopPort>
    <stopKey>foo</stopKey>
    <stopWait>10</stopWait>
  </configuration>
</plugin>

当Jetty正在运行时,执行:

mvn jetty:stop

注意stopPort必须是空闲的。

配置安全设置

你能在插件中配置LoginServices。下面是为webapp设置HashLoginService的例子:

<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <configuration>
    <scanIntervalSeconds>10</scanIntervalSeconds>
    <webApp>
      <contextPath>/test</contextPath>
    </webApp>
    <loginServices>
      <loginService implementation="org.eclipse.jetty.security.HashLoginService">
        <name>Test Realm</name>
        <config>${project.basedir}/src/etc/realm.properties</config>
      </loginService>
    </loginServices>
  </configuration>
</plugin>

用多个Webapp Root文件夹

如果你有额外的资源想要合并到当前的webapp中,但没有被集成到WAR中,你能告诉Jetty这些额外的资源位于的文件夹。在运行时,当Jetty收到一个资源请求时,它搜索所有的路径得到资源。下面是配置例子:

<configuration>
  <webApp>
    <contextPath>/${build.finalName}</contextPath>
    <baseResource implementation="org.eclipse.jetty.util.resource.ResourceCollection">
      <resourcesAsCSV>src/main/webapp,/home/johndoe/path/to/my/other/source,/yet/another/folder</resourcesAsCSV>
    </baseResource>
  </webApp>
</configuration>

运行超过一个Webapp

你能用一个jetty.xml文件配置你想部署的额外的(预编译的)webapp,或者你能用<contextHandlers>配置元素来做。如果你想部署webapp A,和webapp B和C在同一个Jetty实例中:

放配置想在webapp A的 pom.xml中:

<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <configuration>
    <scanIntervalSeconds>10</scanIntervalSeconds>
    <webApp>
      <contextPath>/test</contextPath>
    </webApp>
    <contextHandlers>
      <contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
        <war>${project.basedir}../../B.war</war>
        <contextPath>/B</contextPath>
      </contextHandler>
      <contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
        <war>${project.basedir}../../C.war</war>
        <contextPath>/B</contextPath>
      </contextHandler>
    </contextHandlers>
  </configuration>
</plugin>

或者,增加一个jetty.xml文件到webapp A。从jetty发布版本中拷贝jetty.xml文件,然后为其它两个webapp增加WebAppContext:

<Ref refid="Contexts">
  <Call name="addHandler">
    <Arg>
      <New class="org.eclipse.jetty.webapp.WebAppContext">
        <Set name="contextPath">/B</Set>
        <Set name="war">../../B.war</Set>
      </New>
    </Arg>
  </Call>
  <Call>
    <Arg>
      <New class="org.eclipse.jetty.webapp.WebAppContext">
        <Set name="contextPath">/C</Set>
        <Set name="war">../../C.war</Set>
      </New>
    </Arg>
  </Call>
</Ref>

然后配置这个jetty.xml文件的位置到webapp A的jetty插件:

<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <configuration>
    <scanIntervalSeconds>10</scanIntervalSeconds>
    <webApp>
      <contextPath>/test</contextPath>
    </webApp>
    <jettyXml>src/main/etc/jetty.xml</jettyXml>
  </configuration>
</plugin> 

为这任何一种方式,其它的webapp都必须已经被构建,并且他们会被监控变化。

设置系统属性

你能用maven properites插件定义系统属性。下面是一个例子配置logback logging系统作为jetty logger:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>properties-maven-plugin</artifactId>
  <version>1.0-alpha-2</version>
  <executions>
    <execution>
      <goals>
        <goal>set-system-properties</goal>
      </goals>
      <configuration>
        <properties>
          <property>
            <name>logback.configurationFile</name>
            <value>${project.baseUri}/resources/logback.xml</value>
          </property>
        </properties>
      </configuration>
    </execution>
  </executions>
</plugin>

注意:如果一个系统属性已经被设置(例如,从命令行或者通过JVM),那么默认这些配置属性不覆盖他们(看下面的<force>参数的使用)。

指定系统属性在POM中

下面是一个例子怎么在POM中指定系统属性:

<plugin> 
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <configuration> 
    <systemProperties>
      <systemProperty>
        <name>fooprop</name>
        <value>222</value>
      </systemProperty>
    </systemProperties>
    <webApp>
      <contextPath>/test</contextPath>
    </webApp>
  </configuration> 
</plugin>

为了改变默认的行为,使这些系统属性覆盖命令行中指定的那些,使用<force>参数:

<plugin> 
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <configuration>
    <systemProperties>
      <force>true</force>
      <systemProperty>
       <name>fooprop</name>
       <value>222</value>
     </systemProperty>
    </systemProperties>
    <webApp>
      <contextPath>/test</contextPath>
    </webApp>
  </configuration>
</plugin>

在文件中指定系统属性

你也能在一个文件中指定你的系统属性。通过这种方式指定的系统属性不会覆盖命令行、JVM和POM中指定的系统属性。
假定我们与一个文件mysys.props,包含:

fooprop=222

在插件中的配置方式如下;

<plugin>
  <groupId>org.eclipse.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <configuration>
    <systemPropertiesFile>${project.basedir}/mysys.props</systemPropertiesFile>
    <webApp>
      <contextPath>/test</contextPath>
    </webApp>
  </configuration>
</plugin>

你也能通过在命令行设置系统属性jetty.systemPropertiesFile来指定文件。

被Jetty Maven插件扫描的文件

如果你设置一个非0的scanInterval配置参数,jetty maven插件将每scanInterval执行一次文件扫描,如果发现变化,则根据配置重新部署webapp。被扫描的文件依赖被执行的目标。

目标文件
Jetty:runpom.xml, <dependencies>, <classesDirectory>, <testClassesDirectory>, <webXml> or <webAppSourceDirectory>/WEB-INF/web.xml, <jettyEnvXml> or <webAppSourceDirectory>/WEB-INF/jetty-web.xml, <webAppSourceDirectory>/WEB-INF/jetty-web.xml, <scanTargets>, <scanTargetPatterns>, any defaultsDescriptor for the webapp, any overrideDescriptor for the webapp
jetty:run-warpom.xml, <war>
jetty:run-explodedpom.xml, <war>/WEB-INF/web.xml, <war>/WEB-INF/jetty-web.xml, <war>/WEB-INF/jetty-env.xml,<war>/WEB-INF/classes, <war>/WEB-INF/lib
jetty:deploy-warpom.xml, <war>
jetty:run-forked 
jetty:startpom.xml, <dependencies> from the pom, <classesDirectory>, <testClassesDirectory>, <webXml> or <webAppSourceDirectory>/WEB-INF/web.xml, <jettyEnvXml> or <webAppSourceDirectory>/WEB-INF/jetty-web.xml, <webAppSourceDirectory>/WEB-INF/jetty-web.xml, <scanTargets>, <scanTargetPatterns>, any defaultsDescriptor for the webapp, any overrideDescriptor for the webapp
jetty:stop 

 

 

 

 

 

 

 

 

 

 

 

 

 

Jetty Jspc Maven插件

这个插件将帮助你预编译你的jsp,并和相关的maven war插件一起放他们到集成的war中。

配置

下面是jspc插件要求的基本设置:

<plugin>
  <groupId>org.eclipse.jetty</groupId>
   <artifactId>jetty-jspc-maven-plugin</artifactId>
   <version>9.1.0.RC1</version>
   <executions>
     <execution>
       <id>jspc</id>
       <goals>
         <goal>jspc</goal>
       </goals>
       <configuration>
       </configuration>
     </execution>
   </executions>
 </plugin>

配置参数(configuration)如下:

webXmlFragment
 默认值:${project.basedir}/target/webfrag.xml
 用于产生servlet声明。将被嵌入到一个存在的web.xml中。

webAppSourceDirectory
 默认值:${project.basedir}/src/main/webapp
 jsps、tags等放置的资源文件夹的根。

webXml
 默认值:${project.basedir}/src/main/webapp/WEB-INF/web.xml

includes
 默认值:**\/*.jsp, **\/*.jspx
 逗号分隔的模式列表,指定将被处理的文件。

excludes
 默认值:**\/.svn\/**
 逗号分隔的模式列表,指定排除的文件。

classesDirectory
 默认值:${project.build.outputDirectory}
 webapp的类放置的路径

generatedClasses
 默认值:${project.build.outputDirectory}
 jsp产生的类放置的路径

insertionMarker
 默认值:none
 一个标记String,在源web.xml中,指示长生的web.xml片段的插入位置。

useProvidedScope
 默认值:true 是否嵌入产生的片段文件到源web.xml。嵌入的文件将进入同样的文件夹作为webXmlFragment。

keepSources
 默认值:false
 如果true,产生的.java文件被处理完后将不被删除。

tldJarNamePatterns
 默认值:.*taglibs[^/]*\.jar|.*jstl-impl[^/]*\.jar$
 在包含tld的‘系统’(例如容器)路径上的jar的模式。用|分隔。

jspc
 默认值:org.apache.jasper.JspC

JspC类真正执行预编译。在JspC类上的所有setter都是可用的。你能从这里下载javadoc。

采用所有的默认值,下面是怎么配置war查将,使用产生的web.xml,包含所有jsp servlet声明:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-war-plugin</artifactId>
  <configuration>
    <webXml>${project.basedir}/target/web.xml</webXml>
  </configuration>
</plugin>