Tomcat部署项目的方式
增加Artifacts的时候,如果选择:
【Web Application: Exploded(暴露)】:编译后的产物是解压的
【Web Application: Archive(压缩)】:编译后的产物是压缩的war包
- 将Web项目整个文件夹,放在
%TOMCAT_HOME%/webapps目录中,文件夹名作为ContextPath
例如crm项目,build后 项目路径 out文件夹 --> artifacts文件夹 下的 crm_war_exploded 文件夹 拷贝至 %TOMCAT_HOME%/webapps。 启动Tomcat后,http://localhost:8080/crm_war_exploded/就可以访问。context就是文件夹名crm_war_exploded
- 将web项目打包成war, 放在
%TOMCAT_HOME%/webapps目录中,war文件名作为ContextPath
例如crm项目,build后 项目路径 out文件夹 --> artifacts文件夹 --> crm_war_exploded的子文件夹压缩成 crm1.zip 后缀改成 crm1.war, 移动至 %TOMCAT_HOME%/webapps,会自动解压成crm1文件夹。 启动Tomcat后,http://localhost:8080/crm1/就可以访问。context就是文件夹名crm1
war包本质上就是jar,jar就是基于zip,zip基础上加上签名等操作
-
在
%TOMCAT_HOME%/conf/server.xml的HOST标签中添加以下内容(ContextPath是Path属性值):<Context docBase="项目路径" path="xxxx" /> -
在
%TOMCAT_HOME%/conf/Catalina/localhost中新建一个xml文件,xml文件名作为ContextPath: (不需要path属性,path即为xml文件名) -
IDEA 为了不侵入,%TOMCAT_HOME%.在
Dcatalina.base(每次启动都变化,可从控制台获取)下增加 crm.xml
<Context path="/crm" docBase="/Users/~/Desktop/learn_java/code/MyPro/out/artifacts/crm_war_exploded" />
maven初始化配置
- windows: 先配置
JAVA_HOME,然后配置MAVEN_HOME,添加%MAVEN_HOME%/bin到PATH中.mac:在~/.zshrc中配置环境变量:
export M2_HOME=/Users/robbie/apache-maven-3.3.3
export PATH=$PATH:$M2_HOME/bin
- 修改仓库位置:在
%MAVEN_HOME%/conf/settings.xml的<settings>标签中添加1个<localRepository>
<localRepository>F:\Dev\Java\.m2\repository</localRepository>
3.提高仓库的下载速度:在%MAVEN_HOME%/conf/settings.xml的<mirrors>标签中添加1个<mirror>
<mirror>
<id>aliyun</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
命令行新建Maven项目
1、 命令行输入:mvn archetype:generate, 会让我们选择项目类型。默认值是7,maven-archetype-quickstart,是个普通的java项目,创建web项目,输入10.输入groupId、artifactId、version、package.
2、命令行输入:mvn archetype:generate -DgroupId=com.xx.maven -DartifactId=helloworld -Dversion=1.0-RELEASE -DarchetypeGoupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart
- mav compile、mav clean、mvn test 、 mvc package
mvn compile会报错 需要修改JDK版本。mvn test默认使用Junit3.8。
<profile>
<id>jdk14</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>14</jdk>
</activation>
<properties>
<maven.compiler.source>14</maven.compiler.source>
<maven.compiler.target>14</maven.compiler.target>
<maven.compiler.compilerVersion>14</maven.compiler.compilerVersion>
</properties>
</profile>
IDEA创建maven项目
- IDEA自带一个maven
- 创建Maven项目
- 导入Maven项目
选择pom.xml进行导入
- pom.xml
- 下载依赖
以下操作,会把工程下所有module的依赖全部下载。
以下只会下载当前module的依赖,或者点击module文件夹右键,【Maven】-【Reload project】
构建生命周期
在终端输入:mvn compile 这个是 阶段phase. mvn compiler:compile 是执行某个插件的某个goal。
default 生命周期
生成Runnable Jar
jar包分为普通jar包:提供功能供别人使用,Runnable Jar:可以直接运行。
运行jar包命令:$ java -jar 路径
普通项目打包(非maven项目)
建一个普通java项目,主类Main方法里打印一句话。
然后 【build】-【build Artifacts】
java -jar 运行,发现成功打印。
maven项目打包
- 方法一 maven-jar-plugin
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib</classpathPrefix>
<mainClass>主类</mainClass>
</manifest>
</archive>
<finalName>jar的文件名</finalName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<!-- <phase>package</phase> -->
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
executions: 在executions中说明这个插件该如何执行。
这种方式,依赖的lib并没有放入最终的jar里。不推荐这种方式。
- 方法二 maven-assembly-plugin
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>主类</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>jar文件名</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
多出的一个firstmvn-1.0.0.jar是按照默认方式打的,不用管。
- 方法三 maven-shade-plugin
<build>
<plugins>
<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.ManifestResourceTransformer">
<mainClass>主类</mainClass>
</transformer>
</transformers>
<finalName>jar文件名</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
- 方法四 spring-boot-maven-plugin
<build>
<plugins>
<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.scc.Main</mainClass>
<finalName>firstmvn4</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
安装本地jar到Maven的LocalRepository
mvn install:install-file -Dfile=jar的路径 -DgroupId=组织 -DartifactId=库名 -Dversion=版本 -Dpackaging=jar
然后再pom.xml里引用依赖
dependency中的scope取值
类路径包括编译路径、测试路径、运行路径等。
compile是默认的,在编译路径、测试路径、运行路径都可用。
test仅在测试编译和执行阶段可用。
system使用场景:上面说本地的jar包可以安装到maven本地的中央仓库里使用,也可以放在项目里,指定system.不推荐这种做法,推荐安装到本地仓库 具体步骤:
1.项目里lib文件,导入jar包。然后 右键【Add As Library】
2.添加依赖,依赖里指定system和systemPath.
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<scope>system</scope>
<systemPath>${basedir}/lib/xxxx.jar</systemPath>
</dependency>
- 打包的插件添加
<includeSystemScope>true</includeSystemScope>
创建maven web项目
首先参考上面创建普通的maven项目,不勾选Create from archetype
然后配置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.scc</groupId>
<artifactId>webpro</artifactId>
<version>1.0.0</version>
<!-- 打包方式-->
<packaging>war</packaging>
<!-- 文件编码-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- 依赖-->
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- 构建信息-->
<build>
<filename>webpro</filename>
</build>
</project>
加上<packaging>war</packaging>,只有加上这个IDEA才会认为这是个web项目。然后对项目进行Reimport。【Project Structure】--【Facets】--【web】下面才会出现这个项目。
为了避免jar包冲突,修改servlet的scope为provided。
这时候main文件夹下没有webapp文件夹
添加web.xml
将web.xml放在/src/main/webapp/WEB-INF下面
把Maven项目部署到Tomcat上去
使用Maven内置的Tomcat
Maven自带tomcat7插件,利用这个插件部署项目。会把项目部署到tomcat7上,而不是我们自己下载的tomcat9.(tomcat7是从maven中央仓库下载的。)
<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>
<uriEncoding>UTF-8</uriEncoding>:浏览器会自动给url进行uriencoding操作,在tomcat7时,必须配置uriencoding的解码方式,tomcat8之后不需要。不配置会乱码,即使request.setCharacterEncoding("UTF-8");也不行,后面【编码问题】再讨论这个问题。
运行命令$ tomcat7:run报错。是因为编译阶段需要javax.servlet,所以pom.xml里配置了javax.servlet的依赖,但是tomcat7运行时又自带了javax.servlet,导致了jar包冲突。解决办法:修改
修改servlet的scope为provided。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency
运行命令$ tomcat7:run,可以成功部署项目,但无法热部署。我们自己的Tomcat是Tomcat9。
解决方案是:利用 $ tomcat7:deploy把我们的项目部署到IEDA关联的Tomcat9上。这样就能方便的使用IDEA的热更新了。
使用独立安装的Tomcat9
首先把tomcat9运行起来,但是tomcat9是不允许任何项目随便部署上去,Tomcat9提供一个用户名和密码,开发权限,然后通过url、用户名和密码部署上去。
在 %TOMCAT_HOME%/conf/tomcat-users.xml中添加用户权限.如下。用户名和密码可以自己定,其他不要改。
<tomcat-users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<user username="root" password="root" roles="manager-gui,manager-script" />
</tomcat-users>
在%MAVEN_HOME%/conf/settings.xml的中添加
<server>
<id>tomcat9</id>
<username>root</username>
<password>root</password>
</server>
集成tomcat7-maven-plugin
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/context_path</path>
<update>true</update>
<port>8080</port>
<!--
<url>http://localhost:8080/manager/text</url>
-->
<uriEncoding>UTF-8</uriEncoding>
<server>tomcat9</server>
<!--
<username>root</username>
<password>root</password>
-->
</configuration>
</plugin>
<path>/context_path</path>:配置context_path.
<update>true</update>:是否可以热部署。
<url>http://localhost:8080/manager/text</url>:访问Tomcat9的url.端口和ip根据实际情况配置。本地的话可以省略。
<uriEncoding>UTF-8</uriEncoding>:后面再加以说明。
<server>tomcat9</server>:通过%MAVEN_HOME%/conf/settings.xml配置的server的id,查找server.(也可以通过 username和password的方式。)然后会自动通过url上传到自己本地的tomcat9上去。
步骤:启动tomcat9.(sh startup.sh) --> mvn tomcat7:deploy/redeploy. 这样就部署到tomcat9上去了。
可以看到,mvn tomcat7:deploy.命令会首先执行编译打包操作,然后会上传到tomcat9上去。
但是这样还是不方便,我们要结合Maven和IDEA。 使用IDEA内置的build.
删除tomcat7插件。
<build>
<finalName>webpro</finalName>
</build>
配置IDEA的tomcat
这样就依然可以使用IDEA部署,热更新了。
Tomcat7编码问题
通过Tomcat7部署项目,会出现编码问题
pom.xml
<build>
<finalName>webpro</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/myweb</path>
<port>8080</port>
</configuration>
</plugin>
</plugins>
</build>
LoginServlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 解决post请求参数乱码
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println(username +" ======= "+ password);
response.setContentType("text/plain,charset=UTF-8");
if ("123".equals(username) && "123".equals(password)) {
response.getWriter().write("登录成功");
} else {
response.getWriter().write("登录失败");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
post请求正常,get请求,用户名和密码输入中文的时候,打印的是乱码。是因为浏览器会自动进行uriEncoding。
设置request.setCharacterEncoding("UTF-8");是设置请求体的编码,并不会影响url。所以post请求正常,get会乱码。
解决: 方法一:在tomcat7,server.xml的connector标签配置uriEncoding。 方法二:在tomcat7插件里配置。
<configuration>
<path>/myweb</path>
<port>8080</port>
<uriEncoding>UTF-8</uriEncoding>
</configuration>
当输入账号和密码后,发现响应又是乱码。这里就不是Tomcat7的问题了,Tomacat9也有可能有问题。
这是因为首先LoginServlet.java里的内容写入文件时,IDEA配置的是UTF-8编码
LoginServlet.java编译的过程中,会首先加载到内存中,然后再写入.class文件,那么加载在内存和写入.class文件的时候,如果用IDEA build,他会保持和写入文件时一样的编码方式,但是如果用mvn package,如果不配置,他会使用系统默认的编码方式,windows是GBK.(mac这里没问题) 就会导致乱码的产生。
配置maven编译的时候编码方式,pom.xml里增加:
<!-- 属性-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>