Jetty开发指导:Maven和Jetty
使用MavenApache Maven是一种软件项目管理和综合工具。基于项目对象模型(POM)的概念,Maven能从核心信息管理一个项目的构建、报告和文档。他是用于构建一个web应用项目的理想工具,这些项目能用jetty-maven-plugin轻松的运行web应用,从而节省开发时间。你也能用Maven构建、测试和运行一个嵌入Jetty的项目。首先我们将看一个很简单嵌入Jetty的He
使用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:run | pom.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-war | pom.xml, <war> |
jetty:run-exploded | pom.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-war | pom.xml, <war> |
jetty:run-forked | |
jetty:start | pom.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>
更多推荐
所有评论(0)