JavaEE开发-第五节 Maven

Maven简介

  1. 传统开发中的常见痛点
    1. 第三方jar包的下载、升级、依赖、冲突:第三方jar包和它的依赖,旧版本升级,jar包之间的冲突
    2. 不同IDE之间的项目共享:用之前方法创建的项目是无法导入其他IDE的,比如Eclipse
    3. 单元测试:新建一个test文件夹,每个单元测试文件都需要手动点击,无法将所有的单元测试文件一次性运行
    4. 打包发布:打包比较麻烦
  2. Apache Maven,主要用于自动化构建和管理Java项目
    1. 基于项目对象模型(POM,Project Object Model)的概念
    2. 下载地址:https://maven.apache.org/download.cgi
      1. 下载Binary zip archive下的apache-maven-3.6.3-bin.zip

安装与配置

  1. 直接解压即可,解压到与Tomacat安装目录同级的目录:D:\Dev\Java\目录下
  2. 配置环境变量:
    1. windows下:
      1. 必须配置好JAVA_HOME,Maven对JDK版本的要求:http://maven.apache.org/docs/history.html
      2. 配置MAVEN_HOME路径
        1. 跟配置JAVA_HOME一样的方法,配置一个MAVEN_HOME:D:\Dev\Java\apache-maven-3.6.3
      3. 添加MAVEN_HOME\bin到PATH中
        1. 在PATH中新增maven的bin目录:%MAVEN_HOME%\bin,跟配置JDK的bin目录一样
    2. mac下:
      1. 终端输入命令:vim ~/.bash_profile
      2. 输入i编辑

         export MAVEN_HOME=/Users/mac/Desktop/H555/MJ-java/Java/apache-maven-3.6.3 
         export PATH=$PATH:$MAVEN_HOME/bin
        
      3. 点击esc,:wq回车
      4. 执行以下命令使配置生效:source ~/.bash_profile
      5. 查看版本:mvn -v
  3. 配置本地镜像同步文件路径
    1. 打开maven安装目录下的setting.xml文件夹/Users/mac/Desktop/H555/MJ-java/Java/apache-maven-3.6.3/conf/settings.xml
    2. 找到<settings....>标签,在下面添加一行

       //windows:
       <localRepository>D:/Dev/Java/.m2/repository</localRepository>
       //mac:
       <localRepository>/Users/mac/Desktop/H555/MJ-java/Java/.m2/repository</localRepository>
      
    3. 这样,maven从远程仓库下载的一些文件就会同步到本地指定的目录中,下次其他项目使用就直接从本地仓库获取。如果不设置会默认放到C盘(mac系统根目录 cd ~)
    4. 注意 这跟iOS的cocoapods一样,就是下载第三方依赖库到本地
  4. 配置远程镜像服务器源
    1. maven下载第三方依赖库的服务器地址在国外,因此可以修改镜像路径
    2. 在settings.xml文件夹找到<mirrors>标签,内部添加如下标签,配置的是阿里云的镜像

       <mirror>
           <id>aliyun</id>
           <mirrorOf>central</mirrorOf>
           <name>aliyun</name>
           <url>https://maven.aliyun.com/repository/public</url>
       </mirror>
      

Maven项目的常见目录

  1. Maven使用“约定优于配置”的思想
    1. 创建Maven项目时,Maven将创建默认项目结构,开发人员只需要相应地放置文件 图1
  2. 使用命令行新建一个maven项目
    1. 新建一个TestMaven文件夹cd到该目录下
    2. 输入mvn archetype:generate命令
    3. 如果遇到下面

       Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 7: 
      
      1. 表示上面有几种项目,我们选择第7种,直接点击回车继续
    4. 此时会遇到

       //组织id,公司域名反写,比如com.zh.maven
       Define value for property 'groupId': com.zh
       //项目名称
       Define value for property 'artifactId': 01_helloworld
       //版本号:这里默认为1.0-SNAPSHOT,直接点击回车
       Define value for property 'version' 1.0-SNAPSHOT: : 
       //包名,可以只写使用com.zh.maven
       Define value for property 'package' : com.zh.maven
      
    5. 一直回车即可
    6. 此时就看到TestMaven文件夹下多了一个01_helloword项目,目录结构如上图所示,没有resources

pom.xml

  1. pom.xml是Maven项目的核心配置文件,根元素是project。project的常用子元素如下表所示

     元素                  描述
     modelVersion        pom的版本,目前都使用4.0.0,是必要元素
     groupId             组织名称,一般用域名的倒写,比如com.mj.hello
     artifactId          项目名称
     version             项目的版本号,比如1.0.0、3.0、1.0-SNAPSHOT、1.0-RELEASE
     packaging           打包方式,比如pom、jar (默认值)、maven-plugin、ejb、war、ear、rar
     properties          属性信息,比如文本编码等
     dependencies        依赖信息
     build               构建信息,比如插件配置等
    
  2. groupId、artifactId、version,组成一个Maven坐标(Coordinate),能够确定唯一的一个项目

Maven常用指令

mvn archetype:generate  创建Maven项目
mvn compile   编译项目
mvn test    执行单元测试
mvn packge 获取编译后的代码,并将其打包为可分发的格式,例如jar
mvn clean   清除target
mvn clean packge   先执行clean,再执行packge
mvn dependency:tree 获取当前项目所有的第三方jar包依赖列表信息

修改Maven项目的JDK版本(mac系统不需要)

  1. 创建一个maven项目后,cd到有pom.xml同级的目录下
  2. 然后通过命令行编译此项目:mvn compile
  3. 会发现报错:不再支持原选项5,请用7或更高版本。。。
  4. 也就是说maven项目默认是JDK5,因此不支持,尽管系统安装的是JDK8
  5. 那么如何让maven设置为支持JDK8呢?

方法1:在pom.xml中添加属性(每个Maven项目都要添加)

  1. 找到属性(<properties>)标签,添加如下:

     //使用jdk8
     <maven.compiler.source>8</maven.compiler.source> 
     <maven.compiler.target>8</maven.compiler.target>
     <maven.compiler.compilerVersion>8</maven.compiler.compilerVersion>
    

方法2:在pom.xml中添加插件(每个Maven项目都要添加)

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-compiler-plugin</artifactId> 
    <version>3.8.1</version> 
    <configuration> 
        <source>8</source> 
        <target>8</target> 
    </configuration> 
</plugin>

方法3:在maven配置文件中添加

  1. %MAVEN_HOME%/conf/settings.xml<profiles>标签中添加1个 <profile>,这是一种一劳永逸的办法,不需要去修改每一个Maven项目的pom.xml
<profile> 
    <id>jdk8</id> 
    <activation> 
        <activeByDefault>true</activeByDefault> 
        <jdk>8</jdk> 
    </activation> 
    <properties> 
        <maven.compiler.source>8</maven.compiler.source> 
        <maven.compiler.target>8</maven.compiler.target>
        <maven.compiler.compilerVersion>8</maven.compiler.compilerVersion>
    </properties> 
</profile>

IDEA创建Maven项目

IDEA配置本地安装的maven

  1. 默认情况下,IDEA自己集成的有maven,但是为了方便一般配置成自己本地安装的maven
  2. 打开IDEA,则点击idea->preferences … ->build,execution,deployment->build tools->Maven点击
  3. 修改Maven home directory 的默认maven为我们自己安装的maven,选择右边的路径,最终选择apache-maven-3.6.3(D:\Dev\Java\apache-maven-3.6.3
  4. User settings file勾选右边的Override(覆盖),路径选择maven安装目录下的setting.xml文件(D:\Dev\Java\apache-maven-3.6.3/conf/settings.xml)
  5. Local respository勾选右边的Override(覆盖),路径选择/Users/mac/Desktop/H555/MJ-java/Java/.m2/repository,本地的仓库路径。

纯java项目创建

  1. file->new -> module-> maven->勾选Create from archetype(原型模板) ->选择org.apache.maven.archetypes:maven-archtype-quickstart(快速创建)->next
  2. 点击artifact coordinates

     groupid: com.zh.maven (组织名称)
     artifactld: 07_helloworld (跟项目名称保持一致)
     version: 1.0-SNAPSHOT (版本号)
    
  3. 点击next,点击完成即可

JavaEE项目创建

1.命令行创建

  1. 新建一个文件夹TestWebMaven
  2. cd到该目录下,执行mvn archetype:generate
  3. 输入10,点击回车

     10: internal -> org.apache.maven.archetypes:maven-archetype-webapp (An archetype which contains a sample Maven Webapp project.)
    
  4. 设置groupid、artifactId、version、package,最后输入y,回车
  5. 项目目录如下:

     TestWebMaven
         HelloWeb
             pom.xml
         src
             main
                 resources
                 webapp
                     index.jsp
                     WEB-INF
                         web.xml
    
    1. 没有生生成java文件夹

2.IDEA创建

  1. file->new -> module-> maven->勾选Create from archetype ->选择org.apache.maven.archetypes:maven-archtype-webapp->点击next
  2. 其余跟创建纯java项目一样

3.最终方式

  1. 上面的纯java项目、web项目的创建方式,最终pom.xml会自动生成很多用不上的代码,那么下面就可以从0开始创建
  2. 步骤如下:
    1. file ->new->module…->Maven->(不勾选Create from archetype) next->项目命名(10_TestWeb)、路径(~/Desktop/JavaStudy/Codes/JavaProject/10_TestWeb)、groupid(com.zh)、artifactid(10_TestWeb)、version(1.0.0)->点击finish
    2. 设置项目路径以及基本信息,点击完成
    3. 此时打开项目的pom.xml文件,内容非常少,

       <?xml version="1.0" encoding="UTF-8"?>
       <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/xsd/maven-4.0.0.xsd">
           <modelVersion>4.0.0</modelVersion>
              
           <groupId>com.zh</groupId>
           <artifactId>10_TestWeb</artifactId>
           <version>1.0.0</version>
       </project>
      
    4. 当前项目仅仅是一个纯java项目,不是web项目
      1. 查看web项目:点击右上角倒数第三个(project structure…)->facets就能看到10_TestWeb不在里面,说明当前项目不是web项目
      2. 右击java文件夹->new->列表中也没有 Create New Servlet这个选项(也说明不是web项目)
  3. 创建后的项目目录如下:

     10_TestWeb
             src
                 main
                     java
                     resources
                     webapp(没有)
                 test
             10_TestWeb.iml
             pom.xml
    
创建web项目部分
  1. 在pom.xml中添加如下标签:

     <!--设置打包方式-->
     <packaging>war</packaging>
    
  2. 然后点击右上角的maven本地仓库刷新
  3. 再次点击查看web项目,会发现10_TestWeb在里面
  4. 在project structure->Facets 下点击10_TestWeb,点击Deployment Descriptors下的加号“+”->选择web.xml,在默认路径.../10_TestWeb/WEB-INF/web.xml之间添加src/main/webapp/,点击OK,然后点击下面的apply/ok即可
  5. 此时项目目录main文件夹中就多了一个webapp文件夹

     webapp
         WEB-INF
             web.xml
    
  6. 右击java文件夹->new->Create New Servlet(此时有这个选项了)

IDEA导入Maven项目

  1. 打开idea,点击file->new->module from existing Sources …
  2. 找到创建的maven项目(TestMaven),打开文件夹,找打pom.xml,然后点击打开

IDEA使用maven命令

  1. 打开一个maven项目,此时idea右边工具栏会显示一个Maven标识,点击展开,找到01_Helloword项目
  2. 展开项目,显示lifecyle,点击展开,会看到很多命令,这些命令双击即可执行
  3. 比如双击:compile,编译项目
  4. 也可以点击Maven工具展开的上面的m标识,然后输入相应的命令来执行

Maven使用第三方库、插件

项目添加依赖库(远程jar包)

  1. 通常一个项目要用到n个第三方依赖库,那么如何通过maven导入呢?
  2. 比如项目中要做单元测试,需要用到Junit,步骤如下
    1. 在pom.xml中添加一个<dependencies></dependencies>标签
    2. 在下面2个网址中查询第三方库,然后添加
      1. 网址:https://search.maven.org、https://mvnrepository.com
      2. 比如使用第一个搜索,输入Junit找到对应的目标,然后点击打开,右边的Apache Maven下面直接已经写好了引用方式,直接复制即可,然后放到dependencies标签内部

         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <version>4.13.2</version>
         </dependency>
        
    3. 下载第三方库到本地
      1. 右击项目,选择Maven->点击reload project 或者直接点击右上角的m刷新图标,或者点击右边Maven工具栏展开,点击左上角刷新
    4. 代码举例:

       <!--当前项目依赖于哪些jar包-->
       <dependencies>
           <!--  一个dependency就依赖于一个jar包-->
           <dependency>
               <groupId>junit</groupId>
               <artifactId>junit</artifactId>
               <version>4.13.2</version>
           </dependency>
       </dependencies>
      

本地jar包导入Maven项目

有三种方式,这里只讲到一种。

  1. 从上面可知,pom.xml配置的第三方jar、插件都是从远程maven管理的第三方仓库下载的,那么如果远程的maven仓库没有我们想要的第三方库呢?
  2. 如果按照原来的方式,在项目中新建一个lib文件夹,然后将jar包复制进去,然后配置类加载(Add as Library..),然后通过maven的packege打包时会报错
  3. 解决思路:将这个jar包导入到maven的本地仓库中去即.m2/repository文件夹中去,可以直接使用如下指令

     mvn install:install-file -Dfile=jar的路径 -DgroupId=组织 -DartifactId= 库名 -Dversion=版本 -Dpackaging=jar
     //比如:将/Users/mac/Desktop/dom4j-2.1.3.jar包拷贝到mvn的本地仓库
     mvn install:install-file -Dfile=/Users/mac/Desktop/dom4j-2.1.3.jar -DgroupId=com.zh -DartifactId= dom4j -Dversion=2.1.3 -Dpackaging=jar
    
  4. 在pom.xml中添加依赖

     <dependency>
         <groupId>com.zh</groupId>
         <artifactId>dom4j</artifactId>
         <version>2.1.3</version>
     </dependency>
    
  5. 此时再通过packge打包就行了

maven插件打包Runnable Jar

  1. 如果当前项目有个Main类,里面有个main入口函数,如何打包成一个jar包,然后提供给用户直接双击就可以执行呢?或者通过命令行:java -jar xxx.jar执行?
  2. 首先在pom.xml中添加如下标签

     <build>
         <!-- 安装插件-->
         <plugins>
         <!-- 存放各种插件-->
          
         </plugins>
     </build>
    
  3. 有四种方法,通过添加插件打包

方法一:maven-jar-plugin插件

<!--
该插件可以将项目打包成可运行的jar(包含main函数,双击直接可以运行)包,但是不会打包项目的依赖库
-->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.0.2</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <!-- jar包依赖的第三方jar包寻找的路径-->
                <classpathPrefix>lib</classpathPrefix>
                <!-- 指定哪个类是main函数入口-->
                <mainClass>com.zh.Main</mainClass>
            </manifest>
        </archive>
        <!-- 最终打包的jar名称-->
        <finalName>hellojava</finalName>
    </configuration>
</plugin>
<!--
该插件是专门打包项目的依赖jar包
-->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>3.1.2</version>
    <!-- 插件执行任务 -->
    <executions>
        <!-- 每个执行 -->
        <execution>
            <!-- 再生命周期的哪个阶段执行-->
            <!-- <phase>package</phase> -->
            <!--一个插件中有n个goal(目标)需要指定执行哪一个目标 -->
            <goals>
                <!--指向拷贝依赖操作 -->
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <!--
                将依赖的jar包拷贝到target文件夹下的lib文件夹中
                ${project.build.directory}:就是指的是target文件夹路径
                最终提供给别人的是hellojava.jar和lib2个文件
                 -->
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>
  1. 写入上面之后,点击packge打包,就会在Target项目目录下生成一个hellojava.jar包和一个lib文件夹
  2. 给用户提供hellojava.jar和lib2个文件即可

方法二:通过maven-assembly-plugin插件

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.3.0</version>
    <configuration>
        <archive>
            <manifest>
                <mainClass>com.zh.Main</mainClass>
            </manifest>
        </archive>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <finalName>hellojava</finalName>
        <appendAssemblyId>false</appendAssemblyId>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>
  1. 该插件,双击右侧工具栏Maven的packge之后,就会在Target项目目录下只生成一个hellojava.jar包
  2. 给用户提供hellojava.jar文件即可,本质是将第三方依赖库直接打到了hellojava.jar文件中

方法三:通过maven-shade-plugin插件

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.3</version>
    <executions>
        <execution>
            <!-- <phase>package</phase> -->
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <shadedArtifactAttached>true</shadedArtifactAttached>
                <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestReso urceTransformer">
                        <mainClass>com.zh.Main</mainClass>
                    </transformer>
                </transformers>
                <finalName>hellojava</finalName>
            </configuration>
        </execution>
    </executions>
</plugin>

方法四:通过spring-boot-maven-plugin插件

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>2.3.0.RELEASE</version>
    <executions>
        <execution>
            <!-- <phase>package</phase> -->
            <goals>
                <goal>repackage</goal>
            </goals>
            <configuration>
                <mainClass>com.zh.Main</mainClass>
                <finalName>hellojava</finalName>
            </configuration>
        </execution>
    </executions>
</plugin>

构建生命周期(Build Lifecycle)

  1. 构建生命周期,描述了构建的过程。Maven内置了3个构建生命周期
    1. clean (清理)
    2. default (默认,重点关注)
    3. site (站点)
  2. 构建生命周期由phase(阶段)组成
    1. phase可以跟plugin goal(插件目标)绑定
    2. plugin goal代表1个特定的任务
    3. 一旦某个phase被执行,就会执行其绑定的所有goal
    4. 比如双击packge时就会执行pom.xml中配置的打包插件spring-boot-maven-plugin
  3. 通过命令mvn 插件名称:help可以查看插件包含的所有goal
    1. 比如mvn archetype:help:查看archetype插件下有哪些任务(goal)

    图1

default生命周期

  1. default生命周期由下表中的几个phase组成

     phase               描述
        
     validate            确认项目正确并且所有必要的信息均可用
     compile             编译项目的源代码(src/main)
     test                使用合适的单元测试框架测试编译后的源代码(src/test)
     package             获取编译后的代码,并将其打包为可分发的格式,例如jar
     verify              对集成测试的结果进行任何检查,以确保符合质量标准
     install             将软件包安装到本地存储库中,以作为本地其他项目中的依赖项
     deploy              在构建环境中完成后,将最终软件包复制到远程存储库中,以便与其他开发人员和项目共享
    
  2. 使用命令mvn package就会默认按顺序执行validate、compile、test、package阶段
  3. 注意:install是将packge打包好的jar包安装到本地仓库,比如之前打包的hellojava.jar包中

举例:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>3.1.2</version>
    <!-- 插件执行任务 -->
    <executions>
        <!-- 每个执行 -->
        <execution>
            <!-- 在生命周期的哪个阶段执行,这个是在package阶段(phase)执行-->
            <phase>package</phase> 
            <!--一个插件中有n个goal(目标)需要指定执行哪一个目标 -->
            <goals>
                <!--指向拷贝依赖操作 -->
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <!--
                将依赖的jar包拷贝到target文件夹下的lib文件夹中
                ${project.build.directory}:就是指的是target文件夹路径
                最终提供给别人的是hellojava.jar和lib2个文件
                 -->
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

dependency中scope的取值

  1. compile: 默认值。编译依赖关系在所有类路径中均可用。此外,这些依赖项会传递到相关项目
  2. provide: 仅在编译和测试类路径上可用,并且不可传递。希望JDK或容器在运行时提供它
  3. runtime: 依赖关系不是编译所必需的,而是运行所必需的。它在运行时和测试类路径中,但不在编译类路径中
  4. test: 依赖关系对于正常使用该应用程序不是必需的,并且仅在测试编译和执行阶段可用。它不是可传递的
  5. system::必须显式提供jar的位置(可以通过systempath标签指定),不会去Maven仓库中查找

举例

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.3</version>
    <!-- scope的取值-->
    <scope>test</scope>
</dependency>

Maven项目的本地部署

新建10_TestWeb 项目

  1. 新建一个JaEE项目10_TestWeb
  2. 创建LoginServlet类
    1. 此时会发现LoginServlet类中报错,找不到HttpServlet这个父类
    2. 还记得非Maven项目时不报错,是因为HttpServlet这个类在Tomcat包中,将Tomcat这个jar包导入到项目中,才不会报错,那么maven项目如何使用呢?就需要下pom.xml中添加依赖
  3. 打开pom.xml添加servlet依赖

     <!--添加依赖-->
     <dependencies>
         <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
             <version>4.0.1</version>
             <!--为了避免 jar包冲突, 修改 servlet的 scope为 provided
             意思就是只在仅在编译和测试类路径上可用
             因为下面我们引用了Tomcat7,Tomcat7也提供了servlet,但是仅仅在运行时提供,因此这个servletjar包只能使用在
             运行时之前,避免与Tomcat7运行是提供的servlet包冲突
             -->
             <scope>provided</scope>
         </dependency>
     </dependencies>
    

Tomcat插件部署Maven项目(使用Maven内置Tomcat)

  1. Tomcat插件是一个Maven内置的插件,可以将web项目部署到maven自带的Tomcat上去
  2. 这个看上去有点多余,本来IDEA就可以直接部署项目到Tomcat
    1. 非maven项目通过IDEA添加Tomcat,对项目进行部署,这个过程之前已经讲过
  3. 那么maven项目如何部署到Tomact上呢?
  4. 集成tomcat7-maven-plugin插件

     <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.tomcat.maven</groupId>
                 <artifactId>tomcat7-maven-plugin</artifactId>
                 <version>2.2</version>
                 <configuration>
                     <!-- 设置访问路径-->
                     <path>/context_path</path>
                     <!-- 访问端口-->
                     <port>8080</port>
                     <!-- 编码配置-->
                     <uriEncoding>UTF-8</uriEncoding>
                 </configuration>
             </plugin>
         </plugins>
     </build>
    
  5. 在webapp下新增一个index.jsp文件,里面写上测试数据
  6. 运行
    1. 上面配置完后点击右上角m,从远程加载本地依赖库
    2. 点击右侧工具栏Maven然后展开,选择10_TestWeb->plugins->tomcat7
    3. 运行:双击tomcat7:run,即将web项目部署到tomcat上
    4. 此时浏览器访问:http://localhost:8080/context_path/login
  7. 疑问:
    1. 添加servlet依赖,为何scope标签值为provided?
      1. 之前非Maven项目,项目中使用servlet,需要导入本地Tomcat的servlet-api.jar/jsp-api.jar包,也就是说Tomcat内部包含了servletjar包
      2. 那么上面通过插件tomcat7-maven-plugin引入了tomcat7,那么通过dependency引入的servlet依赖就会冲突
      3. 为了避免冲突将dependency引入的servlet依赖进行provided设置,目的就是引入的这个依赖仅仅在编译、测试的时候使用,真正运行的时候使用插件引入的tomcat7中的jar包
    2. 上面的使用tomcat7-maven-plugin插件的功能是什么?
      1. 从远程下载tomcat7到本地仓库(而且最高版本就是7,没有9)
      2. 当双击插件的tomcat7:run运行时,将当前项目部署到远程仓库下载的本地tomcat7上

Tomcat插件部署Maven项目(使用本地安装的Tomcat9)

  1. %TOMCAT_HOME%/conf/tomcat-users.xml中的<tomcat-users>标签中添加用户

     <role rolename="manager-gui"/> 
     <role rolename="manager-script"/> 
     <user username="root" password="root" roles="managergui,manager-script" />
    
    1. 部署到tomcat上需要用户名密码,即tomcat提供一个用户名、密码给别人
  2. %MAVEN_HOME%/conf/settings.xml中添加

     <server> 
         <id>tomcat9</id> 
         <username>root</username> 
         <password>root</password> 
     </server>
    
    1. 告诉maven,将来连接哪个tomcat
  3. pom.xml中集成 tomcat7-maven-plugin插件
    1. 告诉这个插件,如果执行项目部署连接哪一个Tomcat服务器
     <plugin>
         <groupId>org.apache.tomcat.maven</groupId>
         <artifactId>tomcat7-maven-plugin</artifactId>
         <version>2.2</version>
         <!--插件配置-->
         <configuration>
             <!--项目部署后的访问路径-->
             <path>/context_path</path>
             <!--设置访问端口-->
             <port>8080</port>
             <!--热部署
             修改内容后,重新执行tomcat7:deploy,就可以将更改的代码部署上去
             -->
             <update>true</update>
             <!--访问tomcat的路径url-->
             <!-- <url>http://localhost:8080/manager/text</url>-->
             <!--<uriEncoding>UTF-8</uriEncoding>-->
             <!-- 这个tomcat9就是在上面第二步maven的settings.xml中配置过的,因此下面2行可以用这一行替换 -->
             <server>tomcat9</server>
             <!--
             <username>root</username>
             <password>root</password>
             -->
         </configuration>
     </plugin>
    
  4. 部署项目
    1. 运行tomcat9,通过命令行,或者手动先启动tomcat9
    2. 部署:双击tomcat7:deploy或者tomcat7:redeploy,本质会去settings.xml找到id为tomcat9,拿到用户名、密码,去登录本地运行的Tomcat9,即将web项目部署到tomcat上

IDEA部署Maven项目(最终版)

  1. 上面讲的用maven插件+本地Tomcat/远程Tomcat部署项目过程麻烦,有没有一种办法用IDEA上面配置的Tomcat来部署呢?直接不使用什么Tomcat插件部署maven项目
  2. 结论:可以直接使用IDEA配置的Tomcat来部署Maven项目,部署过程跟非Maven项目一样(略)
  3. Maven项目的打包
    1. 非Maven的web项目打包的结果
      1. 打包输出目录:out/artifacts/project
    2. Maven的web项目
      1. Maven打包(双击packge),打包输出目录:basedir/target/project
      2. IDEA打包(点击工具栏build->build Artifacts…->选择10_TestWeb:war->build),打包输出目录:basedir/target/project,同Maven打包
    3. IDEA非常智能
      1. 自动判断当前项目是maven项目,将输出包的位置输出到target中
      2. 尽管项目中的第三方依赖jar不在WEB-INF下面的lib文件夹中,仅仅在pom.xml中配置,在打包的时候仍然可以将相应的第三方jar包打包到target中
    4. 设置打包的包名:

       <build>
           <!--打包后的文件夹名称-->
           <finalName>10_TestWeb</finalName>
       </build>
      

Maven常见问题

  1. 解决文件编码的警告:
    1. 双击packge时,会报错:Using platform encoding(UTF-8 actually)...
    2. 解决办法:在pom.xml的<properties>标签中添加

       //通过maven打包,编译的时候用UTF8进行编码打包。如果不设置,默认编码不是UTF-8,出现汉字响应给前端的时候前端的汉字出现乱码(因为前端用UTF-8解析)。
       <project.build.sourceEncoding>UTF8</project.build.sourceEncoding>
      
  2. 解决IDEA控制台输出乱码:
    1. Settings -> Build, Execution, Deployment -> Build Tools -> Maven -> Runner
    2. 在VM Options中添加-Dfile.encoding=GBK
  3. 如何修改创建后的Servlet默认代码?
    1. 打开IDEA的perference->搜索框输入code template->File and Code Templates->点击Other->Web->Java code templates->Servlet Annotated Class.java
    2. 在默认的doPost方法中添加

       #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
       #parse("File Header.java")
       @WebServlet("/${Entity_Name}")
       public class ${Class_Name} extends HttpServlet {
           protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
               doGet(request,response);
           }
              
           protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              
           }
       }
      
    3. 点击默认即可

Maven打包资源文件

  1. 默认情况下,Maven并不会将源代码文件(main/java)夹中的配置文件(propertis、xml等)打包(默认只打包resources文件夹下的资源文件)
  2. 若想打包源代码文件夹中的配置文件,需要进行额外的配置

     <build>
         <!-- 说明资源的位置(哪些东西算是资源) -->
         <resources>
             <!-- 第一个位置 -->
             <resource>
                 <directory>src/main/resources</directory>
             </resource>
             <!-- 第二个位置 -->
             <resource>
                 <directory>src/main/java</directory>
                 <includes>
                     <include>**/*.properties</include>
                     <include>**/*.xml</include>
                 </includes>
             </resource>
         </resources>
     </build>
    
Table of Contents