maven---13使用maven构建Web应用

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文件目录结构如下:

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/
web项目的maven目录结构
eclipse中maven结构的web项目
项目打包配置
  • 在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模式

官网standalone模式

 <!-- 配置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 ->

留言

有什么不懂的一起探讨一下吧,欢迎留下宝贵意见,喜欢就点个赞吧(哈哈),多谢鼓励。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,494评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,678评论 6 342
  • 转自:http://www.cnblogs.com/crazy-fox/archive/2012/02/09/23...
    晴天哥_王志阅读 2,234评论 2 27
  • 使用指导 如何添加外部依赖jar包 在Maven工程中添加依赖jar包,很简单,只要在POM文件中引入对应的<de...
    静默虚空阅读 2,769评论 0 13
  • 我们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编...
    付鹏丶阅读 1,616评论 0 15