1.简介
之前的maven项目打包类型都为pom或者POM,今天讲一下用maven构建web应用,web应用的打包类型为war。
2.Web项目的目录结构
- java的web应用,其标准打包方式是war, war和jar类似,只不过它包含更多内容,如jsp文件、servlet文件、java类、web.xml配置,依赖包、静态web资源(html css js文件)等。
war文件目录结构如下:
jar文件目录结构如下:
-jar/
+META-INF/
+packagename
|+ java.class
|+ ...
- 一个WAR包至少包含两个子目录:META-INF和WEB-INF。
- META-INF:包含一些打包元数据,打包时会涉及到。
- WEB-INF:必须包含web资源描述文件web.xml。classes包含所有该web项目的类,而lib则包含所有web项目依赖的JAR包,classes和lib目录都会在运行的时候被加入到Classpath中。
- war包中的还包含了其他web资源,如html或者jsp,js,css等。
2.1Maven对web项目的布局约定
- maven对不同类型项目的布局结构要求不一样,对于web项目有一个通用的约定,不过用户必须显示制定web项目的打包类型为war才会按照正确的方式打包web项目。
- web项目的类及资源文件同一般的JAR项目一样,默认位置:src/main/java和src/main/resources。测试及测试资源文件默认位置:src/test/java和src/test/resources。Web项目比较特殊的地方在于:他有一个web资源目录,默认位置:src/main/webapp/
- 在src/main/webapp目录下除了html、jsp、css等必须包含子目录WEB-INF,且子目录必须包含web.xml文件。
- 在使用Maven创建Web项目之前必须理解Maven结构和WAR包结构的对应关系.
- 注意:WAR包中有一个lib目录包含所有依赖JAR包,但Maven项目结构中没有这样一个目录,这是因为依赖都配置在POM中,Maven在使用WAR方式打包的时候会根据POM的配置从本地仓库复制相应的JAR文件。
- 而对于JAR方式打包的时候不会把依赖打包进去,但是会在META-INF文件中包含pom.xml文件信息用于表明该jar包的依赖情况。maven---3手写一个helloWord----》6.补充:Maven打包的JAR文件目录内容
3.编写web项目
4.使用jetty-maven-plugin进行测试
4.1需求背景
- 进行web开发时需要测试,而测试内容可以分为和页面相关和页面无关的测试。
- 和页面无关的测试有:数据访问,业务逻辑等,这一类测试使用单元测试(junit或testNG就可以完成)。这一类测试不要通过浏览器来测试了,也不要滥用下面的方法来测试这些内容。
- 和页面有关的:如验证程序功能、验证页面布局、jsp、js、css修改等与页面相关的特性,都需要手动部署到web容器在打开浏览器进行测试。而传统的web页面测试需要手动编译、测试、打包及部署,往往消耗10几秒甚至更长。(jetty-maven-plugin要解决的事)
- jetty-maven-plugin能够帮助我们节省时间,它会周期性地检查项目内容,发现项目变更后(包括src中webapp中内容)自动更新到内置的jetty Web容器中。然后就可以直接测试web页面了。
- 注意:jetty-maven-plugin主要通过将项目自动部署到jetty中从而方便测试,所以在生产环境中不应该使用该方式,因为生成环境中我们的项目有可能部署到其它web容器中tomcat、jboss,jetty等,所以它主要用来帮助日常快速开发和测试
4.2实践
4.2.1配置插件
使用org.eclipse.jetty,该插件要求maven3.3+级以上版本。org.eclipse.jetty
- pom.xml配置
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.3.14.v20161028</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webApp>
<contextPath>/test</contextPath>
</webApp>
<httpConnector>
<port>8168</port>
<host>localhost</host>
</httpConnector>
</configuration>
</plugin>
scanIntervalSeconds 表示该插件扫描项目变更的时间间隔,如配置默认0,表示不扫描。
contextPath:表示项目部署后的context path。可以通过http://hostname:port/test访问该应用。
port端口,默认8080
host配置主机名,默认localhost
settings.xml配置
默认情况下,只有org.apache.maven.plugins和org.codehaus.mojo两个groupId下的插件才支持简化的命令调用,即mvn help:system,是可以的,因为maven-help-plugin的groupid是org.apache.maven.plugins。而mvn jetty:run就不行,因为jetty-maven-plugin的groupId是org.eclipse.jetty。更多原因请看 maven---7生命周期和插件--->8.4插件前缀
为了在命令行直接运行mvn jetty:run,用户需要配置settings.xml如下:
<pluginGroups>
<!-- pluginGroup
| Specifies a further group identifier to use for plugin lookup.
<pluginGroup>com.your.plugins</pluginGroup>
-->
<pluginGroup>org.eclipse.jetty</pluginGroup>
....
</pluginGroups>
4.2.2启动jetty
现在运行如下命令启动jetty-maven-plugin:
mvn jetty:run
默认端口8080,希望使用其他端口通过jetty.http.port参数,如
mvn jetty:run -Djetty.http.port=9999
启动jetty之后,用户修改类、jsp、html等都会被插件扫描到并重新自动部署。
4.2.3jetty-maven-plugin的其它配置
上面是jetty-maven-plugin的最核心配置,如果有需要可以自定义web.xml位置,项目class文件位置,web资源目录位置等。还能以war包方式部署项目,甚至在maven生命周期嵌入jetty-maven-plugin等,具体看官网介绍:org.eclipse.jetty。
4.3其它jetty-maven-plugin插件
除了上面的配置jetty的插件外,还有其它的,可以选择使用。网址org.mortbay.jetty,其配置我测试过了,也可以使用。同样也需要在settings.xml中配置pluginGroup。
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.5</version>
<configuration>
<webAppSourceDirectory>src/main/webapp</webAppSourceDirectory>
<scanIntervalSeconds>5</scanIntervalSeconds> 每隔10秒查看项目是否有变化,有变化重新编译
<contextPath>/iqasweb</contextPath>
<connectors>
org.mortbay.jetty.nio.SelectChannelConnector
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>8088</port> 服务器监听端口
</connector>
</connectors>
</configuration>
</plugin>
运行命令:jetty:run
5.使用Cargo实现自动化部署
- Cargo是一组帮助用户操作web容器的工具,它支持计划所有web容器(tomcat、jboss、jetty、glassfish等),Cargo通过cargo-maven2-plugin提供Maven集成,Maven使用该插件将Web项目部署到Web容器中。
- cargo-maven2-plugin和jetty-maven-plugin的功能相似,但目的不同。
- jetty-maven-plugin:帮助日常开发人员的快速开发和测试。
- cargo-maven2-plugin:服务于自动化部署。
插件官网:Cargo
5.1需求
- 专门的测试人员希望一条简单的Maven命令就可以构建项目并部署到Web容器中,然后进行功能测试。
- 以tomcat8为例,介绍如何自动化地将web应用部署至本地和远程web容器中。
5.2部署至本地Web容器
- Cargo支持两种本地部署方式:standalone模式和existing模式。
- standalone模式:Cargo会从Web容器的安装目录复制一份配置到用户指定的目录,然后在此基础上部署应用,每次重新构建的时候,这个目录都会被清空,所有配置被重新生成。
- existing模式:用户需要指定现有的Web容器配置的目录,然后Cargo会直接使用这些配置并将应用部署到其对应的位置。
5.2.1standalone模式
<!-- 配置cargo-maven2-plugin插件实现自动部署,命令cargo:start -->
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.5.1</version>
<configuration>
<container>
<containerId>tomcat8x</containerId>
<home>D:\Soft\tomcat\tomcat8.0.32</home>
</container>
<configuration>
<type>standalone</type>
<home>${project.build.directory}/tomcat8x</home>
<properties>
<cargo.servlet.port>8083</cargo.servlet.port>
</properties>
</configuration>
</configuration>
</plugin>
- 解释 配置了configuration和container
- configuration:type表示部署模式。home:表示复制容器配置到什么位置,${project.build.directory}/tomcat8x表示构建输出目录,即target/的tomcat8x子目录。
cargo.servlet.port配置容器监听端口,默认8080 - container: containerId表示容器的类型,home元素表示容器的安装目录,基于该配置,Cargo会从D:\Soft\tomcat\tomcat8.0.32目录下复制配置到当前项目的target/tomcat8x下。
5.2.2运行
- 使用命令
mvn clean package cargo:run
当然如果target已经有构建好的war可以直接cargo:run
- 然后进入浏览器进行访问:http://hostname:port/项目打包的名称/
访问的项目打包名称不是你项目名称,打包名称默认是artifactId-version.packing。可以通过 finalName来配置友好的名称。project/build/finalName. - 同样为了使用前缀简化命令调用cargo:run。在settings.xml中配置pluginGroup
<pluginGroups>
...
<pluginGroup>org.codehaus.cargo</pluginGroup>
</pluginGroups>
不然出现以下错误
[ERROR] No plugin found for prefix 'cargo' in the current project and in the plu
gin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repo
sitories [local (D:\Soft\maven\maven_jar\repository), nexus (http://172.19.201.1
55:8081/repository/maven-public/)] -> [Help 1]
5.2.3结束
命令:Ctr+C结束
5.2.4existing模式
要将应用直接部署到现有的Web容器下,使用该模式。
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.5.1</version>
<configuration>
<container>
<containerId>tomcat8x</containerId>
<home>D:\Soft\tomcat\tomcat8.0.32</home>
</container>
<configuration>
<type>existing</type>
<home>D:\Soft\tomcat\tomcat8.0.32</home>
<properties>
<cargo.servlet.port>9996</cargo.servlet.port>
</properties>
</configuration>
</configuration>
</plugin>
和standalone不同的是configuration下的目录表示现有Web容器目录,运行mvn cargo:start之后,便能够在tomcat的webapps子目录看到被部署的Maven项目。
5.3部署至远程web容器(吐血)
5.3.1配置
- 也可以让Cargo部署应用至远程的正在运行的Web容器中。当然,前提是拥有该容器的相应管理员权限。相关配置如下:
<!-- 配置cargo-maven2-plugin插件实现自动部署,部署至远程Web容器,命令cargo:start -->
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.4.4</version>
<configuration>
<container>
<containerId>tomcat8x</containerId>
<type>remote</type>
</container>
<configuration>
<type>runtime</type>
<properties>
<cargo.remote.username>tomcat_script</cargo.remote.username>
<cargo.remote.password>tomcat_script</cargo.remote.password>
<cargo.remote.uri>http://localhost:8080/manager/text</cargo.remote.uri>
</properties>
</configuration>
</configuration>
</plugin>
- 解释
- container的type值为remote,不然默认installed。
- configuration:的type为runtime,表示既不使用独立的容器配置,也不使用本地现有的容器配置,而是依赖一个已运行的容器。
properties声明一些容器热部署相关的配置。这里是tomcat8的用户名、密码、管理地址。
注意:配置的tomcat用户名要有manager-scripte权限。即在tomcat-users.xml配置
<user username="tomcat_script" password="tomcat_script" roles="manager-script"/>
对于的tomcat6及之前的版本,远程连接地址的写法和tomcat7、tomcat8不同,如下。
<cargo.remote.manager.url>http://localhost:8080/manager/html</cargo.remote.manager.url>
5.3.2运行
- 先启动tomcat。
- 执行mvn clean package cargo:redeploy
正常运行。
5.3.3没弄懂的地方
上面部署的远程tomcat其实是在本地localhost,部署是成功的,当我把项目部署到远程的tocmat上时即修改管理地址和远程tomcat的管理账号时。
<cargo.remote.uri>http://192.19.106.168:8080/manager/text</cargo.remote.uri>
结果出错:至今不知道问题出在哪,找了好久。。。。。。我在想是不是我的部署的项目太大了298M。但是部署到本地没有问题啊??希望懂得可以帮我解答一下,出错提示如下,查了很久说是权限,权限设置了manager-script,但是本地都可以,就是部署到远程不可以。。。。
[ERROR] Failed to execute goal org.codehaus.cargo:cargo-maven2-plugin:1.4.4:rede
ploy (default-cli) on project iqasweb: Execution default-cli of goal org.codehau
s.cargo:cargo-maven2-plugin:1.4.4:redeploy failed: Failed to redeploy [E:\Reposi
tory\iqasproject\iqasweb\target\iqasweb-remote.war]: The username you provided i
s not allowed to use the text-based Tomcat Manager (error 403): Server returned
HTTP response code: 403 for URL: http://172.19.201.155:8080/manager/text/list ->
留言
有什么不懂的一起探讨一下吧,欢迎留下宝贵意见,喜欢就点个赞吧(哈哈),多谢鼓励。