JavaWeb(1-Web、Tomcat、Http 和 Maven)

421 阅读54分钟

1.web的基本概念

静态web

  • html、css
  • 提供给所有人看的数据始终不会发生变化!

动态web

  • 淘宝,几乎是所有的网站。
  • 提供给所有人看的数据始终会发生变化,每个人在不同的时间,不同的地点看到的信息各不相同。
  • 技术栈:servlet/JSP,ASP,PHP

在Java中,动态web资源开发的技术统称为JavaWeb

web应用程序 Web应用程序:一种可以通过浏览器进行访问的程序。它包含多个web资源,如a.html、b.html等,这些资源可以被外界访问并提供服务。每一个你能访问到的页面或资源,实际上都存储在世界某处的计算机上。

Web应用程序的组成

一个完整的web应用由多个部分组成,包括静态web和动态web。

静态web:

  • 后缀通常为.htm或.html。
  • 服务器上直接存储的网页文件,可以直接读取。
  • image.png
  • 缺点:
    • 页面无法动态更新,所有用户看到的内容都相同。
    • 虽然有轮播图、点击特效等伪动态效果,但这些通常通过JavaScript等客户端脚本实现。
    • 无法与数据库交互,数据无法持久化,用户交互受限。

动态web:

  • 页面内容会根据用户或其他条件动态展示。
  • image.png
  • 优点:
    • 页面可以动态更新,不同用户可能看到不同的内容。
    • 可以与数据库交互,实现数据的持久化和用户交互。
  • 缺点:
    • 如果动态资源出现错误,需要重写后台程序并重新发布,可能导致停机维护。

Web应用程序的部署与运行

Web应用编写完成后,需要部署到服务器上才能供外界访问。服务器统一管理这些资源,并提供相应的服务。

  • Web页面可以动态更新,所有用户看到都不是同一个页面
  • 它可以与数据库交互(数据持久化:注册,商品信息,用户信息………)

2.web服务器讲解

2.1 技术讲解

ASP (Active Server Pages)

  • 微软开发的一种服务器端脚本环境,用于创建动态和交互式的Web页面
  • 优点:允许开发者在HTML中嵌入VBScript或JScript脚本代码,使得服务器端可以动态地生成和修改网页内容。此外,ASP还可以与COM(Component Object Model)组件交互,这使得ASP能够利用Windows平台上丰富的组件库。
  • 缺点:存在一些局限性,如代码与HTML混合导致页面结构混乱、维护困难成本高,以及性能瓶颈等问题

PHP (Hypertext Preprocessor)

  • PHP是一种通用的开源脚本语言,尤其适用于Web开发。
  • 优点:简单易学,功能强大,且跨平台兼容性好。在开发速度、代码简洁性等方面具有优势,特别在中小型网站和Web应用程序中广泛应用
  • 缺点:在处理高并发、大数据量时可能会遇到性能瓶颈。

JSP/Servlet

  • JSP(JavaServer Pages)和Servlet都是基于Java语言的Web开发技术。
  • JSP 允许在HTML页面中嵌入Java代码片段,使得页面呈现逻辑与业务逻辑分离,提高了代码的可读性和可维护性。
  • Servlet 则是运行在Web服务器或应用服务器上的Java程序,用于处理客户端的请求并返回响应。
  • Java作为一种跨平台的语言,使得基于Java的Web应用可以在不同的服务器上运行
  • B/S (浏览器/服务器):指客户端主要通过Web浏览器与服务器进行交互的架构模式。在这种架构中,大部分的业务逻辑和数据处理都集中在服务器端,客户端只需要一个支持HTML和JavaScript的浏览器即可。
  • C/S (客户端/服务器):指应用程序分为客户端和服务器两部分。客户端通常是一个专门安装的软件,负责与服务器进行通信和交互。与B/S架构相比,C/S架构在某些情况下可以提供更好的性能和更丰富的交互体验,但部署和维护成本可能更高。
  • 很多与Web开发相关的开源组件和技术都是基于Java的。Java在Web开发领域有着广泛的应用
  • Java Web技术,特别是基于Servlet和JSP的应用,结合适当的架构设计和优化,可以承载 高并发、高负载和高可用 要求带来的影响。
  • JSP的语法与ASP在某些方面相似(例如,它们都允许在HTML中嵌入服务器端代码)

2.2 Web服务器

Web服务器是一种被动操作的软件,用于处理客户端的请求并返回相应的响应信息。常见的Web服务器软件有IIS、Tomcat等。

IIS (Internet Information Services)

IIS是微软开发的Web服务器软件,主要用于Windows操作系统。它支持ASP、ASP.NET等Web开发技术,提供了丰富的配置选项和管理工具。IIS与Windows系统紧密集成,方便部署和管理Web应用程序。

Tomcat

Tomcat是Apache 软件基金会(Apache Software Foundation)的jakarta项目中的一个开源项目,最新的Servlet 和JSP 规范总是能在Tomcat中得到体现,因为Tomcat 技术先进、性能稳定,而且免费,因而深受lava爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web应用服务器。

Tomcat 服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选。对于Java初学者来说,Tomcat是一个很好的选择。

手写Tomcat服务器
手写Tomcat服务器是一个高级且富有挑战性的任务,通常在工作3-5年后,对Java Web开发有了深入理解和实践经验后,可以尝试进行。

3、Tomcat

3.1、安装tomcat

官网:tomcat.apache.org/

3.2、Tomcat启动

  1. 使用startup.bat文件启动

    • 找到Tomcat的安装目录,进入bin文件夹。
    • 双击startup.bat文件来启动Tomcat。
    • 启动后,可以在浏览器中输入以下地址来验证是否启动成功:http://localhost:8080http://127.0.0.1:8080 或者 http://电脑真实ip:8080。 (这个地址是Tomcat的默认根目录,通常显示Tomcat的欢迎页面。)
    • 要关闭Tomcat,可以双击bin目录下的shutdown.bat文件,或者直接关闭命令窗口。
  2. 使用命令行启动

    • 打开命令行窗口(cmd),进入Tomcat安装目录下的bin文件夹。
    • 输入命令 catalina run 并按回车键启动Tomcat。
    • 同样,启动后可以通过上述浏览器地址来验证。
  3. 可能遇到的问题及其解决方案

  • Java环境变量没有配置
    解决方案:确保已经安装了Java,并正确配置了JAVA_HOME环境变量,以及将Java的bin目录添加到系统的PATH环境变量中。
  • 如果Tomcat启动后立即闪退
    解决方案:可能是Java版本不兼容或系统权限问题。尝试以管理员权限运行Tomcat,或者检查Java版本是否与Tomcat兼容。
  • 乱码问题
    解决方案:乱码问题通常是由于字符编码不一致导致的。可以通过修改 conf/logging.properties 文件中的 java.util.logging.ConsoleHandler.encoding 属性来设置控制台输出的编码,例如设置为GBKjava.util.logging.ConsoleHandler.encoding = GBK 。此外,还需要确保的Web应用程序的页面编码与Tomcat服务器的编码设置一致。

3.2、Tomcat的目录结构

Tomcat的目录结构是有组织且易于理解的。以下是一些关键文件夹及其作用:

  • bin:包含Tomcat的启动和关闭脚本,以及其他一些有用的命令行工具。
  • conf:包含Tomcat的配置文件,如server.xml(定义服务器配置)、web.xml(定义Web应用程序的默认配置)等。
  • lib:包含Tomcat运行所需的库文件。
  • logs:Tomcat的日志文件存放地,用于记录运行时的信息、错误等。
  • temp:Tomcat运行时使用的临时文件存放地。
  • webapps:这是Web应用程序的部署目录。你可以将你的.war文件或解压后的Web应用程序目录放在这里,Tomcat会自动部署它们。
  • work:Tomcat编译JSP文件时生成的Servlet类和其他临时文件存放地。

3.3、Tomcat配置

Tomcat的端口配置

默认情况下,Tomcat使用8080端口监听HTTP请求。在Tomcat的配置文件server.xml中,你可以找到一个或多个<Connector>元素,用于配置Tomcat的连接器。例如:

<Connector port="8081" protocol="HTTP/1.1"
      connectionTimeout="20000"
      redirectPort="8443" />

port="8080": 指定Tomcat监听的端口号。可以将其更改为其他未被占用的端口
protocol="HTTP/1.1": 指定使用的协议
connectionTimeout="20000": 指定连接的超时时间(以毫秒为单位)
redirectPort="8443": 当请求需要重定向到HTTPS时,使用的端口号

可以配置启动的端口号

  • Tomcat 的默认端口号为:8080。
  • MySQL 的默认端口号为:3306端口。这个端口是MySQL用于监听客户端连接的端口。如果更改了MySQL的配置并指定了不同的端口,那么客户端连接时就需要使用新的端口号。
  • HTTP 的默认端口号为: 80。当在浏览器中输入一个网址(例如http://www.example.com)而不指定端口时,浏览器会默认使用80端口进行连接。
  • HTTPS 的默认端口号为: 443。当在浏览器中输入一个SSL/TLS加密的HTTPS网址(例如https://www.example.com)时,浏览器会使用443端口进行连接。

可以配置主机的名称

在Tomcat中,可以配置虚拟主机(Virtual Hosts),使得不同的主机名或域名可以映射到不同的Web应用程序。默认的主机名为localhost,它通常映射到本地IP地址127.0.0.1 这意味着当访问http://localhost:8080时,实际上是在访问运行在本机的Tomcat服务器。

网站应用存放位置

Tomcat默认将Web应用程序存放在webapps目录下。当将一个WAR(Web Application Archive)文件(通常是一个以.war为扩展名的压缩文件)放在这个目录下时,Tomcat会自动解压它并部署为一个Web应用程序。也可以在Tomcat的配置文件中修改这个默认的应用存放位置。

Tomcat的虚拟主机配置

  <Host name="www.qinjiang.com"  appBase="webapps"
        unpackWARs="true" autoDeploy="true">
        
name="http://www.qinjiang.com":指定了此<Host>元素的名称,即它代表的虚拟主机名。在这个例子中,它是www.qinjiang.com
当Tomcat接收到一个请求时,它会根据请求中的主机名来确定应该使用哪个<Host>元素来处理该请求

appBase="webapps":appBase属性定义Tomcat在其安装目录下的哪个子目录中查找Web应用程序。默认情况下,这个值是 webapps 
当将WAR文件放在这个目录下时,Tomcat会自动解压它并部署为Web应用程序

unpackWARs="true":unpackWARs属性决定当Tomcat发现一个WAR文件时是否应该自动解压它
如果设置为 true ,则Tomcat会解压WAR文件并将解压后的内容作为Web应用程序。
如果设置为 false ,则Tomcat会直接从WAR文件中运行应用程序,这通常被称为“WAR内运行”

autoDeploy="true":autoDeploy属性决定Tomcat是否应该自动部署在 appBase 目录下找到的新Web应用程序或WAR文件
如果设置为 true ,则当Tomcat检测到新的Web应用程序或WAR文件时,它会自动部署它们。
如果设置为 false ,则需要手动触发部署过程

高难度面试题:请你谈谈网站是如何进行访问的

网站访问流程

  1. 输入域名并回车:
    用户在浏览器地址栏中输入一个域名(如www.qinjiang.com),然后按下回车键。
  2. 检查本地hosts文件:
    浏览器会首先检查本机的C:\Windows\System32\drivers\etc\hosts文件,看是否有这个域名的映射记录。hosts文件是一个用于存储IP地址和主机名映射关系的文本文件,它允许用户为特定的主机名指定IP地址。
    • 如果有映射:浏览器会直接使用hosts文件中指定的IP地址进行访问,跳过DNS解析过程。
    • 如果没有映射:浏览器会继续进行DNS解析。
  3. DNS解析:
    浏览器会向配置的DNS服务器发送DNS查询请求,以获取该域名的IP地址。
    • 找到IP地址:DNS服务器返回域名对应的IP地址,浏览器使用这个IP地址建立连接。
    • 未找到:如果DNS服务器未能找到对应的IP地址,浏览器会向用户显示一个错误消息,如“无法找到服务器”或“DNS解析错误”。 image.png
  4. 建立TCP连接:
    浏览器使用获得的IP地址与目标服务器建立TCP连接。这个过程中,浏览器会向服务器发送一个SYN(同步)包,服务器响应一个SYN-ACK(同步应答)包,然后浏览器再发送一个ACK(应答)包,完成TCP三次握手。
  5. 发送HTTP请求:
    TCP连接建立后,浏览器会发送一个HTTP请求到服务器。这个请求包含了请求的方法(如GET、POST等)、请求的URI(统一资源标识符)、HTTP版本以及其他一些请求头和可能的请求体。
  6. 服务器响应:
    服务器收到HTTP请求后,会处理请求并返回一个HTTP响应。这个响应包含了HTTP状态码(如200表示成功)、响应头和响应体(即网页内容)。
  7. 浏览器渲染:
    浏览器收到服务器的响应后,会解析响应体中的HTML、CSS、JavaScript等内容,并渲染出网页界面供用户查看。
  8. 配置环境变量(可选)
    配置一些与网络连接或应用程序运行相关的环境变量。例如,可以配置代理服务器的地址和端口,以便在访问网站时通过代理服务器进行转发;或者配置某些应用程序的路径,以便在命令行中直接调用这些应用程序。
    需要注意的是,环境变量的配置并不是网站访问流程中的必要步骤,而是根据具体需求进行的可选配置。对于大多数普通用户来说,通常不需要手动配置环境变量来访问网站。

3.4、发布一个web网站

发布一个Web网站到Tomcat服务器涉及几个关键步骤:

  1. 准备网站文件
    首先,需要按照上述结构准备好你的网站文件。这通常包括HTML、CSS、JavaScript文件,以及任何网站需要的图片或其他资源。确保文件结构清晰,并按照上述示例组织它们。
  2. 安装Tomcat服务器
  3. 将网站文件放入Tomcat的webapps目录
  4. 启动Tomcat服务器
    启动Tomcat服务器。可以通过命令行、Tomcat的管理界面或使用集成开发环境(IDE)如Eclipse或IntelliJ IDEA来启动它。
  5. 访问网站
    一旦Tomcat服务器启动并运行,就可以通过浏览器访问网站了。在地址栏中输入http://localhost:8080/kuangstudy(假设Tomcat运行在默认的8080端口上,并且你的网站目录是kuangstudy)。就能看到网站首页(index.html)。

网站应该有的结构

  • webapps : tomcat服务器的web目录
    • ROOT
    • kuangstudy : 网站的目录名
      • WEB-INF
        • classes : java程序
        • lib : web应用所依赖的jar包
        • web.xml : 网站配置文件
      • index.html : 默认的首页
      • static
        • css
          • style.css
        • js
        • img

4、Http

4.1、什么是HTTP

HTTP(Hypertext Transfer Protocol,超文本传输协议)

  • 一种应用层的协议,用于在网络中传输超文本
  • HTTP通常运行在TCP协议之上
  • 它采用请求/响应模式:客户端发出一个请求,服务器接收并处理这个请求,然后返回一个响应给客户端

HTTP能够传输各种类型内容,它们都是构成现代网页的关键元素

  • 文本内容:纯文本、HTML文档等
  • 超文本内容:图片、音乐、视频、链接等

由于HTTP协议使用80端口作为默认端口,因此我们在访问网站时通常不需要指定端口号。

另外,还有一个与HTTP相关的安全协议,叫做 HTTPS(Hypertext Transfer Protocol Secure)。HTTPS是HTTP的安全版本,它通过SSL/TLS协议对传输的数据进行加密,从而保护数据的完整性和隐私性。

4.2、两个时代

HTTP协议经历了两个主要的版本,即HTTP/1.0和HTTP/1.1。这两个版本在请求处理方式和连接管理上有一些重要的区别。

HTTP/1.0

  • 客户端与服务器建立连接后,只能获取一个Web资源,然后连接就会断开。
  • 这种连接方式被称为“短连接”。每次请求都需要重新建立连接,这在一定程度上影响了网络资源的利用效率和性能。

HTTP/1.1

  • 客户端与服务器建立连接后,可以在同一个连接上连续获取多个Web资源,直到客户端或服务器决定关闭连接。
  • 这种连接方式“持久连接”。这种连接方式显著提高了网络资源的利用率和性能,减少了建立和关闭连接的开销。

总的来说,HTTP/1.1相较于HTTP/1.0在连接管理和性能上有了显著的提升,使得Web应用能够更高效地传输和处理数据。

4.3、Http请求

客户端(如浏览器或某个应用程序)向服务器发送一个请求,服务器接收到请求后进行处理,并返回响应给客户端。

4.3.1、请求行

请求行是HTTP请求的第一部分,它主要包括三个部分:请求方法(或称为请求方式)、请求的资源路径(或称为请求URI)以及HTTP协议的版本。

请求方式

  • GET:用于请求指定的页面信息,并返回实体主体。

    • 最常用的请求方式,请求能够携带的参数比较少,且大小有限制(具体限制取决于浏览器和服务器)。GET请求的参数会附加在URL后面,因此会在浏览器的地址栏中显示,这可能导致敏感信息泄露,所以不安全。但因为它简单且直接,所以效率较高。
  • POST:用于提交表单数据到指定的资源,请求服务器进行处理(例如,提交用户注册信息)。

    • POST请求的参数不会显示在URL中,而是作为请求体发送,因此不会在浏览器的地址栏中显示,相对较为安全。POST请求能够携带的参数没有限制,大小也没有限制(但受限于服务器的配置)。不过,因为需要处理请求体,所以相比GET请求可能效率稍低。

除了GET和POST之外,还有其他的请求方式:

  • HEAD:类似于GET请求,但只返回响应头,不返回实体主体。
  • DELETE:请求服务器删除指定的页面。
  • PUT:请求服务器更新资源的全部内容。
  • TRACE:回显服务器收到的请求,主要用于测试或诊断。

请求URL

  • URL网址:客户端(如浏览器)向服务器发起请求时使用的地址,即客户端想要访问的网页地址

HTTP协议的版本

  • HTTP协议的两个主要版本是 HTTP 1.0HTTP 1.1

示例
一个典型的HTTP请求行可能如下所示:

GET /index.html HTTP/1.1

其中,GET是请求方法,/index.html是请求的资源路径,HTTP/1.1表示客户端使用的是HTTP 1.1协议版本,三者以空格分隔

4.3.2、请求头

作用:请求头包含了客户端和服务器之间的附加信息,如请求的类型、请求体的大小、请求体内容的类型、客户端信息等。

格式:请求头以键值对的形式存在,每个键值对由一个字段名(key)和一个字段值(value)组成,它们之间用冒号:分隔,字段名和字段值之间由空格分隔

某些请求头字段(如Cookie)可能包含多个键值对,这些键值对之间由分号;分隔。例如:

Cookie: name=John; age=25; location=New York
  • Accept:客户端告诉服务器它支持的数据类型(如 text/html, application/json等),这样服务器可以返回客户端能够处理的内容。
  • Accept-Encoding:客户端告诉服务器它支持的编码格式。如 gzip, deflate, br 等,用于内容的压缩和解压。
  • Accept-Language:客户端告诉服务器它希望接收语言,这样服务器可以返回对应语言的内容
  • Cache-Control:用于控制缓存的行为。如 max-age=0表示不使用缓存
  • Connection:用于控制连接是否应该在请求之后关闭或保持打开。如 keep-alive表示保持连接打开,以便进行更多的请求。
  • HOST:指定请求的主机和端口号,用于虚拟主机的情况。

4.3.3、请求体

请求体是指HTTP请求中,位于请求头部之后的数据部分。它用于在客户端和服务器之间传输数据,这些数据可以是简单的文本、复杂的JSON或XML结构、二进制文件等。

请求体的使用场景

  • POST请求:在POST请求中,请求体通常用于提交表单数据、JSON对象、文件等。
  • PUT请求:在PUT请求中,请求体可以用于上传资源或更新服务器上的资源。
  • PATCH请求:在PATCH请求中,请求体用于部分更新服务器上的资源。

请求体的内容

请求体的内容取决于发送的数据类型。以下是一些常见的请求体内容类型:

  • application/x-www-form-urlencoded:这是表单数据的默认编码方式,其中数据以键值对的形式编码。
  • multipart/form-data:用于发送包含文件上传的表单数据。
  • application/json:用于发送JSON格式的数据。
  • text/xml 或 application/xml:用于发送XML格式的数据。
  • application/octet-stream:用于发送二进制数据,如文件内容。

当使用请求体时,必须在HTTP请求头部中设置Content-Type来指明请求体的内容类型

4.3.4、示例

客户端向百度的服务器发送了请求的示例

请求行

GET https://www.baidu.com/ HTTP/1.1

请求头

Accept: text/html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive

在这个特定的例子中
Accept-Language:zh-CN,zh;q=0.9 客户端首选简体中文(zh-CN),其次是中文(zh),但后者的优先级较低(q=0.9)
Cache-Control:max-age=0 客户端告诉服务器它不希望使用缓存的内容,而是希望获取最新的内容

  • max-age:这是一个指令,它告诉缓存机制响应内容在多长时间内被认为是“新鲜”的,即在这段时间内可以直接从缓存中提供内容,而不需要再次向服务器发起请求。
  • =0:这是max-age指令的值,它设置为0意味着响应内容立即过期。换句话说,客户端不希望使用任何缓存的响应,而是希望从服务器获取最新的内容。

它实际上是在告诉所有可能位于请求路径上的缓存(如代理服务器、CDN缓存或浏览器本地缓存)不要提供缓存的响应,而是直接转发请求到原始服务器以获取最新的内容。

描述性信息

状态码:200 OK
远程地址:14.215.177.39:443
  • 状态码:200 OK远程地址:14.215.177.39:443 并不是请求的一部分,而是HTTP响应的状态码和服务器地址
  • 在HTTP请求中,只有请求行和请求头是由客户端发送给服务器的。服务器在接收到请求后,会返回一个HTTP响应,其中包含状态码、响应头和响应体。状态码和远程地址(即服务器的IP地址和端口号)是响应的一部分

4.4、Http响应

在HTTP协议中,服务器对客户端的请求做出响应,这个响应包含了状态码、响应头和响应体等信息。

4.4.1、响应状态行

它包括HTTP版本、状态码和状态消息。例如:

HTTP/1.1 200 OK

这里HTTP/1.1是版本,200是状态码,表示请求成功,OK是状态消息。

4.4.2、响应头

响应头是服务器在响应客户端请求时,发送的一系列关于响应的元数据。例如:

  • Cache-Control:用于控制响应的缓存行为。如 private 表示这个响应是私有的,不应该被任何中间缓存存储
  • Connection:用于控制连接是否应该在响应之后关闭或保持打开。如 Keep-Alive 表示服务器希望保持连接打开
  • Content-Encoding:用于指示响应内容的编码方式。如 gzip 表示响应内容使用gzip算法进行了压缩,客户端需要解压缩才能查看内容
  • Content-Type 用于指示响应的内容类型的数据类型
  • Location:让网页重新定位
  • Refresh:告诉客户端,多久刷新一次。这不是一个标准的HTTP响应头。有时,它可能会在HTML元标签中使用来告诉浏览器多久刷新一次页面,但它不是HTTP协议的一部分。

与请求头类似,请求头和响应头共同组成消息头。

4.4.3、响应体

响应体是服务器响应HTTP请求的实际内容。在HTML文档的上下文中,响应体就是HTML代码,客户端(如浏览器)会解析这些代码并将其渲染成可视化的网页。

4.4.4、响应状态码

状态码是服务器响应的一部分,它是一个三位数字代码,用来告诉客户端请求的处理结果。

  • 200 表示请求成功,服务器已经正常处理了请求。
  • 3xx 表示重定向,客户端需要根据服务器提供的新的URL重新发送请求。
  • 4xx 表示客户端错误,如404表示请求的资源不存在。
  • 5xx 表示服务器错误,如500表示服务器遇到了一个意外情况,无法完成对请求的处理。

4.5、常见面试题(HTTP请求的整个生命周期)

当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?

即,描述的是HTTP请求的整个生命周期:

  • 解析URL,确定请求的协议、服务器地址和路径。
  • 将域名解析为IP地址。
  • 建立到服务器的TCP连接(如果是HTTPS,还包括TLS/SSL握手)。
  • 发送HTTP请求到服务器。
  • 服务器处理请求,并返回响应状态码、响应头和响应体。
  • 浏览器接收响应,并根据响应状态码进行相应处理(如重定向、显示网页或显示错误信息)。
  • 浏览器解析响应体(如HTML文档),并渲染成可视化的网页展示给用户。

5、Maven

Maven 安装配置部分参考:Maven 安装配置教程-CSDN博客

5.1、Maven项目架构管理工具

5.1.1、Maven简介

背景:构建一个项目需要用到很多第三方的类库,如写一个使用Spring的Web项目就需要引入大量的jar包。一个项目Jar包的数量之多往往让我们瞠目结舌,并且Jar包之间的关系错综复杂,一个Jar包往往又会引用其他Jar包,缺少任何一个Jar包都会导致项目编译失败。

而Maven就是一款帮助程序员构建项目的工具,我们只需要告诉Maven需要哪些Jar 包,它会帮助我们下载所有的Jar,极大提升开发效率。

作用:在Javaweb开发中,需要导入大量的jar包,Maven用来方便导入jar包

Maven的核心思想:约定大于配置
解释:Maven有一套默认的、经过良好设计的目录结构和项目生命周期。这种约定使得开发者在创建新的Maven项目时,能够快速地理解项目的结构,而不需要花费大量的时间去配置这些细节。开发者应该尽可能地遵循这些默认约定,以保持项目的一致性和可维护性。

所以,使用Maven时,项目的目录结构必须符合Maven的规范,其目录结构如下: 201808131239225.jpg

5.1.2、Maven基本命令

Maven的基本命令是Maven生命周期的一部分,它们帮助用户在项目的不同阶段进行操作。以下是一些常用的Maven命令:

mvn -v 或 mvn --version:这个命令用于查看Maven的版本信息,以确认Maven是否正确安装。

mvn compile:这个命令会编译项目中的源代码。具体来说,它会将src/main/java目录下的Java源文件编译成class文件,并将编译结果放在target/classes目录下。

mvn test:这个命令会执行项目中所有的单元测试。它首先编译src/test/java目录下的测试源代码(如果之前没有编译过),然后执行这些测试用例,并生成测试报告。

mvn package:这个命令会打包项目,默认情况下,它将项目打包成一个jar文件,放在target目录下。如果项目是一个Web应用,可能会打包成war文件。

mvn clean:这个命令会清理项目,主要是删除target目录下的所有生成文件,包括编译后的class文件、测试报告、打包后的jar或war文件等。

mvn install:这个命令会将项目打包并安装到Maven的本地仓库中,这样其他Maven项目就可以通过坐标来引用这个项目了。

如何使用这些命令

  • 确保系统已经安装了Maven,并且可以在命令行中访问。
  • 打开命令行终端。
  • 切换到项目的根目录,也就是包含pom.xml文件的目录。
  • 输入上述命令之一,并按回车执行。

在运行这些命令时,Maven会自动下载所有必要的依赖,并按照Maven的生命周期顺序执行一系列的任务。

5.1.3、Maven仓库

Maven仓库用来存放Maven管理的所有Jar包,分为:本地仓库 和 中央仓库。

本地仓库:Maven本地的Jar包仓库,即自己计算机上的一个目录。
中央仓库: Maven官方提供的仓库。
远程仓库(私服):一般由公司团队搭建的私有仓库。

jar包的查找顺序为: 本地仓库 -> 远程仓库 -> 中央仓库

5.1.4、坐标

在Maven中,坐标是用于唯一标识一个 项目或依赖(在Maven中,依赖通常是指那些在pom.xml文件中声明的库,它们可以是Jar包,也可以是其他形式的打包文件,如War包或Ear包。) 的三元组,它由groupIdartifactIdversion三个部分组成。这三个部分共同定义了一个项目在Maven仓库中的位置,使得Maven能够准确地找到并管理项目的依赖。

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>5.3.19</version>
</dependency>

下面是对这三个坐标向量的解释:

  • groupId:这是组织或公司的一个唯一标识符,通常是以组织的域名倒序的形式给出。例如,Spring框架的groupIdorg.springframework,其中springframework是组织的名称,org是顶级域名,表示这是一个非商业组织。
  • artifactId:这是项目的唯一基本标识符,通常是项目名称。在Spring框架的例子中,artifactIdspring-context,这表示它是Spring框架中与上下文相关的模块。
  • version:这是项目版本的标识符。版本号通常包含 major.minor.patch-qualifier 的格式,其中 major 是主版本号,minor 是次版本号,patch 是补丁版本号,qualifier 是可选的限定符,如SNAPSHOTRC1等。在Spring框架的例子中,version5.3.19,表示这是Spring框架5.3系列的第19个补丁版本。

上面的依赖声明告诉Maven,项目需要org.springframework组织下的spring-context模块,版本为5.3.19的Jar包。Maven会使用这个信息在仓库中定位并添加这个依赖到项目的类路径中。

5.2、下载安装Maven

官网:maven.apache.org/

下载完成后,解压即可;

电脑上的所有环境都放在一个文件夹下,方便管理;

5.3、配置环境变量

在我们的系统环境变量中配置如下配置:

image.png image.png image.png image.png

测试Maven是否安装成功:以管理员身份运行命令行窗口,输入mvn -v,如图所示则配置成功

5.4、阿里云镜像

  • 镜像:mirrors
  • 作用:加速我们的下载
  • 国内建议使用阿里云的镜像
<mirror>
    <id>nexus-aliyun</id>  
    <mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf>  
    <name>Nexus aliyun</name>  
    <url>http://maven.aliyun.com/nexus/content/groups/public</url> 
</mirror>

5.5、本地仓库

在本地的仓库,远程仓库; 建立一个本地仓库:localRepository

<localRepository>D:\Environment\apache-maven-3.6.2\maven-repo</localRepository>
  • 依赖指当前项目所运行的所需jar包,一个项目可以设置多个依赖
  • 格式:
<!--设置当前项目所依赖的所有 jar 包-->
<dependencies>
	<!--设置具体的依赖-->
	<dependency>
		<!--设置所属群组 id-->
		<groupId>org.springframework</groupId>
		<!--依赖所属项目 id-->
		<artifactId>spring-context</artifactId>
		<!--依赖版本号-->
		<version>5.3.19</version>
	</dependency>
</dependencies>

5.6、依赖管理

5.6.1、 依赖配置

屏幕截图 2024-07-05 144954.png

如果不知道依赖的坐标信息,可以访问Maven仓库搜索需要的依赖,优先选择使用频次最多的版本,其中有该版本依赖的坐标,复制 <dependency>...</dependency>部分粘贴到 pom.xml 中,<scope>标签内的内容不需要,应该删去

依赖配置发生改变就要刷新

5.6.1、 依赖范围

作用:通过设置值坐标的依赖范围(scope),可以设置对应jar包的作用范围:编译环境 测试环境 运行环境

<scope> 默认值:compile

5.6.2、 依赖传递

依赖传递是Maven中的一个特性,它允许项目自动地引入其依赖项的依赖。这种机制可以简化依赖管理,因此不需要手动添加所有必要的依赖,只需添加顶层的依赖,Maven会自动处理其余的。 在Maven中,依赖传递遵循以下原则:

  1. 直接依赖间接依赖
    • 直接依赖是指在项目的pom.xml文件中明确声明的依赖。
    • 间接依赖是指直接依赖所依赖的其他库。这些库会被Maven自动解析并添加到项目的类路径中。
  2. 依赖传递冲突问题
    当项目中存在多个依赖,而这些依赖又依赖于不同版本的同一个库时,就会发生依赖冲突。
    Maven使用以下规则来解决依赖冲突:
  • 路径优先:如果依赖树中有多个相同资源的不同版本,Maven会选择路径最短的版本。 例如: 本项目——>A.jar——>B.jar——>X.jar 本项目——>C.jar——>X.jar C.jar和A.jar都依赖了X.jar,但是C.jar的直接依赖路径比A.jar短,那么Maven只会使用C.jar所依赖的X.jar版本。
  • 声明优先:如果两个依赖在pom.xml文件中处于相同层级,那么先声明的依赖优先。在pom.xml中,先出现的依赖会比后出现的依赖具有更高的优先级。
  • 特殊优先:如果同一层级中有多个相同资源的不同版本,且无法通过路径优先或声明优先来解决,那么Maven会默认使用最后一个声明的版本。

如果需要,还可以使用Maven的<exclusions>元素来排除特定的间接依赖,从而手动解决冲突(后详析)。

5.6.3、 可选依赖与排除依赖

可选依赖 和 排除依赖 是Maven中用于管理依赖关系的两个重要特性。

可选依赖

可选依赖允许我们指定某些依赖在传递时不会被包含。这意味着如果一个项目A依赖了项目B,而项目B有一个可选依赖的项目C,那么项目A不会自动继承对项目C的依赖。可选依赖通过<optional>标签在pom.xml中指定,其值可以是truefalse

  • true:表示这个依赖是可选的,不会被子项目继承。
  • false(默认值):表示这个依赖是必需的,会被子项目继承。 例如:
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.19</version>
        <optional>true</optional>
    </dependency>
</dependencies>

在这个例子中,spring-context被标记为可选依赖,因此其他依赖于这个项目的项目不会自动获得spring-context的依赖。

排除依赖

排除依赖允许我们在项目中显式地移除传递性依赖。有时候,我们可能不希望项目依赖树中的某个特定依赖,或者因为版本冲突等原因需要手动控制依赖。在这种情况下,可以在pom.xml中使用<exclusions>标签来排除这些依赖。 例如:

<dependency>
    <groupId>com.tyt</groupId>
    <artifactId>maven_03_pojo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <exclusions>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
    </exclusions>
</dependency>

在这个例子中,maven_03_pojo项目依赖了log4j,但是我们在当前项目中不希望使用log4j,因此我们使用<exclusions>标签排除了对log4j的依赖。

总结来说,可选依赖和排除依赖都是Maven中用于精细控制依赖关系的工具,它们可以帮助您避免不必要的依赖传递和冲突,确保项目的依赖树清晰和稳定。

5.7、分模块开发

5.7.1、分模块开发意义

分模块开发需要先针对模块功能进行设计,再进行编码。这意味着在项目开始时,就应该根据功能需求将项目划分为多个模块,并为每个模块定义清晰的职责和接口。

将原始模块按功能拆分成若干个子模块,方便模块间的 相互调用接口共享

5.7.2、分模块步骤

分模块开发步骤
分模块开发的步骤大致是正确的,但是为了完整性,可以稍微补充一些细节和后续步骤:

  1. 创建 Maven 模块
    • 创建一个新的Maven项目,每个模块都应该有自己的pom.xml文件。
    • pom.xml文件中定义模块的groupIdartifactIdversion等坐标信息。
  2. 书写模块代码
    • 在模块的源代码目录中编写实现模块功能的代码。
    • 确保代码符合模块的设计和接口规范。
  3. 通过 install 指令将模块安装到本地仓库
    • 使用Maven的install命令来构建模块,并将构建好的Jar包安装到本地仓库。
    • 本地仓库是模块依赖的缓存,方便其他模块直接引用。
  4. (可选)发布模块到团队内部可共享的仓库中(私服)
    • 在团队开发中,为了方便模块的共享和重用,可以将模块发布到团队内部的Maven私服中。
    • 发布到私服后,其他团队成员可以通过私服来获取和使用这些模块,而不需要每个开发者都单独构建这些模块。
  5. 其他模块引入 maven_03_pojo 模块
    • 在其他模块的pom.xml文件中,添加对新建模块的依赖声明。
    • 依赖声明的格式通常是:
    <dependency> 
        <groupId> </groupId>
        <artifactId> </artifactId> 
        <version> </version> 
    </dependency>
    

示例

这是原工程目录结构,现将其 com.tyt 包下的domain抽取出,感受一下分模块。

其中包含一个名为com.tyt的包,这个包下有domain目录(其中包含了一些Java类)。 为了提高代码的可维护性和可重用性,我们可以将这些类抽取出来,创建一个新的Maven模块maven_03_pojo

步骤:

  1. 创建 Maven 模块
    首先,我们需要创建一个新的Maven项目,这个项目将成为我们的maven_03_pojo模块。
  2. 配置新建模块的坐标信息
    maven_03_pojo模块的pom.xml文件中,我们需要配置模块的坐标信息,包括groupIdartifactIdversion。这些坐标信息定义了模块在Maven仓库中的位置。 例如:
    <project>
      <groupId>com.tyt</groupId>
      <artifactId>maven_03_pojo</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>jar</packaging>
      <!-- 其他配置 -->
    </project>
    
  3. 书写模块代码
    maven_03_pojo模块中,我们将com.tyt包下的domain目录复制到模块的src/main/java目录下。
  4. 执行 install 指令
    maven_03_pojo模块的根目录下,我们可以执行install命令来构建模块,并将构建好的Jar包安装到本地仓库,便于其他模块引入。
  5. 其他模块引入 maven_03_pojo 模块
    在其他模块中,我们只需要在pom.xml文件中添加对maven_03_pojo模块的依赖声明,就可以使用这个模块中的类了。
    <dependencies>
      <dependency>
        <groupId>com.tyt</groupId>
        <artifactId>maven_03_pojo</artifactId>
        <version>1.0-SNAPSHOT</version>
      </dependency>
    </dependencies>
    

通过这种方式,我们实现了分模块开发,将com.tyt包下的domain抽取出来,创建了一个独立的Maven模块maven_03_pojo

作用:其他模块可以通过添加依赖来引入这个模块,从而使用其中的类。 分模块开发有助于提高代码的可维护性、可重用性和可测试性。

5.8、聚合与继承

5.8.1、聚合

在Maven中,聚合是指将多个Maven项目(模块)组合在一起,以便能够同时构建它们。聚合通常用于管理多模块项目,其中每个模块都是一个独立的Maven项目,但它们一起构成了一个更大的项目。聚合工程本身通常不包含任何业务代码,它只是一个包含pom.xml文件的壳工程,这个文件中会列出所有被聚合的子模块。

聚合的作用

  • 同步构建:当我们需要对多个模块进行同步构建时,可以使用聚合工程。例如,当一个模块更新时,其他依赖它的模块也需要重新构建,聚合工程可以帮助我们一次性构建所有相关的模块。
  • 简化构建过程:通过聚合工程,我们可以通过一次构建命令来构建多个模块,而不是分别进入每个模块的目录进行构建。
  • 统一管理:聚合工程提供了一个统一的视角来管理多个模块的依赖、插件和版本等信息。

聚合工程的配置

创建Maven聚合工程的关键步骤

  1. 创建父工程:首先,需要创建一个Maven父工程。这个父工程本身也是一个Maven项目,但其主要目的是用来管理和构建其他子模块。在创建时,需要在pom.xml文件中指定打包方式为pom:<packaging>pom</packaging>。
  2. 创建子模块:在父工程下创建子模块。这些子模块可以是不同的功能模块,比如DAO层、Service层、Web层等。每个子模块都是一个独立的Maven项目,可以在其pom.xml文件中定义特定的依赖和配置。
  3. 配置子模块依赖:在子模块的pom.xml文件中,你可以添加对其他子模块或外部库的依赖。这样,各个模块就可以根据需要使用其他模块提供的功能或资源。
  4. 聚合模块的pom.xml配置:在父工程的pom.xml文件中,需要添加对各个子模块的引用。这通过在<modules>标签下添加子模块的名称来实现。

下面是一个Maven聚合工程的 pom.xml文件的基本结构

<project>
    ...  
    <groupId>com.mycompany</groupId>
    <artifactId>my-aggregator-project</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    
    <modules>
        <module>module-a</module>
        <module>module-b</module>
        <module>module-c</module>
    </modules>
    ...
</project>

<project> 是pom.xml文件的根元素,所有的配置都会在这个标签内
<groupId> 这个元素定义了项目组的ID,通常是开发者所在组织的反向域名
<artifactId> 这个元素定义了项目的ID,通常是项目名称
<version> 这个元素定义了项目的版本号
<packaging> 这个元素指定了Maven项目的打包方式。在这里,它被设置为pom,表示这个项目是一个聚合项目,它不会生成自己的构件(如jar或war),而是用来管理其他子模块
<modules> 这个元素包含了<module>子元素,每个子元素指定了一个子模块的目录名称。Maven会在这个列表中找到每个子模块的pom.xml文件,并按照它们声明的依赖关系顺序构建它们

在上面的例子中,my-aggregator-project是父项目,它聚合了三个子模块:module-amodule-bmodule-c。每个子模块都有自己的pom.xml文件,定义了该模块的具体配置,如依赖、插件和其他构建设置。
当你在父项目的目录中运行Maven命令(如mvn clean install)时,Maven会首先构建父项目,然后按照<modules>中定义的顺序依次构建所有子模块。这样,你就可以一次性构建整个项目,包括所有的子模块。

  • 引入新的元素 modeles-module

聚合案例

现在有 3 个模块

此时新建一个模块,命名为 maven_01_parent

此时项目结构如下:

设置其打包方式为 pom

设置管理的模块名称

maven_01_parent 已成为 root 工程

现对 maven_01_parent 使用 compile 指令

可以发现其余工程均参与了构建

注意:聚合工程中所包含的模块在进行构建时会根据模块间的依赖关系设置构建顺序,与聚合工程中模块的配置书写位置无关;参与聚合的工程无法向上感知是否参与聚合,只能向下配置哪些模块参与本工程的聚合。

5.8.2、 继承

概念:在Java开发中,使用Maven构建的项目可以创建模块化的结构,其中一个模块(子模块)可以继承另一个模块(父模块)的配置。
作用: ① 简化配置 ② 减少版本冲突

创建Maven聚合工程的关键步骤

  1. 创建父模块
    • 创建一个新的Maven项目,这将成为父模块。
    • 在父模块的pom.xml文件中,设置其打包方式为pom,表示它是一个父项目。
    • <packaging>pom</packaging>
  2. 配置父模块的pom.xml
    • 在父模块的pom.xml中定义项目的信息,如groupId和artifactId。
    • 定义项目的版本号。
    • 添加任何共享的依赖、插件配置、属性等。
  3. 创建子模块
    • 在父模块的项目中,通过Maven命令或IDE创建新的子模块。
    • <modules>标签中添加子模块的目录路径。
  4. 配置子模块的pom.xml
    • 在子模块的pom.xml中,使用<parent>标签指定父模块的信息,包括groupId、artifactId和版本。
    • 可以省略在子模块中与父模块相同的配置,如groupId和版本号,子模块会自动继承这些配置。
    • 添加子模块特有的依赖、插件配置等。
  5. 构建和测试模块
    • 使用Maven命令(如mvn clean install)构建父模块和子模块。
    • 运行测试用例来验证模块的功能。

继承案例

父模块的pom.xml

<project>
    <groupId>com.example</groupId>
    <artifactId>parent-project</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <modules>
        <module>child-module</module>
    </modules>
    <!-- 父模块的共享配置 -->
</project>

子模块的pom.xml

<project>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>parent-project</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>child-module</artifactId>
    <!-- 子模块特有的配置 -->
</project>

在这个例子中,child-moduleparent-project的子模块,它继承了父模块的配置。当构建parent-project时,Maven会自动构建它的子模块child-module。这样的结构有助于保持项目配置的一致性,并简化了构建过程。

dependencyManagement元素

在Maven中,<dependencyManagement>是一个用于在多模块项目中集中管理依赖项版本的元素。它允许你在父POM中 声明 依赖项的版本,而不用实际引入这些依赖。这样做的好处是,你可以在子模块中省略依赖的版本号,从而使得项目更加整洁,同时也减少了版本冲突的可能性。(父POM:是指在Maven项目中,作为其他子模块的父项目的POM文件)

<dependencyManagement>作用如下:

  1. 统一版本管理:在多模块项目中,可能会有多个模块依赖于相同的库,但是不同的模块可能由不同的人维护。使用<dependencyManagement>可以确保所有模块使用的是相同的版本,从而减少了因版本不一致导致的问题。
  2. 避免重复:在父POM中声明依赖项的版本后,子模块中就不需要再次声明版本号,只需要指定groupId和artifactId即可。这样,当需要升级依赖项的版本时,只需在父POM中更改一次即可。
  3. 灵活性:子模块可以选择性地继承父POM中声明的依赖项。这意味着子模块不是强制性地继承所有的依赖,而是可以根据自己的需要来决定是否继承某个依赖。
  4. 清晰性:通过在父POM中使用<dependencyManagement>,可以清楚地看到项目中使用了哪些依赖项以及它们的版本,这有助于项目的维护和审查。

下面是一个使用<dependencyManagement>例子

父模块的pom.xml

<project>
    <!-- ... 其他配置 ... -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>5.3.10</version>
            </dependency>
            <!-- 其他依赖项 -->
        </dependencies>
    </dependencyManagement>
    <!-- ... 其他配置 ... -->
</project>

子模块的pom.xml

<project>
    <!-- ... 其他配置 ... -->
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <!-- 不需要指定版本,因为已经在父模块的dependencyManagement中声明了 -->
        </dependency>
        <!-- 其他依赖项 -->
    </dependencies>
    <!-- ... 其他配置 ... -->
</project>

在这个例子中,子模块继承了父模块的spring-core依赖,但是没有指定版本号。子模块会自动使用父模块在<dependencyManagement>中声明的版本。如果子模块需要其他版本的spring-core,它可以在自己的<dependencies>中指定一个不同的版本,这将覆盖父模块中的版本声明。

注意:子工程使用父工程的可选依赖时,仅需要提供群组id和项目id,无需提供版本,版本由父工程统一提供,避免版本冲突;子工程还可以定义父工程中没有定义的依赖关系。

5.8.3、 聚合与继承的区别

  • 作用: ① 聚合用于快速构建项目 ② 继承用于快速配置
  • 相同点: ① 聚合与继承的pom.xml 文件打包方式均为 pom,可以将两种关系制作DAo同一个 pom 文件中 ② 聚合与继承均属于设计性模块,并未实际的模块内容
  • 不同点: ① 聚合是在当前模块中配置关系,聚合可以感知到参与聚合的模块有哪些 ② 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己

5.9、idea中创建Maven项目

Maven Archetype项目 屏幕截图 2024-07-05 161815.png 常规Maven项目 屏幕截图 2024-07-05 162018.png

5.9.1、 Maven Archetype、常规Maven项目和Jakarta EE Maven项目之间的主要区别:

Maven Archetype

  1. 初始模板:Maven Archetype提供了一系列预定义的项目模板,这些模板可以快速创建具有特定结构的项目,如Web应用程序、Java EE应用等。
  2. 项目结构:根据所选的Archetype,项目结构会自动生成,包括必要的目录、文件和初始代码。
  3. 技术栈:Archetype可能会预先包含某些技术栈的依赖,如Spring Boot、Jakarta EE等。
  4. 依赖管理:Archetype会自动在pom.xml文件中添加必要的依赖,但你仍然可以手动修改或添加依赖。
  5. 项目配置:Archetype会自动生成一些基本的配置,如数据库连接、Spring配置等,但你仍然需要进行一些手动配置。

常规Maven项目

  1. 初始模板:创建常规Maven项目时,你通常需要手动添加所有必要的目录、文件和初始代码。
  2. 项目结构:你需要手动创建目录和文件,并根据项目需求配置它们。
  3. 技术栈:创建常规Maven项目时,你需要手动添加所有需要的依赖,并配置项目的技术栈。
  4. 依赖管理:你需要手动管理所有依赖项,并在pom.xml文件中添加它们。
  5. 项目配置:你需要手动配置项目的所有细节,包括构建、部署等。

Jakarta EE Maven项目

  1. 初始模板:Jakarta EE Maven项目通常会提供一个预定义的模板,用于创建符合Jakarta EE规范的Web应用程序或企业级应用。
  2. 项目结构:项目结构会自动生成,包括必要的目录、文件和初始代码,如JPA实体、JSF页面等。
  3. 技术栈:Jakarta EE Maven项目会预先包含Jakarta EE技术的依赖,如JPA、JSF等。
  4. 依赖管理:Jakarta EE Maven项目会自动在pom.xml文件中添加必要的依赖,但你仍然可以手动修改或添加依赖。
  5. 项目配置:Jakarta EE Maven项目会自动生成一些基本的配置,如数据库连接、Jakarta EE规范配置等,但你仍然需要进行一些手动配置。

总结

  • 使用Maven Archetype可以更快地创建符合特定结构和配置的项目,特别是对于经常创建的项目类型,如Web应用程序或数据访问层。
  • 创建常规Maven项目提供了更高的灵活性,允许用户根据需要手动配置项目结构和依赖。
  • 使用Jakarta EE创建Maven项目时,重点在于选择或自定义包含Jakarta EE相关依赖和配置的Maven Archetype模板,以便快速构建企业级应用。

5.9.2、 创建Maven Archetype项目

1.首先点击new-->project

 2.填写相关项目名,存放的地址等

 3.创建后的效果

4.添加maven依赖,若依赖一直下载不下来,注意在setting中配置一下maven(根据自己的情况配置)以及jdk等

  根据自己的实际安装地址,进行maven相关配置

配置jdk

 配置jre

5.若创建下的maven项目没有Resource目录,则创建该目录

 找到main,右键,选择new Directory--->填写resources --->选中resources,右键选择Resources,点击ok即可

 6.最终完成效果图

5.9.3、 创建常规Maven项目

1.创建新项目

1.进入创建项目 File -> new -> project

2,project 中有 build system 选择maven

2.在已有项目中创建普通maven工程

1.右键项目选择 new -> Module

2.选择 new Module 其实与新建maven工程没什么区别

5.9.4、 创建Jakarta EE Maven项目

idea:New Project -> Jakarta EE

第一步:

第二步:create,创建完成。

创建完成后的项目结构如下:

5.9.5、 集成 Tomcat

在项目创建并配置好 Maven 依赖后需要集成 Tomcat

在IntelliJ IDEA(简称IDEA)中使用Tomcat主要有两种方式:集成本地的Tomcat服务器使用Tomcat的Maven插件。这两种方式各有特点,适用于不同的开发场景和需求。下面将详细介绍这两种方式的不同之处以及如何使用它们。

一、集成本地的Tomcat服务器

1. 使用步骤 屏幕截图 2024-07-05 162340.png

2. 特点与优势

  • 直观易操作:通过IDEA的图形界面直接配置和管理Tomcat服务器,无需离开IDE环境。
  • 快速部署:可以直接在IDEA中部署项目到Tomcat服务器,无需手动复制WAR文件到webapps目录。
  • 实时调试:支持在IDEA中直接对Tomcat上的Java Web应用程序进行调试,方便问题定位和修复。

3. .war 文件与"exploded" 目录区别

在 IntelliJ IDEA 中部署应用程序到 Apache Tomcat 服务器时,你通常会看到两个选项:部署“打包”的工件(通常是一个 .war 文件)和部署“展开”的工件(也称为 "exploded" 目录)。

  • 打包的工件(.war 文件):这是一个压缩的文件,包含了你的应用程序的所有编译后的类文件、资源、库和其他必要的文件。当你选择部署 .war 文件时,IDEA 会将应用程序打包成一个 .war 文件,并将其部署到 Tomcat 服务器。
  • 展开的工件(exploded 目录):这是一个未压缩的目录结构,与 .war 文件的内容相同,但是以目录的形式存在。当你选择部署 exploded 目录时,IDEA 会直接将应用程序的目录结构部署到 Tomcat 服务器,而不是先打包成 .war 文件。 选择哪一种方式取决于你的需求和偏好:
  • 使用 exploded 目录的优点
    • 更快的开发周期:由于不需要每次都打包成 .war 文件,部署和重新部署过程通常更快。
    • 热部署:某些情况下,对 exploded 目录的更改可以实时反映到运行中的应用程序中,无需重新部署。
    • 易于调试:可以直接访问部署的文件,便于查看和调试。
  • 使用打包的工件(.war 文件)的优点
    • 更接近生产环境:在生产环境中,通常会部署 .war 文件,因此这种方式可以模拟生产部署。
    • 更少的本地文件:如果你不希望项目目录中包含太多生成的内容,使用 .war 文件可以保持目录整洁。

对于大多数开发场景,特别是在开发阶段,推荐使用 exploded 目录,因为它提供了更快的迭代速度和更好的调试体验。在准备将应用程序部署到生产环境时,推荐使用 .war 文件进行部署,以确保与生产环境的部署过程一致。

二、使用Tomcat的Maven插件

1. 使用步骤

  1. 在项目的pom.xml文件中添加Tomcat Maven插件的配置

示例配置如下:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version><!-- 版本号可能需要根据实际情况调整 -->
            <configuration>
                <port>80</port><!--访问端口号,可选,默认为8080-->
                <path>/</path><!--项目访问路径,可选,默认为 /项目名-->
            </configuration>
        </plugin>
    </plugins>
</build>
  1. 使用Maven Helper 插件快速启动项目,选中项目,右键 --> Run Maven --> tomcat7:run
image.png

如果需要断点调试,选择 Debug Maven

image.png

关于一些其他问题

运行前要刷新maven:

  1. 鼠标右键点击项目名称。
  2. 在点击弹窗内的“Maven”行。
  3. 最后点击“Reimport”或“Reload project”即可!

安装Maven Helper 插件:在File-->Settings-->Plugins中搜索maven helper,安装后重启idea
报错:无法解析插件:尝试在Setting-Maven里配置本地的Maven仓库

报错的可能是之前手动配置的tomcat服务器没关 端口冲突了,停止运行就好了

1. 特点与优势

  • 自动化构建与部署:通过Maven插件实现项目的自动化构建和部署到Tomcat服务器。
  • 版本控制:Maven插件允许在pom.xml文件中明确指定Tomcat的版本和配置,便于版本控制和依赖管理。
  • 灵活性:可以在不同的开发环境中使用相同的Maven命令来构建和部署项目,提高开发效率。
总结

集成本地Tomcat服务器适合需要快速部署和调试的开发场景,而使用Maven插件则更适合于自动化构建和部署以及跨环境开发的场景。根据项目的具体需求和开发团队的偏好,可以选择适合的方式在IDEA中使用Tomcat。

都可以在浏览器中输入http://localhost:端口号/上下文路径/资源路径来访问部署在Tomcat上的Web应用。

5.10、Web项目结构

截图20240705161201.png

src/main/webapp用于存放Web相关的文件(如HTML、JSP、CSS、JavaScript等),src/test用于存放测试代码。

5.11、POM文件

5.11.1、 pom.xml内容结构

pom.xml是maven的核心配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!--maven版本和头文件-->
<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>

  <!--这里就是我们配置的gav-->
  <groupId>com.zyy</groupId>
  <artifactId>javaweb-maven</artifactId>
  <version>1.0-SNAPSHOT</version>
  <!--packaging  项目的方法方式
    jar:jar应用
    war:javaWeb应用
  -->
  <packaging>war</packaging>

  <name>javaweb-maven Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <!--配置-->
  <properties>
    <!--项目的默认构建编码-->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!--编码版本-->
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <!--项目依赖-->
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <!--项目构建用的东西-->
  <build>
    <finalName>javaweb-maven</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

maven的高级之初在于它会帮你导入这个jar包所依赖的其他jar包

maven由于他的约定大于配置,我们之后可能会遇到我们写的配置文件,无法被导出或者生效的问题,解决方案:

  <!--在build中配置resources,来防止我们资源导出失败的问题-->  
  <build> 
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  </build>

5.11.2、 pom.xml文件配置

一、pom文件三要素

建好Maven工程后,文件列表中会看到pom.xml文件

配置文件通过三要素来锁定一个工程:

①version(版本号)

②groupId(包名)

③artifactId(工程名)

<!--maven的版本号,目前3.0以上的maven工具,生成的都是4.0版本的模型-->
<modelVersion>4.0.0</modelVersion>

<!--包名全小写,域名倒写例如 com.Java或者域名倒写+项目名。例如 com.Java.test-->
<groupId>com.java</groupId>

<!--工程名-->
<artifactId>maven002</artifactId>

<!--工程版本号,版本号都是3位是1.0.0,SNAPSHOT:不稳定版-->
<version>1.0-SNAPSHOT</version>

<!--工程打包方式,可以 jar、war、rar、ear、pom,默认是 jar-->
<packaging>war</packaging>
二、pom文件中JDK资源配置

配置为1.8

<!--全局属性的配置-->
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>
三、pom文件中配置依赖管理

Maven可以根据三要素把需要的jar包依赖从本地仓库引入,并添加到war包中。

如果本地仓库没有,则去远程仓库下载到本地仓库。

从网站查询到需要引入的jar包三要素:Maven的jar包网站:https://mvnrepository.com/

我们想要导入mysql的依赖jar包,先进入网站查询MySQL

找到相关的jar包,点击进入选择版本

如果不太熟悉的话,可以选择使用量较多的版本

选择后,将下列代码复制进pom.xml文件

⑤复制到pom里面,点击更新会自动下载

依赖传递

如果当前jar包还需要依赖其他jar包,则maven也会帮助我们直接引入,且自动适应版本号

<!--此处只需要引入commons-fileupload.jar需要依赖的commons-io.jar会被自动引入-->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>
四、pom文件中build标签进行插件和资源管理

一般我们配置扫描资源文件就好了,插件不需要我们配置

 <build>
    <!--扫描文件资源-->
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
    </resources>

 <!--插件-->
 <pluginManagement><!-- lock down plugins versions to avoid 
 using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current
        /maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see 
        https://maven.apache.org/ref/current/maven-core/default-
        bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/
        maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

5.12、解决遇到的一些问题

  1. maven 3.6.2 报错:unable to import maven project:see logs for details 解决方法:降级为3.6.1
  2. tomcat闪退
  3. idea中每次都要重复配置maven 在idea中的全局默认配置中去配置
  1. maven项目中tomcat无法配置
  2. maven默认web项目中的web.xml版本问题

替换为webapp3.1版本和tomcat一致(看tomcat下的webapps里面的官方案例)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1"
         metadata-complete="true">

  <display-name>Welcome to Tomcat</display-name>

</web-app>
  1. maven仓库的使用 地址:mvnrepository.com/