一 Servlet
Servlet (server applet) 是运行在服务端(tomcat)的Java小程序,是sun公司提供一套定义动态资源规范; 从代码层面上来讲Servlet就是一个接口
用来接收、处理客户端请求、响应给浏览器的动态资源。在整个Web应用中,Servlet主要负责接收处理请求、协同调度功能以及响应数据。我们可以把Servlet称为Web应用中的控制器
不是所有的JAVA类都能用于处理客户端请求,能处理客户端请求并做出响应的一套技术标准就是Servlet
Servlet是运行在服务端的,所以 Servlet必须在WEB项目中开发且在Tomcat这样的服务容器中运行
1.1 动态资源和静态资源
静态资源
-
无需在程序运行时通过代码运行生成的资源,在程序运行之前就写好的资源. 例如:html css js img ,音频文件和视频文件
动态资源
需要在程序运行时通过代码运行生成的资源,在程序运行之前无法确定的数据,运行时动态生成,例如Servlet,Thymeleaf ... ...
动态资源指的不是视图上的动画效果或者是简单的人机交互效果
请求响应与HttpServletRequest和HttpServletResponse之间的对应关系
2.servlet运行步骤
- tomcat接受到请求后,将请求报文的信息转换为一个HttpServletRequest对象,该对象中包含了请求中的所有信息。
- tomcat同时创建了一个HttpServletResponse对象,该对象用于承装要响应给客户端的信息,后面,该对象会被转化为响应的报文。
- tomcat根据请求中的资源路径找到对应的servlet,将servlet实例化,调用service方法,同时将HttpServletRequest和HttpServletResponse对象传入。
3. servlet开发流程
- 创建JavaWeb项目,同时将tomcat添加为当前项目的依赖
- 重写service方法
- 在service方法中,定义业务处理代码
- 在web.xml中,配置Servlet对应的请求映射路径
例:校验输入的用户名是否不为ergou
步骤1 开发一个web类型的module
步骤2 开发一个UserServlet
java文件
package com.ergou.servlet;import jakarta.servlet.Servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServlet;import java.io.IOException;
import java.io.PrintWriter;public class UserServlet extends HttpServlet {@Overridepublic void service(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws ServletException, IOException {
//从servletRequest对象中获取请求中的信息
String username = servletRequest.getParameter("username");//该方法是根据参数名获取参数值,即根据key获取value//处理业务的代码
String info = "YES";if("ergou".equals(username)){info = "NO";}
//将要响应的数据放入response
//应该设置Content-type响应头,也可以使用servletResponse.setContentType()
servletResponse.setHeader("Content-type","text/html");
PrintWriter writer = servletResponse.getWriter();//该方法返回的是一个向响应体中打印字符串的打印流
writer.write(info);writer.close();}
}
自定义一个类,要继承HttpServlet类
重写service方法,该方法主要就是用于处理用户请求的服务方法
HttpServletRequest 代表请求对象,是有请求报文经过tomcat转换而来的,通过该对象可以获取请求中的信息
HttpServletResponse 代表响应对象,该对象会被tomcat转换为响应的报文,通过该对象可以设置响应中的信息
Servlet对象的生命周期(创建,初始化,处理服务,销毁)是由tomcat管理的,无需我们自己new
HttpServletRequest HttpServletResponse 两个对象也是有tomcat负责转换,在调用service方法时传入给我们用的
步骤3 在web.xml为UseServlet配置请求的映射路径
web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="<https://jakarta.ee/xml/ns/jakartaee>"xmlns:xsi="<http://www.w3.org/2001/XMLSchema-instance>"xsi:schemaLocation="<https://jakarta.ee/xml/ns/jakartaee> <https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd>"version="5.0"><!--配置Servlet类,并起一个别名servlet-class 告诉Tomcat对应的要实例化的Servlet类servlet-name 用于关联请求的映射路径--><servlet><servlet-name>userServlet</servlet-name><servlet-class>com.ergou.servlet.UserServlet</servlet-class></servlet><!--servlet-mapping 用来设置对应servlet-name的映射路径--><servlet-mapping><servlet-name>userServlet</servlet-name><url-pattern>/userServlet</url-pattern></servlet-mapping><servlet-mapping><!--关联别名和映射路径--><servlet-name>userServlet</servlet-name><!--可以为一个Servlet匹配多个不同的映射路径,但是不同的Servlet不能使用相同的url-pattern--><url-pattern>/userServlet</url-pattern><!-- <url-pattern>/userServlet2</url-pattern>--><!--/ 表示通配所有资源,不包括jsp文件/* 表示通配所有资源,包括jsp文件/a/* 匹配所有以a前缀的映射路径*.action 匹配所有以action为后缀的映射路径--><!-- <url-pattern>/*</url-pattern>--></servlet-mapping>
</web-app>
Servlet并不是文件系统中实际存在的文件或者目录,所以为了能够请求到该资源,我们需要为其配置映射路径
servlet的请求映射路径配置在web.xml中
servlet-name作为servlet的别名,可以自己随意定义,见名知意就好
url-pattern标签用于定义Servlet的请求映射路径
一个servlet可以对应多个不同的url-pattern
多个servlet不能使用相同的url-pattern
url-pattern中可以使用一些通配写法
/ 表示通配所有资源,不包括jsp文件
/* 表示通配所有资源,包括jsp文件
/a/* 匹配所有以a前缀的映射路径
*.action 匹配所有以action为后缀的映射路径
步骤4 开发一个form表单,向servlet发送一个get请求并携带username参数
index.html文件:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form method="get" action="userServlet">用户名:<input type="text" name="username"> <br><input type="submit" value="校验">
</form>
</body>
</html>
Content-type的设置
Content-type响应头,决定响应报文的响应体会被客户端当作什么文件类型处理。
使用ServletResponse对象调用方法setContentType()
关于url-pattern
在web.xml中:
- servlet-class 告诉Tomcat对应的要实例化的Servlet类
- servlet-name 用于关联请求的映射路径
- servlet-mapping 用来设置对应servlet-name的映射路径
- url-pattern 用来设置路径名
注:
- 一个servlet-name可以对应多个url-pattern
- 一个servlet标签可以对应多个servlet-mapping标签
- 每个url-pattern设置的路径名不能重复
url-pattern的写法
精确匹配
格式:/路径名
要输入完全一样的路径名才能访问
模糊匹配
*作为通配符, *在哪里,哪里就是模糊不确定的
格式①:/
只有一个/符号,意味着无论后面的内容是什么,都认作为此路径,jsp文件除外
格式②:/*
无论后面的内容是什么,都认作为此路径,jsp文件不除外
格式③:/(字符或字符串)*
匹配前缀,以指定字符为开头的路径,即都认作此路径
格式④:*(字符或字符串)
匹配后缀,以指定字符为开头的路径,即都认作此路径
4.注解方式配置servlet
使用注解@WebServlet()即可快速配置路径名
参数直接写一个路径名格式的字符串即可(也可以是value=”路径名“或urlPattern=”路径名”),若要给一个servlet多个路径名,参数写value={”路径名1“,”路径名2“,……}( 或urlPattern={”路径名1“,”路径名2“,……} )
5.Servlet生命周期
- 实例化:即调用定义的Servlet类的构造器
- 初始化:调用init方法进行初始化
- 接受请求,处理请求:调用service方法
- 销毁:调用destory方法
5.1Servlet的生命周期
应用程序中的对象不仅在空间上有层次结构的关系,在时间上也会因为处于程序运行过程中的不同阶段而表现出不同状态和不同行为——这就是对象的生命周期。
简单的叙述生命周期,就是对象在容器中从开始创建到销毁的过程。
5.2Servlet容器
-
Servlet对象是Servlet容器创建的,生命周期方法都是由容器(目前我们使用的是Tomcat)调用的。这一点和我们之前所编写的代码有很大不同。在今后的学习中我们会看到,越来越多的对象交给容器或框架来创建,越来越多的方法由容器或框架来调用,开发人员要尽可能多的将精力放在业务逻辑的实现上。
5.3Servlet主要的生命周期执行特点
生命周期 | 对应方法 | 执行时机 | 执行次数 |
---|---|---|---|
构造对象 | 构造器 | 第一次请求或者容器启动 | 1 |
初始化 | init() | 构造完毕后 | 1 |
处理服务 | service(HttpServletRequest req,HttpServletResponse resp) | 每次请求 | 多次 |
销毁 | destory() | 容器关闭 | 1 |
于load-on-startup
load-on-startup默认为-1,如果是-1,即默认tomcat启动时不会实例化该servlet
如果是正整数则表示容器在启动时就要实例化Servlet,数字表示的是实例化的顺序
load-on-up的赋值可以在注解@WebServlet()中赋值,若要赋值为6,参数列表为(value=“路径名”,loadOnStartup = 6
也可以在web.xml文件中赋值,例:
<servlet><servlet-name>servletLifeCycle</servlet-name><servlet-class>com.atguigu.servlet.ServletLifeCycle</servlet-class><!--load-on-startup如果配置的是正整数则表示容器在启动时就要实例化Servlet,数字表示的是实例化的顺序--><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>servletLifeCycle</servlet-name><url-pattern>/servletLiftCycle</url-pattern></servlet-mapping>
java文件
@WebServlet("/servletLifeCycle")
public class ServletLifeCycle extends HttpServlet {/*生命周期 对应方法 执行时机 执行次数| 构造对象(实例化) | 构造器 | 第一次请求或者容器启动 | 1| 初始化 | init() | 构造完毕后 | 1| 处理服务 接受请求 | service(HttpServletRequest req,HttpServletResponse resp) | 每次请求 | 多次| 销毁 | destory() | 容器关闭 | 1生命周期总结1. 通过生命周期测试我们发现Servlet对象在容器中是单例的2. 容器是可以处理并发的用户请求的,每个请求在容器中都会开启一个线程3. 多个线程可能会使用相同的Servlet对象,所以在Servlet中,我们不要轻易定义一些容易经常发生修改的成员变量4. load-on-startup中定义的正整数表示实例化顺序,如果数字重复了,容器会自行解决实例化顺序问题,但是应该避免重复5. Tomcat容器中,已经定义了一些随系统启动实例化的servlet,我们自定义的servlet的load-on-startup尽量不要占用数字1-5default-servlet 当和所有servlet后,匹配不到路径时,执行default-servlet*/public ServletLifeCycle(){System.out.println("构造器");}@Overridepublic void init() throws ServletException {System.out.println("初始化方法");}@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("service方法");}@Overridepublic void destroy() {System.out.println("销毁方法");}
}
5.4生命周期总结
通过生命周期测试我们发现Servlet对象在容器中是单例的
容器是可以处理并发的用户请求的,每个请求在容器中都会开启一个线程
多个线程可能会使用相同的Servlet对象,所以在Servlet中,我们不要轻易定义一些容易经常发生修改的成员变量
load-on-startup中定义的正整数表示实例化顺序,如果数字重复了,容器会自行解决实例化顺序问题,但是应该避免重复
Tomcat容器中,已经定义了一些随系统启动实例化的servlet,我们自定义的servlet的load-on-startup尽量不要占用数字1-5
6 Servlet继承结构
6.1Servlet 接口
源码
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;public interface Servlet {/*** 初始化 Servlet,在第一次请求时调用。* * @param config ServletConfig 对象,包含了 Servlet 的初始化参数* @throws ServletException 如果发生 Servlet 异常*/void init(ServletConfig config) throws ServletException;/*** 获取 Servlet 配置。* * @return ServletConfig 对象*/ServletConfig getServletConfig();/*** 处理客户端请求。* * @param req ServletRequest 对象,代表客户端的请求* @param res ServletResponse 对象,代表服务器端的响应* @throws ServletException 如果发生 Servlet 异常* @throws IOException 如果发生 I/O 异常*/void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;/*** 返回 Servlet 的信息。* * @return Servlet 的信息*/String getServletInfo();/*** 销毁 Servlet,在 Servlet 被移除时调用。*/void destroy();
}
方法说明
init(ServletConfig config): 初始化 Servlet。这个方法在 Servlet 第一次被请求时调用,并且只调用一次。
ServletConfig
对象包含了 Servlet 的初始化参数。getServletConfig(): 返回一个
ServletConfig
对象,该对象包含了 Servlet 的配置信息。service(ServletRequest req, ServletResponse res): 处理客户端的请求。这个方法会根据请求的类型(GET、POST 等)来调用适当的方法(如
doGet
或doPost
)。ServletRequest
和ServletResponse
对象分别代表客户端的请求和服务器端的响应。getServletInfo(): 返回一个字符串,包含关于 Servlet 的信息,如作者、版本等。
destroy(): 销毁 Servlet。当 Servlet 被移除时调用,用于释放资源。
扩展接口
Servlet
接口通常由GenericServlet
类实现,而GenericServlet
类又实现了ServletConfig
接口。HttpServlet
类则进一步扩展了GenericServlet
,并提供了处理 HTTP 请求的方法(如doGet
和doPost
)。
Servlet 规范接口,所有的Servlet必须实现
public void init(ServletConfig config) throws ServletException;
初始化方法,容器在构造servlet对象后,自动调用的方法,容器负责实例化一个ServletConfig对象,并在调用该方法时传入
ServletConfig对象可以为Servlet 提供初始化参数
public ServletConfig getServletConfig();
获取ServletConfig对象的方法,后续可以通过该对象获取Servlet初始化参数
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
处理请求并做出响应的服务方法,每次请求产生时由容器调用
容器创建一个ServletRequest对象和ServletResponse对象,容器在调用service方法时,传入这两个对象
public String getServletInfo();
获取ServletInfo信息的方法
public void destroy();
Servlet实例在销毁之前调用的方法
6.2GenericServlet 抽象类
源码
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;public abstract class GenericServlet implements Servlet {private ServletConfig config;/*** 初始化 Servlet。* * @param config ServletConfig 对象,包含了 Servlet 的初始化参数* @throws ServletException 如果发生 Servlet 异常*/@Overridepublic void init(ServletConfig config) throws ServletException {this.config = config;this.init(); // 调用子类的 init 方法}/*** 子类可以重写这个方法来进行初始化操作。* * @throws ServletException 如果发生 Servlet 异常*/protected void init() throws ServletException {// 子类可以重写这个方法来进行初始化操作}/*** 返回一个 ServletConfig 对象,该对象包含了 Servlet 的配置信息。* * @return ServletConfig 对象*/@Overridepublic ServletConfig getServletConfig() {return config;}/*** 处理客户端的请求。* * @param req ServletRequest 对象,代表客户端的请求* @param res ServletResponse 对象,代表服务器端的响应* @throws ServletException 如果发生 Servlet 异常* @throws IOException 如果发生 I/O 异常*/@Overridepublic abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;/*** 返回一个字符串,包含关于 Servlet 的信息,如作者、版本等。* * @return Servlet 的信息*/@Overridepublic String getServletInfo() {return "";}/*** 销毁 Servlet,在 Servlet 被移除时调用。* * @throws ServletException 如果发生 Servlet 异常*/@Overridepublic void destroy() {// 子类可以重写这个方法来进行清理操作}// 其他辅助方法/*** 返回指定名称的初始化参数的值。* * @param name 初始化参数的名称* @return 初始化参数的值*/protected String getInitParameter(String name) {return config.getInitParameter(name);}/*** 返回一个包含所有初始化参数名称的枚举。* * @return 初始化参数名称的枚举*/protected Enumeration<String> getInitParameterNames() {return config.getInitParameterNames();}/*** 返回一个 ServletContext 对象,该对象代表了 Servlet 的运行环境。* * @return ServletContext 对象*/protected ServletContext getServletContext() {return config.getServletContext();}
}
方法说明
init(ServletConfig config): 初始化 Servlet。这个方法在 Servlet 第一次被请求时调用,并且只调用一次。
ServletConfig
对象包含了 Servlet 的初始化参数。getServletConfig(): 返回一个
ServletConfig
对象,该对象包含了 Servlet 的配置信息。service(ServletRequest req, ServletResponse res): 处理客户端的请求。这个方法会根据请求的类型(GET、POST 等)来调用适当的方法(如
doGet
或doPost
)。ServletRequest
和ServletResponse
对象分别代表客户端的请求和服务器端的响应。getServletInfo(): 返回一个字符串,包含关于 Servlet 的信息,如作者、版本等。
destroy(): 销毁 Servlet。当 Servlet 被移除时调用,用于释放资源。
getInitParameter(String name): 返回指定名称的初始化参数的值。
getInitParameterNames(): 返回一个包含所有初始化参数名称的枚举。
getServletContext(): 返回一个
ServletContext
对象,该对象代表了 Servlet 的运行环境。扩展
GenericServlet
是一个抽象类,它没有实现service
方法。因此,任何继承GenericServlet
的类都必须实现service
方法。然而,GenericServlet
提供了一些辅助方法,如getInitParameter
和getServletContext
,这些方法可以在子类中使用。
GenericServlet 抽象类是对Servlet接口一些固定功能的粗糙实现,以及对service方法的再次抽象声明,并定义了一些其他相关功能方法
private transient ServletConfig config;
初始化配置对象作为属性
public GenericServlet() { }
构造器,为了满足继承而准备
public void destroy() { }
销毁方法的平庸实现
public String getInitParameter(String name)
获取初始参数的快捷方法
public Enumeration<String> getInitParameterNames()
返回所有初始化参数名的方法
public ServletConfig getServletConfig()
获取初始Servlet初始配置对象ServletConfig的方法
public ServletContext getServletContext()
获取上下文对象ServletContext的方法
public String getServletInfo()
获取Servlet信息的平庸实现
public void init(ServletConfig config) throws ServletException()
初始化方法的实现,并在此调用了init的重载方法
public void init() throws ServletException
重载init方法,为了让我们自己定义初始化功能的方法
public void log(String msg)
public void log(String message, Throwable t)
打印日志的方法及重载
public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
服务方法再次声明
public String getServletName()
获取ServletName的方法
6.3HttpServlet 抽象类
源码
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public abstract class HttpServlet extends GenericServlet {@Overridepublic void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {HttpServletRequest request;HttpServletResponse response;try {request = (HttpServletRequest) req;response = (HttpServletResponse) res;} catch (ClassCastException e) {throw new ServletException("non-HTTP request or response");}service(request, response);}/*** 处理 HTTP 请求。* * @param req HttpServletRequest 对象,代表客户端的请求* @param resp HttpServletResponse 对象,代表服务器端的响应* @throws ServletException 如果发生 Servlet 异常* @throws IOException 如果发生 I/O 异常*/protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String method = req.getMethod();if (method.equals("GET")) {doGet(req, resp);} else if (method.equals("POST")) {doPost(req, resp);} else if (method.equals("PUT")) {doPut(req, resp);} else if (method.equals("DELETE")) {doDelete(req, resp);} else if (method.equals("HEAD")) {doHead(req, resp);} else if (method.equals("OPTIONS")) {doOptions(req, resp);} else if (method.equals("TRACE")) {doTrace(req, resp);} else {// 处理未知 HTTP 方法resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, "HTTP method " + method + " not supported");}}/*** 处理 GET 请求。* * @param req HttpServletRequest 对象,代表客户端的请求* @param resp HttpServletResponse 对象,代表服务器端的响应* @throws ServletException 如果发生 Servlet 异常* @throws IOException 如果发生 I/O 异常*/protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {throw new ServletException("HTTP GET not supported");}/*** 处理 POST 请求。* * @param req HttpServletRequest 对象,代表客户端的请求* @param resp HttpServletResponse 对象,代表服务器端的响应* @throws ServletException 如果发生 Servlet 异常* @throws IOException 如果发生 I/O 异常*/protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {throw new ServletException("HTTP POST not supported");}/*** 处理 PUT 请求。* * @param req HttpServletRequest 对象,代表客户端的请求* @param resp HttpServletResponse 对象,代表服务器端的响应* @throws ServletException 如果发生 Servlet 异常* @throws IOException 如果发生 I/O 异常*/protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {throw new ServletException("HTTP PUT not supported");}/*** 处理 DELETE 请求。* * @param req HttpServletRequest 对象,代表客户端的请求* @param resp HttpServletResponse 对象,代表服务器端的响应* @throws ServletException 如果发生 Servlet 异常* @throws IOException 如果发生 I/O 异常*/protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {throw new ServletException("HTTP DELETE not supported");}/*** 处理 HEAD 请求。* * @param req HttpServletRequest 对象,代表客户端的请求* @param resp HttpServletResponse 对象,代表服务器端的响应* @throws ServletException 如果发生 Servlet 异常* @throws IOException 如果发生 I/O 异常*/protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {throw new ServletException("HTTP HEAD not supported");}/*** 处理 OPTIONS 请求。* * @param req HttpServletRequest 对象,代表客户端的请求* @param resp HttpServletResponse 对象,代表服务器端的响应* @throws ServletException 如果发生 Servlet 异常* @throws IOException 如果发生 I/O 异常*/protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {throw new ServletException("HTTP OPTIONS not supported");}/*** 处理 TRACE 请求。* * @param req HttpServletRequest 对象,代表客户端的请求* @param resp HttpServletResponse 对象,代表服务器端的响应* @throws ServletException 如果发生 Servlet 异常* @throws IOException 如果发生 I/O 异常*/protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {throw new ServletException("HTTP TRACE not supported");}// 其他辅助方法
}
方法说明
service(ServletRequest req, ServletResponse res): 处理客户端的请求。这个方法会根据请求的类型(GET、POST 等)来调用适当的方法(如
doGet
或doPost
)。ServletRequest
和ServletResponse
对象分别代表客户端的请求和服务器端的响应。service(HttpServletRequest req, HttpServletResponse resp): 处理 HTTP 请求。这个方法会根据请求的方法(GET、POST 等)来调用适当的方法(如
doGet
或doPost
)。doGet(HttpServletRequest req, HttpServletResponse resp): 处理 GET 请求。子类可以重写这个方法来处理 GET 请求。
doPost(HttpServletRequest req, HttpServletResponse resp): 处理 POST 请求。子类可以重写这个方法来处理 POST 请求。
doPut(HttpServletRequest req, HttpServletResponse resp): 处理 PUT 请求。子类可以重写这个方法来处理 PUT 请求。
doDelete(HttpServletRequest req, HttpServletResponse resp): 处理 DELETE 请求。子类可以重写这个方法来处理 DELETE 请求。
doHead(HttpServletRequest req, HttpServletResponse resp): 处理 HEAD 请求。子类可以重写这个方法来处理 HEAD 请求。
doOptions(HttpServletRequest req, HttpServletResponse resp): 处理 OPTIONS 请求。子类可以重写这个方法来处理 OPTIONS 请求。
doTrace(HttpServletRequest req, HttpServletResponse resp): 处理 TRACE 请求。子类可以重写这个方法来处理 TRACE 请求。
扩展
HttpServlet
是一个抽象类,它没有实现service
方法。因此,任何继承HttpServlet
的类都必须实现service
方法。然而,HttpServlet
提供了一些处理 HTTP 请求的方法,如doGet
和doPost
,这些方法可以在子类中使用。
abstract class HttpServlet extends GenericServlet HttpServlet抽象类,除了基本的实现以外,增加了更多的基础功能
private static final String METHOD_DELETE = "DELETE";
private static final String METHOD_HEAD = "HEAD";
private static final String METHOD_GET = "GET";
private static final String METHOD_OPTIONS = "OPTIONS";
private static final String METHOD_POST = "POST";
private static final String METHOD_PUT = "PUT";
private static final String METHOD_TRACE = "TRACE";
上述属性用于定义常见请求方式名常量值
public HttpServlet() {}
构造器,用于处理继承
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
对服务方法的实现
在该方法中,将请求和响应对象转换成对应HTTP协议的HttpServletRequest HttpServletResponse对象
调用重载的service方法
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
重载的service方法,被重写的service方法所调用
在该方法中,通过请求方式判断,调用具体的do***方法完成请求的处理
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
对应不同请求方式的处理方法
除了doOptions和doTrace方法,其他的do*** 方法都在故意响应错误信息
6.4 自定义Servlet
继承关系图解
注意
-
自定义Servlet中,必须要对处理请求的方法进行重写
-
要么重写service方法
-
要么重写doGet/doPost方法
-
7.ServletConfig和ServletContext
7.1 ServletConfig的使用
为Servlet提供初始配置参数的一种对象,每个Servlet都有自己独立唯一的ServletConfig对象
容器会为每个Servlet实例化一个ServletConfig对象,并通过Servlet生命周期的init方法传入给Servlet作为属性
源码
import java.util.Enumeration;public interface ServletConfig {/*** 返回 Servlet 的名称。* * @return Servlet 的名称*/String getServletName();/*** 返回一个 ServletContext 对象,该对象代表了 Servlet 的运行环境。* * @return ServletContext 对象*/ServletContext getServletContext();/*** 返回指定名称的初始化参数的值。* * @param name 初始化参数的名称* @return 初始化参数的值*/String getInitParameter(String name);/*** 返回一个包含所有初始化参数名称的枚举。* * @return 初始化参数名称的枚举*/Enumeration<String> getInitParameterNames();
}
方法说明
getServletName(): 返回 Servlet 的名称。
getServletContext(): 返回一个
ServletContext
对象,该对象代表了 Servlet 的运行环境。getInitParameter(String name): 返回指定名称的初始化参数的值。
getInitParameterNames(): 返回一个包含所有初始化参数名称的枚举。
方法名 作用 getServletName() 获取<servlet-name>HelloServlet</servlet-name>定义的Servlet名称 getServletContext() 获取ServletContext对象 getInitParameter() 获取配置Servlet时设置的『初始化参数』,根据名字获取值 getInitParameterNames() 获取所有初始化参数名组成的Enumeration对象
ServletConfig 的使用
-
定义Servlet
public class ServletA extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletConfig servletConfig = this.getServletConfig();// 根据参数名获取单个参数String value = servletConfig.getInitParameter("param1");System.out.println("param1:"+value);// 获取所有参数名Enumeration<String> parameterNames = servletConfig.getInitParameterNames();// 迭代并获取参数名while (parameterNames.hasMoreElements()) {String paramaterName = parameterNames.nextElement();System.out.println(paramaterName+":"+servletConfig.getInitParameter(paramaterName));}} }public class ServletB extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletConfig servletConfig = this.getServletConfig();// 根据参数名获取单个参数String value = servletConfig.getInitParameter("param1");System.out.println("param1:"+value);// 获取所有参数名Enumeration<String> parameterNames = servletConfig.getInitParameterNames();// 迭代并获取参数名while (parameterNames.hasMoreElements()) {String paramaterName = parameterNames.nextElement();System.out.println(paramaterName+":"+servletConfig.getInitParameter(paramaterName));}} }
配置Servlet
<servlet><servlet-name>ServletA</servlet-name><servlet-class>com.atguigu.servlet.ServletA</servlet-class><!--配置ServletA的初始参数--><init-param><param-name>param1</param-name><param-value>value1</param-value></init-param><init-param><param-name>param2</param-name><param-value>value2</param-value></init-param></servlet><servlet><servlet-name>ServletB</servlet-name><servlet-class>com.atguigu.servlet.ServletB</servlet-class><!--配置ServletB的初始参数--><init-param><param-name>param3</param-name><param-value>value3</param-value></init-param><init-param><param-name>param4</param-name><param-value>value4</param-value></init-param></servlet><servlet-mapping><servlet-name>ServletA</servlet-name><url-pattern>/servletA</url-pattern></servlet-mapping><servlet-mapping><servlet-name>ServletB</servlet-name><url-pattern>/servletB</url-pattern></servlet-mapping>
7.2 ServletContext的使用
ServletContext对象有称呼为上下文对象,或者叫应用域对象(后面统一讲解域对象)
容器会为每个app创建一个独立的唯一的ServletContext对象
ServletContext对象为所有的Servlet所共享
ServletContext可以为所有的Servlet提供初始配置参数
7.3ServletContext源码
package javax.servlet;import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Set;/*** 定义了 Servlet 上下文(也就是 Web 应用程序的全局信息)的接口。* 每个 Web 应用程序都有一个 ServletContext 对象,它在 Web 应用启动时创建,* 并在 Web 应用停止时销毁。ServletContext 对象提供了一种在 Web 应用程序中* 存储和共享数据的机制。*/
public interface ServletContext {/*** 获取 Web 应用程序的上下文路径。* 例如,如果应用部署在 Tomcat 的 webapps 目录下的 demo 应用,返回的就是 "/demo"。* 如果部署在 ROOT 目录下,则返回空字符串 ""。*/String getContextPath();/*** 根据资源的路径返回其 Servlet 上下文。* 例如,如果当前应用是 demo,要访问 servlet 容器中的另一个应用 test 中的资源 index.jsp,* 假使资源的路径为 /test/index.jsp,那么可以通过调用 getContext("/test/index.jsp") 获取 test 应用的上下文。* 如果在 servlet 容器中找不到该资源或者该资源限制了外部的访问,则方法返回 null。*/ServletContext getContext(String uripath);/*** 获取当前 servlet 容器支持的 servlet 规范的最高版本。*/int getMajorVersion();/*** 获取当前 servlet 容器支持的 servlet 规范的最低版本。*/int getMinorVersion();/*** 返回文件的 MIME 类型,MIME 类型是容器配置的,可以通过 web.xml 进行配置。*/String getMimeType(String file);/*** 设置一个请求参数。*/void setAttribute(String name, Object value);/*** 获取一个请求参数。*/Object getAttribute(String name);/*** 获取所有请求参数的名称。*/Enumeration<String> getAttributeNames();/*** 移除一个请求参数。*/void removeAttribute(String name);/*** 获取 Servlet 容器的实实际路径。* 可以将一个虚拟路径转换为服务器上的物理路径,这对于文件操作非常有用。*/String getRealPath(String path);/*** 获取 Servlet 容器提供的资源。* @param path 相对于 Servlet 上下文的资源路径* @return 资源的 InputStream,如果找不到资源则返回 null* @throws MalformedURLException 如果路径无效*/InputStream getResourceAsStream(String path) throws MalformedURLException;/*** 获取相对于 Servlet 上下文的资源的 URL。* @param path 资源的路径* @return 资源的 URL,如果找不到资源则返回 null*/URL getResource(String path);/*** 获取 Web 应用程序的初始化参数。* @param name 参数名* @return 对应的参数值,如果没有设置则返回 null*/String getInitParameter(String name);/*** 获取所有初始化参数的名称。* @return 一个 Enumeration,包含所有的参数名称*/Enumeration<String> getInitParameterNames();/*** 获取 Servlet 上下文的名称。*/String getServletContextName();// ... 更多方法 .../*** 获取 Servlet 容器的相关信息,例如服务器信息。*/String getServerInfo();/*** 将 Servlet 上下文与一个登录的会话绑定。* @param session 要绑定的会话* @throws IllegalStateException 如果 Servlet 上下文已经被另一个会话绑定*/void login(String username, String password) throws ServletException;/*** 将 Servlet 上下文与一个登录的会话解绑。*/void logout();// ... 更多方法 ...}
7.4ServletContext其他重要API
获取资源的真实路径
String realPath = servletContext.getRealPath("资源在web目录中的路径");
-
例如我们的目标是需要获取项目中某个静态资源的路径,不是工程目录中的路径,而是部署目录中的路径;我们如果直接拷贝其在我们电脑中的完整路径的话其实是有问题的,因为如果该项目以后部署到公司服务器上的话,路径肯定是会发生改变的,所以我们需要使用代码动态获取资源的真实路径. 只要使用了servletContext动态获取资源的真实路径,那么无论项目的部署路径发生什么变化,都会动态获取项目运行时候的实际路径,所以就不会发生由于写死真实路径而导致项目部署位置改变引发的路径错误问题
获取项目的上下文路径
String contextPath = servletContext.getContextPath();
-
项目的部署名称,也叫项目的上下文路径,在部署进入tomcat时所使用的路径,该路径是可能发生变化的,通过该API动态获取项目真实的上下文路径,可以帮助我们解决一些后端页面渲染技术或者请求转发和响应重定向中的路径问题
域对象的相关API
域对象: 一些用于存储数据和传递数据的对象,传递数据不同的范围,我们称之为不同的域,不同的域对象代表不同的域,共享数据的范围也不同
ServletContext代表应用,所以ServletContext域也叫作应用域,是webapp中最大的域,可以在本应用内实现数据的共享和传递
webapp中的三大域对象,分别是应用域,会话域,请求域
后续我们会将三大域对象统一进行讲解和演示
,三大域对象都具有的API如下
API | 功能解释 |
---|---|
void setAttribute(String key,Object value); | 向域中存储/修改数据 |
Object getAttribute(String key); | 获得域中的数据 |
void removeAttribute(String key); | 移除域中的数据 |
@WebServlet("/servlet04")
public class Servlet4 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//行相关 GET/POST uri http/1.1System.out.println(req.getMethod());//获取请求方式System.out.println(req.getScheme());//获取请求协议System.out.println(req.getProtocol());//获取请求方式System.out.println(req.getRequestURI());//获取请求的uri项目内的资源路径System.out.println(req.getRequestURL());//获取请求的urL项目内资源的完成的路径/*URI统一资源标识符 /demo03/a.html interface URI{} 资源定位的要求和规范 动物类URL统一资源定位符 http://IP:port/domo03/a.html cLass URL impLements URI{} 一个具体的资源路径 哺乳动物类*/System.out.println(req.getLocalPort());//本应用容器的端口号System.out.println(req.getRemotePort());//客户端发请求时使用的System.out.println(req.getRemotePort());//端口号客户端软件的端口号//头相关 key : value key : value ......//根据名字单独获取某个请求头String accept = req.getHeader("Accept");System.out.println("Accept"+accept);//获取本次请求中所有的请求头的名字Enumeration<String> headerNames = req.getHeaderNames();while (headerNames.hasMoreElements()){String hname = headerNames.nextElement();System.out.println(hname+":"+req.getHeader(hname));}}
}
8 HttpServletRequest
8.1HttpServletRequest
HttpServletRequest是一个接口,其父接口是ServletRequest
HttpServletRequest是Tomcat将请求报文转换封装而来的对象,在Tomcat调用service方法时传入
HttpServletRequest代表客户端发来的请求,所有请求中的信息都可以通过该对象获得
8.2 HttpServletRequest常见API
-
获取请求行信息相关(方式,请求的url,协议及版本)
API | 功能解释 |
---|---|
StringBuffer getRequestURL(); | 获取客户端请求的url |
String getRequestURI(); | 获取客户端请求项目中的具体资源 |
int getServerPort(); | 获取客户端发送请求时的端口 |
int getLocalPort(); | 获取本应用在所在容器的端口 |
int getRemotePort(); | 获取客户端程序的端口 |
String getScheme(); | 获取请求协议 |
String getProtocol(); | 获取请求协议及版本号 |
String getMethod(); | 获取请求方式 |
-
获得请求头信息相关
API | 功能解释 |
---|---|
String getHeader(String headerName); | 根据头名称获取请求头 |
Enumeration<String> getHeaderNames(); | 获取所有的请求头名字 |
String getContentType(); | 获取content-type请求头 |
-
获得请求参数相关
API | 功能解释 |
---|---|
String getParameter(String parameterName); | 根据请求参数名获取请求单个参数值 |
String[] getParameterValues(String parameterName); | 根据请求参数名获取请求多个参数值数组 |
Enumeration<String> getParameterNames(); | 获取所有请求参数名 |
Map<String, String[]> getParameterMap(); | 获取所有请求参数的键值对集合 |
BufferedReader getReader() throws IOException; | 获取读取请求体的字符输入流 |
ServletInputStream getInputStream() throws IOException; | 获取读取请求体的字节输入流 |
int getContentLength(); | 获得请求体长度的字节数 |
-
其他API
API | 功能解释 |
---|---|
String getServletPath(); | 获取请求的Servlet的映射路径 |
ServletContext getServletContext(); | 获取ServletContext对象 |
Cookie[] getCookies(); | 获取请求中的所有cookie |
HttpSession getSession(); | 获取Session对象 |
void setCharacterEncoding(String encoding) ; | 设置请求体字符集 |
@WebServlet("/servlet05")
public class Servlet05 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取键值对形式的参数//根据参数名获取个参数值String username = req.getParameter("username");System.out.println(username);String userPWD = req.getParameter("userPWD");System.out.println(userPWD);//根据参数名获取多个参数值String[] hobbies = req.getParameterValues("hobby");System.out.println(hobbies);//获取所有的参数名Enumeration<String> parameterNames = req.getParameterNames();while (parameterNames.hasMoreElements()) {String pname = parameterNames.nextElement();String[] values = req.getParameterValues(pname);if (values.length > 1) {System.out.println(pname + "=" + Arrays.toString(values));} else {System.out.println(pname + "=" + values[0]);}}//返回所有参数的map集合//key =参数名 value =参数值Map<String, String[]> parameterMap = req.getParameterMap();Set<Map.Entry<String, String[]>> entries = parameterMap.entrySet();for (Map.Entry<String, String[]> entry : entries) {String pname = entry.getKey();String[] value = entry.getValue();if (value.length > 1) {System.out.println(pname + "=" + Arrays.toString(value));} else {System.out.println(pname + "=" + value[0]);}}/**以上API专门用于获取key=value形式的参数,无论这些参数是在url后还是在请求体中 GET POST请求请求行 方式urihttp/1.1请求头请求体form表单标签提交GET请求时,参数以键值对形式放在urL后不放在请求体里, GET方式的请求也是可以有请求体post*///获得请求体中的非键值对数据? JSON串 文件//获取一个从请求体中读取字符的字符输入流// BufferedReader reader = req.getReader() JSON串//获得一个从请求中读取二进制数据字节的输入流//ServLetInputStream inputstream = req.getInputStream();文件}
}
9 HttpServletResponse
9.1 HttpServletResponse
HttpServletResponse是一个接口,其父接口是ServletResponse
HttpServletResponse是Tomcat预先创建的,在Tomcat调用service方法时传入
HttpServletResponse代表对客户端的响应,该对象会被转换成响应的报文发送给客户端,通过该对象我们可以设置响应信息
9.2 HttpServletResponse的常见API
-
设置响应行相关
API | 功能解释 |
---|---|
void setStatus(int code); | 设置响应状态码 |
-
设置响应头相关
API | 功能解释 |
---|---|
void setHeader(String headerName, String headerValue); | 设置/修改响应头键值对 |
void setContentType(String contentType); | 设置content-type响应头及响应字符集(设置MIME类型) |
-
设置响应体相关
API | 功能解释 |
---|---|
PrintWriter getWriter() throws IOException; | 获得向响应体放入信息的字符输出流 |
ServletOutputStream getOutputStream() throws IOException; | 获得向响应体放入信息的字节输出流 |
void setContentLength(int length); | 设置响应体的字节长度,其实就是在设置content-length响应头 |
-
其他API
API | 功能解释 |
---|---|
void sendError(int code, String message) throws IOException; | 向客户端响应错误信息的方法,需要指定响应码和响应信息 |
void addCookie(Cookie cookie); | 向响应体中增加cookie |
void setCharacterEncoding(String encoding); | 设置响应体字符集 |
MIME类型
-
MIME类型,可以理解为文档类型,用户表示传递的数据是属于什么类型的文档
-
浏览器可以根据MIME类型决定该用什么样的方式解析接收到的响应体数据
-
可以这样理解: 前后端交互数据时,告诉对方发给对方的是 html/css/js/图片/声音/视频/... ...
-
tomcat/conf/web.xml中配置了常见文件的拓展名和MIMIE类型的对应关系
-
常见的MIME类型举例如下
文件拓展名 | MIME类型 |
---|---|
.html | text/html |
.css | text/css |
.js | application/javascript |
.png /.jpeg/.jpg/... ... | image/jpeg |
.mp3/.mpe/.mpeg/ ... ... | audio/mpeg |
.mp4 | video/mp4 |
.m1v/.m1v/.m2v/.mpe/... ... | video/mpeg |
@WebServlet("/servlet06")
public class Servlet06 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置响应行相关的API HTTP/1.1 200/404/405/500/ . . .resp.setStatus(200);String info="<h1>孙俊祥大佬好</h1>";//设置响应体API//resp.setHeader("aaa","value");//resp.setHeader("Content-Type","text/html")//resp.setHeader("Content-Length","text/html")resp.setContentType("text/html");resp.setContentLength(1234);//设置响应体内容API//获得一个向响应体中输入文本字符输入流PrintWriter writer=resp.getWriter();
// writer.write("<h1>孙俊祥大佬好</h1>");writer.write(info);//获得一个向响应体中输入二进制信息的字节输出流
// ServletOutputStream outputStream = resp.getOutputStream();}
}
10 请求转发和响应重定向
10.1 概述
什么是请求转发和响应重定向
请求转发和响应重定向是web应用中间接访问项目资源的两种手段,也是Servlet控制页面跳转的两种手段
请求转发通过HttpServletRequest实现,响应重定向通过HttpServletResponse实现
请求转发生活举例: 张三找李四借钱,李四没有,李四找王五,让王五借给张三
响应重定向生活举例:张三找李四借钱,李四没有,李四让张三去找王五,张三自己再去找王五借钱
10.2 请求转发
请求转发运行逻辑图
请求转发特点
请求转发通过HttpServletRequest对象获取请求转发器实现
请求转发是服务器内部的行为,对客户端是屏蔽的
客户端只发送了一次请求,客户端地址栏不变
服务端只产生了一对请求和响应对象,这一对请求和响应对象会继续传递给下一个资源
因为全程只有一个HttpServletRequset对象,所以请求参数可以传递,请求域中的数据也可以传递
请求转发可以转发给其他Servlet动态资源,也可以转发给一些静态资源以实现页面跳转
请求转发可以转发给WEB-INF下受保护的资源
请求转发不能转发到本项目以外的外部资源
@WebServlet("/servletA") public class ServletA extends HttpServlet {/**1请求转发是通过HttpservLetRequest对象实现的*2请求转发是服务器内部行为,对客户端是屏蔽的*3客户端只产生了一次请求服务端只产生了一对 request 利response对象*4客户端的地址栏是不变的*5请求的参数是可以继续传递的*6目标资源可以是servlet动态资源也可以是html静态资源*7目标资源可以是WEB-INF下的受保护的资源该方式也是WEB-工INF下的资源的唯一访问方式*8.外部资源不可以是外部的资源*/@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("servletA 执行了");String money = req.getParameter("money");System.out.println("servletA获得参数:money="+money);//请求转发给ServletB//获得请求转发器//*1请求转发是通过HttpservLetRequest对象实现的// *2请求转发是服务器内部行为,对客户端是屏蔽的// *3客户端只产生了一次请求服务端只产生了一对 request 利response对象// *4客户端的地址栏是不变的// *5请求的参数是可以继续传递的 // RequestDispatcher requestDispatcher = req.getRequestDispatcher("servletB");//6目标资源可以是servlet动态资源也可以是html静态资源 // RequestDispatcher requestDispatcher = req.getRequestDispatcher("大佬.html");//7目标资源可以是WEB-INF下的受保护的资源该方式也是WEB-工INF下的资源的唯一访问方式 // RequestDispatcher requestDispatcher = req.getRequestDispatcher("WEB-INF/大佬B.html");//8.外部资源不可以是外部的资源RequestDispatcher requestDispatcher = req.getRequestDispatcher("http://www.bilibili.com");//让请求转发器做出转发动作requestDispatcher.forward(req, resp);} }
10.3 响应重定向
响应重定向运行逻辑图
响应重定向特点
响应重定向通过HttpServletResponse对象的sendRedirect方法实现
响应重定向是服务端通过302响应码和路径,告诉客户端自己去找其他资源,是在服务端提示下的,客户端的行为
客户端至少发送了两次请求,客户端地址栏是要变化的
服务端产生了多对请求和响应对象,且请求和响应对象不会传递给下一个资源
因为全程产生了多个HttpServletRequset对象,所以请求参数不可以传递,请求域中的数据也不可以传递
重定向可以是其他Servlet动态资源,也可以是一些静态资源以实现页面跳转
重定向不可以到给WEB-INF下受保护的资源
重定向可以到本项目以外的外部资源
@WebServlet("/servlet1") public class Servlet1 extends HttpServlet {/*响应重定向*1.响应重定向是通动HttpServLetResponse对象实现*2.响应重定向是在服务端提示下的,客户端的行为,*3.客户端的地址栏是变化的*4.客户端至少发送了两次请求客户端产生了多次请求*5.请求产生了多次 后端就会有多个request对象 此时请求中的参数不能继续自动传递*6.目标资源资源可以视图资源*7.目标资源不可以是wEB-INF下的资源*8.目标资源可以是外部资源**** 重点:同样能够实现页面跳转,优先使用响应重定向*** */@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//接收用户请求System.out.println("Servlet1 执行了");//*5.请求产生了多次 后端就会有多个request对象 此时请求中的参数不能继续自动传递System.out.println("servlet1 got money="+req.getParameter("money"));//响应重定向 设置响应状态码为302同时设置Location 响应头://*1.响应重定向是通动HttpServLetResponse对象实现// *2.响应重定向是在服务端提示下的,客户端的行为,// *3.客户端的地址栏是变化的// *4.客户端至少发送了两次请求客户端产生了多次请求 // resp.sendRedirect("servlet2");//*6.目标资源资源可以视图资源 // resp.sendRedirect("a.html");//*7.目标资源不可以是wEB-INF下的资源 // resp.sendRedirect("WEB-INF/b.html");//*8.目标资源可以是外部资源resp.sendRedirect("http://www.bilibili.com");} }
十一 MVC架构模式
MVC(Model View Controller)是软件工程中的一种
软件架构模式
,它把软件系统分为模型
、视图
和控制器
三个基本部分。用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
-
M:Model 模型层,具体功能如下
-
存放和数据库对象的实体类以及一些用于存储非数据库表完整相关的VO对象
-
存放一些对数据进行逻辑运算操作的的一些业务处理代码
-
-
V:View 视图层,具体功能如下
-
存放一些视图文件相关的代码 html css js等
-
在前后端分离的项目中,后端已经没有视图文件,该层次已经衍化成独立的前端项目
-
-
C:Controller 控制层,具体功能如下
-
接收客户端请求,获得请求数据
-
将准备好的数据响应给客户端
-
MVC模式下,项目中的常见包
-
M:
-
实体类包(pojo /entity /bean) 专门存放和数据库对应的实体类和一些VO对象
-
数据库访问包(dao/mapper) 专门存放对数据库不同表格CURD方法封装的一些类
-
服务包(service) 专门存放对数据进行业务逻辑运算的一些类
-
-
C:
-
控制层包(controller)
-
-
V:
-
web目录下的视图资源 html css js img 等
-
前端工程化后,在后端项目中已经不存在了
-
非前后端分离的MVC
前后端分离的MVC
举例
张三网络购物买10本<<JAVA从入门到精通>>