首页 > 代码库 > Maven实战读书笔记(13)

Maven实战读书笔记(13)

WAR

1、基于JavaWeb应用,其标准的打包方式是WAR

2WARJAR类似,不过它包含更多的内容,如JSP文件、ServletJava类、web.xml配置文件、依赖JAR包、静态web资源(如HTMLCSSJavaScript文件)等

 

一个典型的WAR文件的目录结构

- war /

 + META-INF /

 + WEB-INF /

 | + classes /

 | | + ServletA.class

 | | + config.properties

 | | + ...

 | |

 | |

 | + lib /

 | | + dom4j-1.4.1.jar

 | | + mail-1.4.1.jar

 | | + ...

 | |

 | + web.xml

 |

 + img /

 |

 + css /

 |

 + js /

 |

 + index.html

 + sample.jsp

1、一个WAR包下至少包含两个子目录,META-INFWEB-INF,前者包含了一些打包元数据信息,不用关心,后者是WAR包的核心,WEB-INF下必须包含一个Web资源表示文件web.xml

2WEB-INF的子目录classes包含所有该Web项目的类,而另一个子目录lib则包含所有该Web项目的依赖的JAR包,classeslib目录都会在运行的时候被加入到Classpath

3、除了META-INFWEB-INF一般的WAR包都会包含很多Web资源例如你往往可以在WAR包的根目录下看到很多html或者jsp文件,此外,还能看到一些文件夹如imgcssjs

 

显式指定Web项目的打包方式为war

<project>

...

       <groupId>com.juvenxu.mvnbook</groupId>

       <artifactId>sample-war</artifactId>

       <packaging>war</packaging>

       <version>1.0-SNAPSHOT</version>

...

</project>

如果不显示指定packagingMaven会使用默认的jar打包方式,从而导致无法正确打包Web项目

 

一个典型的Web项目的Maven目录结构如下

+ project

 |

 + pom.xml

 |

 + src/

  + main /

  | + java /

  | | + ServletA.java

  | | + ...

  | |

  | + resources /

  | | + config.properties

  | | + ...

  | |

  | + webapp /

  |   + WEB-INF /

  |   | + web.xml

  |   |

  |   + img /

  |   |

  |   + css /

  |   |

  |   + js /

  |   +

  |   + index.html

  |   + sample.jsp

  |

  + test /

    + java /

    + resources /

 

一般配置finalName元素,更改war包的名称

1、该元素默认值已在超级的POM中设定,值为 $ {project.artifactId}-$ {project.version}

2、不过上面这样的名称显然不利于部署

3、配置<finalName>account</finalName>,项目生成的war包名称就会成为account.war,方便部署

 

关于Web测试

1、一般方式,将war包部署到应用服务器,然后打开浏览器进行测试,比如验证程序功能、验证页面布局,尤其是一些与页面相关的的特性

2、近年来也出现了很多自动化的Web测试技术如Selenium,它能够录制Web操作,生成各种语言脚本,然后自动重复这些操作以进行测试,这类技术方法是未来的趋势,但是还是无法完全替代,手动的、亲眼对比的验证的测试

 

关于Web页面测试和底层代码测试的一些建议

1、在介绍jetty-maven-plugin之前,要强调一点,虽然手动的Web页面测试是必不可少的,但这种方法绝不应该被滥用

2、现实中常见的情况是,很多程序员即使修改了一些较为底层的代码 (如数据库访问、业务逻辑),都会习惯性地打开浏览器测试整个应用,这往往是没有必要的

3、可以用单元测试覆盖的代码就不应该依赖于Web页面测试,且不说页面测试更加耗时耗力,这种方式还无法自动化,更别提重复性了

4、因此Web页面测试应该仅限于页面的层次,例如JSPCSSJavaScript的修改,其他代码修改 (如数据访问),请编写单元测试

 

为什么使用jetty-maven-plugin这个插件帮助测试?

1、传统的Web测试方法要求我们编译、测试、打包及部署,这往往会消耗数10秒至数分钟的时间,jetty-maven-plugin能够帮助我们节省时间,它能够周期性地检查项目内容,发现变更后自动更新到内置的Jetty Web容器

2、换句话说,它帮我们省去了打包和部署的步骤,jetty-maven-plugin默认就很好地支持了Maven的项目目录结构,在通常情况下,我们只需要直接在IDE中修改源码,IDE就能够执行自动编译,jetty-maven-plugin发现编译后的文件变化后,自动将其更新到Jetty容器,这时就可以直接测试Web页面了

 

配置jetty-maven-plugin

<plugin>

       <groupId>org.mortbay.jetty</groupId>

       <artifactId>jetty-maven-plugin</artifactId>

       <version>7.1.6.v20100715</version>

       <configuration>

              <scanIntervalSeconds>10</scanIntervalSeconds>

              <webAppConfig>

                     <contextPath>/test</contextPath>

              </webAppConfig>

       </configuration>

</plugin>

对上述配置进行解释

1jetty-maven-plugin并不是官方的Maven插件,它的groupIdorg.mortbay.jetty

2、使用了Jetty 7的最新版本,在该插件的配置中,scanIntervalSeconds顾名思义表示该插件扫描项目变更的时间间隔,这里的配置是每隔10

3、需要注意的是,如果不进行配置,该元素的默认值是0,表示不扫描,用户也就失去了所谓的自动化热部署的功能

4webappConfig元素下的contextPath表示项目部署后的context path,例如这里的值为/test,那么用户就可以通过http://hostname:port/test/访问该应用

 

配置jetty-maven-plugin插件的命令行简化操作

默认情况下,只有org.apache.maven.pluginsorg.codehaus.mojo两个groupId下的插件才支持简化的命令行调用,即可以运行mvn help:system,但mvn jetty:run就不行了

这是因为,maven-help-plugingroupIdorg.apache.maven.plugins,而jetty-maven-plugingroupIdorg.mortbay.jetty,为了直接能在命令行直接运行mvn jetty:run,用户需要配置settings.xml

<settings>

       <pluginGroups>

              <pluginGroup>org.mortbay.jetty</pluginGroup>

       </pluginGroups>
</settings>

 

启动Jetty

命令mvn jetty:run

jetty-maven-plugin会启动Jetty,并且默认监听本地的8080端口,并将当前项目部署到容器中,同时它还会根据用户配置扫描代码改动

 

如果希望使用其他端口,运行jetty

可以添加jetty.port参数

mvn jetty:run -Djetty.port=9999

 

关于jetty-maven-plugin插件自动扫描的说明

启动jetty后,用户可以在IDE中修改各类文件,如JSPHTMLCSSJavaScript甚至是Java类。只要不是修改类名、方法名等较大的操作,jetty-maven-plugin都能够扫描到变更并正确地将变化更新至Web容器中

 

jetty-maven-plugin插件的进一步研究

1、热部署仅仅是jetty-maven-plugin插件最核心的配置点

2、还可以自定义web.xml的位置、项目class文件的位置、web资源目录的位置等

3、用户还能够以WAR包的方式部署项目,然后执行一些集成测试,最后停止容器

4、进一步研究地址,http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin

 

使用Cargo实现自动化部署,Cargo是什么?

Cargo是一组帮助用户操作Web容器的工具,它能够帮助用户实现自动化部署,而且它几乎支持所有的Web容器,如TomcatJBossJettyGlassfish等。

Gargo通过cargo-maven2-plugin提供了Maven集成,Maven用户可以使用该插件将Web项目部署到Web容器中

 

cargo-maven2-pluginjetty-maven-plugin的区别

虽然cargo-maven2-pluginjetty-maven-plugin的功能看起来很相似,但它们的目的是不同的

1jetty-maven-plugin主要用来帮助日常的快速开发和测试

2cargo-maven2-plugin主要服务于自动化部署

 

Cargo的部署

Cargo支持两种本地部署的方式,分别为standalone模式和existing模式

1standalone模式中,Cargo会从Web容器的安装目录复制一份配置到用户指定的目录,然后在此基础上部署应用,每次重新构建的时候,这个目录都会被清空,所有配置被重新生成

2、而在existing模式中,用户需要指定现有的Web容器配置目录,然后Cargo会直接使用这些配置并将应用部署到其对应的位置

 

使用standalone模式部署应用至本地Web容器(tomcat6x)
<plugin>

       <groupId>org.codehaus.cargo</groupId>

       <artifactId>cargo-maven2-plugin</artifactId>

       <version>1.0</version>

       <configuration>

              <container>

                     <containerId>tomcat6x</containerId>

                     <home>D:\cmd\apache-tomcat-6.0.29</home>

              </container>

              <configuration>

                     <type>standalone</type>

                     <home>${project.build.directory}/tomcat6x</home>

              </configuration>

       </configuration>

</plugin>

对上面的配置进行解释:

1cargo-maven2-plugingroupIdorg.codehaus.cargo,这不属于官方的两个Maven插件groupId,因此用户需要将其添加到settings.xmlpluginGroup元素中以方便命令行调用

2cargo-maven2-plugin包括了containerconfiguration两个元素,configuration的子元素type表示部署的模式(这里是standaloneconfiguration的子元素home表示复制容器配置到什么位置,这里的值为${project.build.directory}/tomcat6x,表示构件输出目录,即target/下的tomcat6x子目录

3container元素下的containerId表示容器的类型,home元素表示容器的安装目录

4、基于该配置Cargo会从D:\cmd\apache-tomcat-6.0.29目录下复制配置到当前项目的target/tomcat6x/目录下

5、执行mvn cargo:start,让Cargo启动Tomcat并部署应用

 

Cargo会让Web容器监听8080端口,如何修改端口号为8081

<plugin>

       <groupId>org.codehaus.cargo</groupId>

       <artifactId>cargo-maven2-plugin</artifactId>

       <version>1.0</version>

       <configuration>

              <container>

                     <containerId>tomcat6x</containerId>

                     <home>D:\cmd\apache-tomcat-6.0.29</home>

              </container>

              <configuration>

                     <type>standalone</type>

                     <home>${project.build.directory}/tomcat6x</home>

                     <properties>

                            <cargo.servlet.port>8081</cargo.servlet.port>

                     </properties>

              </configuration>

       </configuration>

</plugin>

 

使用existing模式部署应用至本地Web容器

<plugin>

       <groupId>org.codehaus.cargo</groupId>

       <artifactId>cargo-maven2-plugin</artifactId>

       <version>1.0</version>

       <configuration>

              <container>

                     <containerId>tomcat6x</containerId>

                     <home>D:\cmd\apache-tomcat-6.0.29</home>

              </container>

              <configuration>

                     <type>existing</type>

                     <home> D:\cmd\apache-tomcat-6.0.29</home>

              </configuration>

       </configuration>

</plugin>

 

部署至远程Web容器?没测出来,他妈的。

 


Maven实战读书笔记(13)