
When you search for artifacts using http://repository.sonatype.org, the browser is querying the Nexus repository using a REST API. In this post, I’m going to show you some simple Ruby scripts which you can use to search the Maven repository ...
If you are looking for the easiest way to search for artifacts in the Central Maven Repository, go to http://repository.sonatype.org. Sonatype maintains a publi instance of Nexus that can be used to search for artifacts by GAV (groupId, artifactId...
A common question from Apache Maven users is “How do I search the central repository?” or “How do I find out what groupId or artifactId I should use for a specific dependency?” Use Sonatype’s Nexus installation at htt...
One of the users on the m2eclipse user list has some great feedback about a presentation he did at the Stockholm JUG on the best of breed Maven tooling which includes Nexus and m2eclipse. Apparently people are impressed with the Maven support insi...
Maven 3.0 uses a new standalone component that handles inheritance and interpolation of a model in any format. The model needn’t even be XML based. If you can translate your model into a list of property-value pairs, you can use this framewo...
There’s are lots of people who already know that Mark de Visser is the new CEO of Sonatype, but Zack wrote a nice bit about it today in his InfoWorld blog: http://weblog.infoworld.com/openresource/archives/2008/11/marketing_maven.html I am r...
本章我们使用 Maven Archetype 插件创建一个简单的 web 应用程序。 我们将会在一个名为 Jetty 的 Servlet 容器中运行这个 web 应用程序,同时添加一些依赖,编写一个简单的 Servlet,并且生成一个 WAR 文件。 本章最后,你将能够开始使用 Maven 来提高你开发 web 应用程序的速度。
本章的样例是通过 Maven Archetype 插件生成的。
虽然没有样例源码你也应该能够理解这个开发过程,但还是推荐你下载样例源码作为参考。
本章的样例项目包含在本书的样例代码中,你可以从两个地方下载,http://www.sonatype.com/book/mvn-examples-1.0.zip
或者 http://www.sonatype.com/book/mvn-examples-1.0.tar.gz
。解开存档文件至任意目录,然后到 ch05/ 目录。 在
ch05/ 目录你会看到一个名为
simple-webapp/ 的目录,它包含了本章开发出来的 Maven
项目。如果你想要在浏览器里看样例代码,访问 http://www.sonatype.com/book/examples-1.0
,然后点击 ch05/ 目录。
我们已经有意的使本章关注于一个简单 Web 应用(POWA)—— 一个 servlet 和一个 JSP 页面。 在接下来的二十多页中,我们不会告诉你如何开发你的 Struts 2,Tapesty,Wicket,JSF,或者 Waffle 应用,我们也不会涉及到集成诸如 Plexus,Guice 或者 Spring Framework 之类的 IoC 容器。 本章的目标是展示给你看开发 web 应用的时候 Maven 提供的基本设备,不多,也不少。 本书的后面,我们将会看一下开发两个 web 应用,一个使用了 Hibernate, Velocity 和 Spring Framework,另外一个使用了 Plexus。
创建你的 web 应用程序项目,运行 mvn archetype:create ,加上参数
artifactId 和 groupId。 指定
archetypeArtifactId 为
maven-archetype-webapp。 如此便创建了恰到好处的目录结构和 Maven
POM。
~/examples$ mvn archetype:create -DgroupId=org.sonatype.mavenbook.ch05 \
-DartifactId=simple-webapp \
-DpackageName=org.sonatype.mavenbook \
-DarchetypeArtifactId=maven-archetype-webapp
[INFO] [archetype:create]
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating Archetype: maven-archetype-webapp:RELEASE
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.sonatype.mavenbook.ch05
[INFO] Parameter: packageName, Value: org.sonatype.mavenbook
[INFO] Parameter: basedir, Value: ~/examples
[INFO] Parameter: package, Value: org.sonatype.mavenbook
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: artifactId, Value: simple-webapp
[INFO] ********************* End of debug info from resources from generated POM *******
[INFO] Archetype created in dir: ~/examples/simple-webapp 在 Maven Archetype 插件创建好了项目之后,切换目录至 simple-web
后看一下 pom.xml 。 你会看到如下的 XML
文档:
Example 5.1. simple-web 项目的初始 POM
<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.sonatype.mavenbook.ch05</groupId> <artifactId>simple-webapp</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>simple-webapp Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>simple-webapp</finalName> </build> </project>
注意 packaging 元素包含的值是 war
。这种打包类型配置让 Maven 以 WAR 文件的形式生成一个 web 应用。一个打包类型为
war 的项目,将会在 target/ 目录创建一个
WAR 文件,这个文件的默认名称是
${artifactId}-${version}.war 。对于这个项目, 默认的
WAR 文件是
target/simple-webapp-1.0-SNAPSHOT.war 。在这个
simple-webapp 项目中,我们已经通过在项目的构建配置中加入
finalName 元素来自定义这个生成的 WAR 文件的名称。根据
simple-webapp 的 finalName
,package 阶段生成的 WAR 文件为
target/simple-webapp.war 。
在你已经编译,测试并且打包了你的 web 应用之后,你会想要将它部署到一个 servlet 容器中,然后测试一下由 Maven
Archetype 插件创建的 index.jsp 。通常情况下,你需要下载 Jetty 或者
Apache Tomcat,解压分发包,复制你的应用程序 WAR 文件至
webapps/ 目录,然后启动你的容器。 现在,实现同样的目的,你不再需要做这些事情。
取而代之的是,你可以使用 Maven Jetty 插件在 Maven 中运行你的 web 应用。为此,你需要在项目的
pom.xml 中配置 Maven Jetty 插件。
在你项目的构建配置中添加如下插件元素:
Example 5.2. 配置 Jetty 插件
<project>
[...]
<build>
<finalName>simple-webapp</finalName>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
</plugin>
</plugins>
</build>
[...]
</project>在项目的 pom.xml中 配置好 Maven Jetty 插件之后,你就可以调用 Jetty
插件的 Run 目标在 Jetty Servlet 容器中启动你的 web 应用。如下运行 mvn
jetty:run :
~/examples$ mvn jetty:run
...
[INFO] [jetty:run]
[INFO] Configuring Jetty for project: simple-webapp Maven Webapp
[INFO] Webapp source directory = \
/Users/tobrien/svnw/sonatype/examples/simple-webapp/src/main/webapp
[INFO] web.xml file = \
/Users/tobrien/svnw/sonatype/examples/simple-webapp/src/main/webapp/WEB-INF/web.xml
[INFO] Classes = /Users/tobrien/svnw/sonatype/examples/simple-webapp/target/classes
2007-11-17 22:11:50.532::INFO: Logging to STDERR via org.mortbay.log.StdErrLog
[INFO] Context path = /simple-webapp
[INFO] Tmp directory = determined at runtime
[INFO] Web defaults = org/mortbay/jetty/webapp/webdefault.xml
[INFO] Web overrides = none
[INFO] Webapp directory = \
/Users/tobrien/svnw/sonatype/examples/simple-webapp/src/main/webapp
[INFO] Starting jetty 6.1.6rc1 ...
2007-11-17 22:11:50.673::INFO: jetty-6.1.6rc1
2007-11-17 22:11:50.846::INFO: No Transaction manager found - if your webapp requires one,\
please configure one.
2007-11-17 22:11:51.057::INFO: Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server
当 Maven 启动了 Jetty Servlet 容器之后,在浏览器中载入 URL http://localhost:8080/simple-webapp/
。 Archetype 生成的简单页面 index.jsp 没什么价值;它包含了一个文本为“Hello
World!”的二级标题。 Maven 认为 web 应用程序的文档根目录为
src/main/webapp 。这个目录就是存放
index.jsp 的目录 。 index.jsp 的内容为
Example 5.3, “src/main/webapp/index.jsp 的内容”:
在 src/main/webapp/WEB-INF 目录中我们会找到可能是最小的 web
应用程序描述符 web.xml。
Example 5.4. src/main/webapp/WEB-INF/web.xml 的内容
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> </web-app>
一个只有一个单独的 JSP 页面而没有任何配置好的 servlet 的 web 应用程序基本是没用的。 让我们为这个应用添加一个简单的
servlet ,同时为 pom.xml 和 web.xml
做些改动以支持这个变化。 首先,我们需要在目录 src/main/java 下创建一个名为
org.sonatype.mavenbook.web 的新的包。
$ mkdir -p src/main/java/org/sonatype/mavenbook/web $ cd src/main/java/org/sonatype/mavenbook/web
包创建好之后,切换目录至
src/main/java/org/sonatype/mavenbook/web ,创建一个名为
SimpleServlet.java 的 servlet 类,代码如下:
Example 5.5. SimpleServlet 类
package org.sonatype.mavenbook.web;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SimpleServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println( "SimpleServlet Executed" );
out.flush();
out.close();
}
}
我们的 SimpleServlet 仅此而已,一个往响应 Writer 打印一条简单信息的
servlet 。为了把这个 servlet 添加到你的 web 应用,并且使其与请求路径匹配,需要添加如下的
servlet 和 servlet-mapping 元素至你项目的
web.xml 文件。 文件 web.xml 可以在目录
src/main/webapp/WEB-INF 中找到。
Example 5.6. 匹配 Simple Servlet
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>simple</servlet-name> <servlet-class>org.sonatype.mavenbook.web.SimpleServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>simple</servlet-name> <url-pattern>/simple</url-pattern> </servlet-mapping> </web-app>
一切文件就绪,准备测试这个 servlet 。 src/main/java 下的类,以及
web.xml 已经被更新了。在启动 Jetty 插件之前,运行 mvn compile
以编译你的项目:
~/examples$ mvn compile
...
[INFO] [compiler:compile]
[INFO] Compiling 1 source file to ~/examples/ch05/simple-webapp/target/classes
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Compilation failure
~/ch05/simple-webapp/src/main/java/org/sonatype/mavenbook/web/SimpleServlet.java:[4,0] \
package javax.servlet does not exist
~/ch05/simple-webapp/src/main/java/org/sonatype/mavenbook/web/SimpleServlet.java:[5,0] \
package javax.servlet.http does not exist
~/ch05/simple-webapp/src/main/java/org/sonatype/mavenbook/web/SimpleServlet.java:[7,35] \
cannot find symbol
symbol: class HttpServlet
public class SimpleServlet extends HttpServlet {
~/ch05/simple-webapp/src/main/java/org/sonatype/mavenbook/web/SimpleServlet.java:[8,22] \
cannot find symbol
symbol : class HttpServletRequest
location: class org.sonatype.mavenbook.web.SimpleServlet
~/ch05/simple-webapp/src/main/java/org/sonatype/mavenbook/web/SimpleServlet.java:[9,22] \
cannot find symbol
symbol : class HttpServletResponse
location: class org.sonatype.mavenbook.web.SimpleServlet
~/ch05/simple-webapp/src/main/java/org/sonatype/mavenbook/web/SimpleServlet.java:[10,15] \
cannot find symbol
symbol : class ServletException
location: class org.sonatype.mavenbook.web.SimpleServlet
编译失败了,因为你的 Maven 项目没有对 Servlet API 的依赖。 在下一节,我们会为你项目的 POM 添加 Servlet API 。
为了编写一个 servlet ,我们需要添加 Servlet API 作为项目依赖。
Servlet 规格说明是一个 JAR 文件,它能从 Sun Microsystems 的站点下载到
http://java.sun.com/products/servlet/download.html
。JAR 文件下载好之后你需要把它安装到位于
~/.m2/repository 的 Maven 本地仓库。你必须为所有 Sun Microsystems
维护的 J2EE API 重复同样的过程,包括
JNDI, JDBC, Servlet,
JSP, JTA, 以及其它。
如果你不想这么做因为觉得这样太无聊了,其实不只有你这么认为。 幸运的是,有一种更简单的方法来下载所有这些类库并安装到本地仓库 —— Apache
Geronimo 的独立的开源实现。
很多年以来,获取 Servlet 规格说明 JAR 文件的唯一方式是从 Sun Microsystems 下载。 你必须到 Sun 的 web 站点,同意并且点击它的许可证协议,这样才能访问 Servlet JAR。这是必须的,因为 Sun 的规格说明 JAR 文件并没有使用一个允许再次分发的许可证。 很多年来编写一个 Servlet 或者使用 JDBC 之前你必须手工下载 Sun 的构件。 这很乏味并且令人恼火,直到 Apache Geronimo 项目创建了很多通过 Sun 认证的企业级规格说明实现。 这些规格说明 JAR 是按照 Apache 软件许可证版本 2.0 发布的,该许可证允许对源代码和二进制文件进行免费的再次分发。 现在,对你的程序来说,从 Sun Microsystems 下载的 Servlet API JAR 和从 Apache Geronimo 项目下载的 JAR 没什么大的差别。 它们同样都通过了 Sun Microsystems 的严格的一个测试兼容性工具箱(TCK)。
添加像 JSP API 或者 Servlet
API 这样的依赖现在很简单明了了,不再需要你从 web 站点手工下载
JAR 文件然后再安装到本地仓库。 关键是你必须知道去哪里找,使用什么
groupId, artifactId, 和
version 来引用恰当的 Apache Geronimo 实现。给
pom.xml 添加如下的依赖元素以添加对 Servlet 规格说明
API 的依赖。.
Example 5.7. 添加 Servlet 2.4 规格说明作为依赖
<project>
[...]
<dependencies>
[...]
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-servlet_2.4_spec</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
[...]
</project>
所有 Apache Geronimo 规格说明的实现的 groupId 都是
org.apache.geronimo.specs 。这个
artifactId 包含了你熟悉的规格说明的版本号;例如,如果你要引入 Servlet 2.3
规格说明,你将使用的 artifactId 是
geronimo-servlet_2.3_spec ,如果你想要引入 Servlet 2.4
规格说明,那么你的 artifactId 将会是
geronimo-servlet_2.4_spec 。你必须看一下 Maven 的公共仓库来决定使用什么版本。
最好使用某个规格说明实现的最新版本。 如果你在寻找某个特定的 Sun 规格说明对应的 Apache Geronimo
项目,我们已经在附录归纳了一个可用规格说明的列表。
这里还有必要指出的是我们的这个依赖使用了 provided 范围。这个范围告诉 Maven jar
文件已经由容器“提供”了,因此不再需要包含在 war 中。
如果你对在这个简单 web 应用编写自定义 JSP 标签感兴趣,你将需要添加对 JSP 2.0 规格说明的依赖。 使用以下配置来加入这个依赖。
Example 5.8. 添加 JSP 2.0 规格说明作为依赖
<project>
[...]
<dependencies>
[...]
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jsp_2.0_spec</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
[...]
</project>
在添加好这个 Servlet 规格说明依赖之后,运行 mvn clean install ,然后运行 mvn jetty:run 。
[tobrien@t1 simple-webapp]$ mvn clean install ... [tobrien@t1 simple-webapp]$ mvn jetty:run [INFO] [jetty:run] ... 2007-12-14 16:18:31.305::INFO: jetty-6.1.6rc1 2007-12-14 16:18:31.453::INFO: No Transaction manager found - if your webapp requires one,\ please configure one. 2007-12-14 16:18:32.745::INFO: Started SelectChannelConnector@0.0.0.0:8080 [INFO] Started Jetty Server
到此为止,你应该能够获取 SimpleServlet 的输出。 在命令行,你可以使用 curl 在标准输出打印 servlet 的输出。
~/examples$ curl http://localhost:8080/simple-webapp/simple
SimpleServlet Executed

