Web:全球广域网,也称为万维网(www),能够通过浏览器访问的网站
JavaWeb: 是用 Java技术来解决相关web互联网领域的技术栈
JavaWeb 技术栈
-
B/S 架构:Browser/Server,浏览器/服务器 架构模式,它的特点是,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web资源,服务器把Web资源发送给浏览器即可
好处:易于维护升级:服务器端升级后,客户端无需任何部署就可以使用到新的版本
-
静态资源:HTML、CSS、JavaScript、图片等。负责页面展现
-
动态资源:Servlet、JSP 等。负责逻辑处理
-
数据库:负责存储数据
-
HTTP协议:定义通信规则
-
Web服务器:负责解析 HTTP 协议,解析请求数据,并发送响应数据
HTTP
概念:HyperText Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则
HTTP 协议特点:
- 基于TCP协议:面向连接,安全
- 基于请求-响应模型的:一次请求对应一次响应
- HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的。
- 缺点:多次请求间不能共享数据。Java中使用会话技术(Cookie、Session)来解决这个问题
- 优点:速度快
HTTP-请求数据格式
请求数据分为3部分:
- 请求行:请求数据的第一行。其中GET表示请求方式,/表示请求资源路径,HTTP/1.1表示协议版本
- 请求头:第二行开始,格式为key:value形式。
- 请求体: POST请求的最后一部分,存放请求参数
GET / HTTP/1.1
Host: www.itcast.cn
Connection: keep-alive
User-Agent: Mozilla/5.0 Chrome/91.0.4472.106
…
POST / HTTP/1.1
Host: www.itcast.cn
Connection: keep-alive
Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 Chrome/91.0.4472.106
username=superbaby&password=123456
GET请求和 POST请求区别:
-
GET请求请求参数在请求行中,没有请求体。
POST请求请求参数在请求体中
-
GET请求请求参数大小有限制,
POST没有
常见的HTTP 请求头:
- Host: 表示请求的主机名
- User-Agent: 浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0 … Chrome/79,IE浏览器的标识类似Mozilla/5.0 (Windows NT …) like Gecko;
- Accept:表示浏览器能接收的资源类型,如text/*,image/或者/*表示所有;
- Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页;
- Accept-Encoding:表示浏览器可以支持的压缩类型,例如gzip, deflate等。
HTTP-响应数据格式
响应数据分为3部分:
- 响应行:响应数据的第一行。其中HTTP/1.1表示协议版本,200表示响应状态码,OK表示状态码描述
- 响应头:第二行开始,格式为key:value形式
- 响应体: 最后一部分。存放响应数据
HTTP/1.1 200 OK
Server: Tengine
Content-Type: text/html
Transfer-Encoding: chunked…
<html>
<head>
<title></title>
</head>
<body></body>
</html>
常见的HTTP 响应头:
- Content-Type:表示该响应内容的类型,例如text/html,image/jpeg;
- Content-Length:表示该响应内容的长度(字节数);
- Content-Encoding:表示该响应压缩算法,例如gzip;
- Cache-Control:指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒
Web服务器 - Tomcat
Web服务器
Web服务器是一个应用程序(软件),对 HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷。主要功能是“提供网上信息浏览服务” 。
Tomcat
简介
- 概念: Tomcat是Apache软件基金会一个核心项目,是一个开源免费的轻量级Web服务器,支持Servlet/ISP少量JavaEE规范。
- JavaEE: Java Enterprise Edition,Java企业版。指Java企业级开发的技术规范总和。包含13项技术规范:JDBC、JNDI、EJB、RMI、JSP、Servlet、XML、JMS、Java lDL、JTS、JTA、JavaMail、JAF
- Tomcat 也被称为 Web容器、Servlet容器。Servlet 需要依赖于 Tomcat才能运行
- 官网:https://tomcat.apache.org/
基本使用:安装、卸载、启动、关闭、配置、部署项目
-
下载:官网下载
-
安装:绿色版,直接解压即可
-
卸载:直接删除目录即可
-
启动:双击:bin\startup.bat
-
Tomcat输出日志的编码为UTF-8,而Windows控制台为GBK,一般会出现乱码。
修改conf/ logging.properties
java.util.logging.ConsoleHandler.encoding = GBK
-
-
关闭:
- 直接×掉运行窗口:强制关闭
- bin\shutdown.bat:正常关闭
- Ctrl+C:正常关闭
-
配置:
修改启动端口号:conf/server.xml
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
注:HTTP协议默认端口号为80,如果将Tomcat端口号改为80,则将来访问Tomcat时,将不用输入端口号
-
Tomcat 部署项目:
将项目放置到 webapps 目录下, 即部署完成
一般 JavaWeb项目会被打成war包,然后将 war包放到 webapps目录下,Tomcat会自动解压缩 war文件
IDEA中创建Maven Web项目
Web项目结构
Maven Web项目结构:开发中的项目 :
部署的JavaWeb项目结构:开发完成,可以部署的项目 :
- 编译后的Java字节码文件和resources的资源文件,放到WEB-INF下的classes目录下
- pom.xml中依赖坐标对应的jar包,放入WEB-INF下的lib目录下
使用骨架创建
骨架:项目模板
创建一个新项目或模块,再点击Maven Archetype,在Archetype中选择。
org.apache.maven.archetypes:maven-archetype-webapp
点击Create创建完成。
可以发现,在main下没有Java目录,右键main,New,Directory,直接选择Java就行。
不适用骨架创建
创建一个新项目或模块:File->New -> Module…或者Project…
我这里创建一个模块,选择New Module,Build System选择Maven。
点击Create创建完成。
再pom.xml中编写打包方式:
<packaging>war</packaging>
然后要创建webapp目录,可以手动创建,也可以自动创建。
自动创建:打开Project Structure,选择Facets,右键Web,点击Add,选择Web,选择刚刚创建的项目。
修改Deployment Descriptors中的路径。
修改Web Resource Directories中的路径。
点击Apply,再点击OK即可。
IDEA中使用Tomcat
在IDEA中集成使用Tomcat有两种方式,分别是集成本地Tomcat和Tomcat Maven插件
集成本地Tomcat
点击Edit Congfigurations…,再点击+号,选择Tomcat Server、Local。
点击Application server后的configure…,选择Tomcat Home的路径。点击OK。
接下来是部署,切换到Deployment。点击Deploy at the server startup下的+号,再点击Artifact…,选择tomcat-deom:war 即可。
最后点击apply,再点击OK就完成了。
Tomcat Maven插件
在pom.xml中添加Tomcat插件,可以使用快捷键alt+(fn)+ins(ert)
<build>
<finalName>tomcat-deom</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
在项目中,右键->Run Maven -> tomcat7:run运行
Maven Tomcat插件目前只有Tomcat7版本,没有更高的版本可以使用
使用Maven Tomcat插件,要想修改Tomcat的端口和访问路径,可以直接修改pom.xml
<build>
<finalName>tomcat-deom</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8000</port><!--访问端口号 -->
<!--项目访问路径-->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
Servlet
Servlet是JavaWeb最为核心的内容,它是Java提供的一门动态web资源开发技术。
Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet。
快速入门
-
创建web项目,导入Servlet依赖坐标
... <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <!-- provided指的是在编译和测试过程中有效,最后生成的war包时不会加入 因为Tomcat的lib目录中已经有servlet-api这个jar包,如果在生成war包的时候生效就会和Tomcat中的jar包冲突,导致报错 --> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>web-demo</finalName> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> </plugin> </plugins> </build> </project>
-
创建:定义一个类,实现Servlet接口,并重写接口中的所有方法,并在service方法中输出一句话
public class ServletDemo1 implements Servlet { public void init(ServletConfig servletConfig) throws ServletException { } public ServletConfig getServletConfig() { return null; } public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("Servlet:Hello World!"); } public String getServletInfo() { return null; } public void destroy() { } }
-
配置:在类上使用@WebServlet注解,配置该Servlet的访问路径
@WebServlet("/demo1") public class ServletDemo1 implements Servlet { public void init(ServletConfig servletConfig) throws ServletException { } ... }
-
访问:启动Tomcat,浏览器输入URL访问该Servlet
Servlet执行流程
- 浏览器发出
http://localhost:8080/web-demo/demo1
请求,从请求中可以解析出三部分内容,分别是localhost:8080
、web-demo
、demo1
- 根据
localhost:8080
可以找到要访问的Tomcat Web服务器 - 根据
web-demo
可以找到部署在Tomcat服务器上的web-demo项目 - 根据
demo1
可以找到要访问的是项目中的哪个Servlet类,根据@WebServlet后面的值进行匹配
- 根据
- 找到ServletDemo1这个类后,Tomcat Web服务器就会为ServletDemo1这个类创建一个对象,然后调用对象中的service方法
- service方法中有ServletRequest和ServletResponse两个参数,ServletRequest封装的是请求数据,ServletResponse封装的是响应数据
Servlet生命周期
生命周期: 对象的生命周期指一个对象从被创建到被销毁的整个过程。
Servlet运行在Servlet容器(web服务器)中,其生命周期由容器来管理,分为4个阶段:
-
加载和实例化:默认情况下,当Servlet第一次被访问时,由容器创建Servlet对象
默认情况,Servlet会在第一次访问被容器创建。
也可以在服务器启动的时候来创建Servlet:
/* loadOnstartup的取值有两类情况 (1)负整数:第一次访问时创建Servlet对象 (2)0或正整数:服务器启动时创建Servlet对象,数字越小优先级越高 */ @WebServlet(urlPatterns = "/demo1",loadOnStartup = 1)
-
初始化:在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次
-
请求处理:每次请求Servlet时,Servlet容器都会调用Servlet的service()方法对请求进行处理
-
服务终止:当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法完成资源的释放。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收
可以在Terminal命令行中,使用mvn tomcat7:run
启动,然后再使用ctrl+c
关闭tomcat
package com.xlr.web;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet(urlPatterns = "/demo2",loadOnStartup = 1)
public class ServletDemo2 implements Servlet {
/**
* 初始化方法
* 1.调用时机:默认情况下,Servlet被第一次访问时,调用
* * loadOnStartup: 默认为-1,修改为0或者正整数,则会在服务器启动的时候,调用
* 2.调用次数: 1次
*/
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init...");
}
public ServletConfig getServletConfig() {
return null;
}
/**
* 提供服务
* 1.调用时机:每一次Servlet被访问时,调用
* 2.调用次数: 多次
*/
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Servlet:Hello World!");
}
public String getServletInfo() {
return null;
}
/**
* 销毁方法
* 1.调用时机:内存释放或者服务器关闭的时候,Servlet对象会被销毁,调用
* 2.调用次数: 1次
*/
public void destroy() {
System.out.println("destroy");
}
}
Servlet方法
- 初始化方法,在Servlet被创建时执行,只执行一次
void init(ServletConfig servletConfig)
- 提供服务方法, 每次Servlet被访问,都会调用该方法
void service(ServletRequest servletRequest, ServletResponse servletResponse)
- 销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet
void destroy()
剩下的两个方法是:
- 获取Servlet信息
String getServletInfo()
//该方法用来返回Servlet的相关信息,没有什么太大的用处,一般我们返回一个空字符串即可
public String getServletInfo() {
return "";
}
- 获取ServletConfig对象
ServletConfig getServletConfig()
Servlet体系结构
我们将来开发B/S架构的web项目,都是针对HTTP协议,所以我们自定义Servlet,会通过继承HttpServlet
@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//TODO GET 请求方式处理逻辑
System.out.println("get");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//TODO POST 请求方式处理逻辑
System.out.println("post");
}
}
-
要想发送一个GET请求,请求该Servlet,只需要通过浏览器发送
http://localhost:8080/web-demo/demo4
,就能看到doGet方法被执行了 -
要想发送一个POST请求,需要编写一个form表单来发送请求,在webapp下创建一个
a.html
页面,内容如下:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/web-demo/demo4" method="post"> <input name="username"><input type="submit"> </form> </body> </html>
启动测试,即可看到doPost方法被执行了。
前端发送GET和POST请求的时候,参数的位置不一致,GET请求参数在请求行中,POST请求参数在请求体中。为了能处理不同的请求方式,我们得在service方法中进行判断,然后写不同的业务处理。
@WebServlet(urlPatterns = "/demo5",loadOnStartup = 1)
public class ServletDemo5 implements Servlet {
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init...");
}
public ServletConfig getServletConfig() {
return null;
}
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//获取请求方式,根据不同的请求方式进行不同的业务处理
HttpServletRequest request = (HttpServletRequest) servletRequest;
//1. 获取请求方式
String method = request.getMethod();
//2. 判断
if ("GET".equals(method)) {
// get方式处理逻辑
} else if ("POST".equals(method)) {
// get方式处理逻辑
}
}
public String getServletInfo() {
return null;
}
public void destroy() {
System.out.println("destroy");
}
}
我们可以对Servlet接口进行继承封装,来简化代码开发。
package com.xlr.web;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class MyHttpServlet implements Servlet {
public void init(ServletConfig servletConfig) throws ServletException {
}
public ServletConfig getServletConfig() {
return null;
}
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//获取请求方式,根据不同的请求方式进行不同的业务处理
HttpServletRequest request = (HttpServletRequest) servletRequest;
//1. 获取请求方式
String method = request.getMethod();
//2. 判断
if ("GET".equals(method)) {
// get方式处理逻辑
doGet(request,servletResponse);
} else if ("POST".equals(method)) {
// get方式处理逻辑
doPost(request,servletResponse);
}
}
protected void doPost(ServletRequest req, ServletResponse res) {
}
protected void doGet(ServletRequest req, ServletResponse res) {
}
public String getServletInfo() {
return null;
}
public void destroy() {
}
}
有了MyHttpServlet这个类,以后我们再编写Servlet类的时候,只需要继承MyHttpServlet,重写父类中的doGet和doPost方法,就可以用来处理GET和POST请求的业务逻辑。
package com.xlr.web;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
@WebServlet("/demo")
public class ServletDemo extends MyHttpServlet{
@Override
protected void doPost(ServletRequest req, ServletResponse res) {
System.out.println("post...");
}
@Override
protected void doGet(ServletRequest req, ServletResponse res) {
System.out.println("get...");
}
}
Servlet urlPattern配置
Servlet要想被访问,必须配置其访问路径(urlPattern)
一个Servlet可以配置多个urlPattern
@WebServlet(urlPatterns = {
"/demo","/demo0"})
urlPattern配置规则:
-
精确匹配
- 配置路径:
@WebServlet("/demo5")
- 访问路径:
localhost:8030/web-demo/demo5
- 配置路径:
-
目录匹配
-
配置路径:
@WebServlet("/demo/*")
-
访问路径:
localhost:8030/web-demo/demo localhost:8030/web-demo/demo/abc localhost:8030/web-demo/demo/123 localhost:8030/web-demo/demo/abc/123
/*
代表的是零或多个层级访问目录,同时精确匹配优先级要高于目录匹配。
-
-
拓展名匹配
- 配置路径:
@WebServlet("*.do")
- 访问路径:
localhost:8030/web-demo/abc.do localhost:8030/web-demo/123.do
- 如果路径配置的不是扩展名,那么在路径的前面就必须要加
/
否则会报错 - 如果路径配置的是
*.do
,那么在*.do的前面不能加/
,否则会报错
- 配置路径:
-
任意匹配
-
配置路径:
@WebServlet("/") @WebServlet("/*")
-
访问路径:
localhost:8030/web-demo/abc localhost:8030/web-demo/123
当我们的项目中的Servlet配置了 “/”,会覆盖掉tomcat中的DefaultServlet
会引发请求静态资源的时候没有走默认的而是走了自定义的Servlet类,如:localhost:8030/web-demo/a.html无法被访问到
**DefaultServlet:**当其他的url-pattern都匹配不上时走这个Servlet
优先级为 精确匹配 > 目录匹配 > 扩展名匹配 > /* > /
-
XML配置方式编写Servlet
Servlet从3.0版本后开始支持注解配置,3.0版本前只支持XML配置文件的配置方法。
对于XML的配置步骤有两步:
-
编写Servlet类
-
在web.xml中配置该Servlet
<web-app> <display-name>Archetype Created Web Application</display-name> <!--Servleet全类名--> <servlet> <servlet-name>demo</servlet-name> <servlet-class>com.xlr.web.ServletDemo</servlet-class> </servlet> <!--Servlet访问路径--> <servlet-mapping> <!-- servlet的名称,要和上面的名称一致--> <servlet-name>demo</servlet-name> <url-pattern>/demo</url-pattern> </servlet-mapping> </web-app>