本学习笔记参考尚硅谷、菜鸟教程、w3cschool等教程。
Servlet简介
Servlet 官网: Java Servlet Technology (oracle.com)
Servlet API文档: Java Servlet Technology - The Java EE 6 Tutorial (oracle.com)
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。一个 Servlet 就是 Java 编程语言中的一个类,它被用来扩展服务器的性能,服务器上驻留着可以通过“请求-响应”编程模型来访问的应用程序。虽然 Servlet 可以对任何类型的请求产生响应,但通常只用来扩展 Web 服务器的应用程序。
使用 Servlet,可以交互式地浏览和修改数据,生成动态Web内容,收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录。
Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
Servlet命名
Servlet 的命名可以看出 sun 命名的特点,如 Applet 表示小应用程序;Scriptlet = Script + Applet,表示小脚本程序;同样 Servlet = Service + Applet,表示小服务程序。
Servlet由来
Servlet 是在服务器上运行的小程序。这个词是在 Java applet的环境中创造的,Java applet 是一种当作单独文件跟网页一起发送的小程序,它通常用于在客户端运行,结果得到为用户进行运算或者根据用户互作用定位图形等服务。
服务器上需要一些程序,常常是根据用户输入访问数据库的程序。这些通常是使用公共网关接口(Common Gateway Interface,CGI)应用程序完成的。然而,在服务器上运行 Java,这种程序可使用 Java 编程语言实现。在通信量大的服务器上,JavaServlet 的优点在于它们的执行速度更快于 CGI 程序。各个用户请求被激活成单个程序中的一个线程,而无需创建单独的进程,这意味着服务器端处理请求的系统开销将明显降低。
实现过程
最早支持 Servlet 技术的是 JavaSoft 的 Java Web Server。此后,一些其它的基于 Java 的 Web Server 开始支持标准的 Servlet API。Servlet 的主要功能在于交互式地浏览和修改数据,生成动态 Web 内容。
- 客户端发送请求至服务器端;
- 服务器将请求信息发送至 Servlet;
- Servlet 生成响应内容并将其传给服务器。响应内容动态生成,通常取决于客户端的请求;
- 服务器将响应返回给客户端。
Servlet 相对 CGI 的优势
Java Servlet 通常情况下与使用 CGI(Common Gateway Interface,公共网关接口)实现的程序可以达到异曲同工的效果。但是相比于 CGI,Servlet 有以下几点优势:
- 性能明显更好。
- Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请求。
- Servlet 是独立于平台的,因为它们是用 Java 编写的。
- 服务器上的 Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。因此,Servlet 是可信的。
- Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库或其他软件进行交互。
简要说说什么是CGI
按我的初步理解,CGI形式的程序,是通过前端修改网页URL来实现与后端程序通信的。
详细解释借用他人博客:WEB之CGI----CGI详解(原理,配置及访问)_cgi web-优快云博客
Servlet 在IDEA中开发流程
-
创建JavaWeb项目,添加web框架支持,将Tomcat添加入项目依赖。
<!-- 以下示例为验证username是否与admin冲突,是则输出No,否则输出Yes --> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <form method="get" action="userServlet"> 用户名: <input type="text" name="username"><br> <input type="submit" value="校验"> </form> </body> </html>
-
重写service方法,service(HttpServletRequest req, HttpServletResponse resp)
-
在service方法中,定义业务处理代码。
public class UserServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //super.service(req, resp); //注释此处,不然会出现405 // 1. 从request对象中获取请求中任何信息 String username = req.getParameter("username"); //根据参数名获取参数值,无论参数是在url?后,还是在请求体中 // 2. 处理业务代码 String info = "YES"; if("admin".equals(username)){ info = "NO"; } // 3.设置Content-Type响应头,明确返回的数据类型 resp.setContentType("text/html;charset=utf-8"); // 4.将要相应的数据放入response PrintWriter out = resp.getWriter(); // 该方法返回的是一个向响应体中打印字符串的打印流 out.println(info); } }
-
在web.xml中配置Servlet对应的请求映射路径(web-app标签内)
<!-- 配置Servlet类,并起一个别名 servlet-class 告诉tomcat对应的要实例化的servlet类 servlet-name 用于关联请求的映射路径 --> <servlet> <!--给UserServlet起一个别名--> <servlet-name>userServlet</servlet-name> <servlet-class>com.test.servlet.UserServlet</servlet-class> </servlet> <servlet-mapping> <!--关联别名和映射路径--> <servlet-name>userServlet</servlet-name> <url-pattern>/userServlet</url-pattern> </servlet-mapping>
注意:
一个servlet-name可以对应多个url-pattern,但一个url-pattern只能对应一个servlet-name
/ 表示通配所有资源,不包括jsp文件
/* 表示通配所有资源,包括jsp文件
/a/* 匹配所有以a前缀的映射路径
*.action 匹配所有以action为后缀的映射路径
映射关系图
Servlet注解方式配置
利用注解时,可以省去在web.xml中写入相关标签,加开开发效率。
@WebServlet注解源码
官方JAVAEEAPI文档下载地址 :Java EE - Technologies (oracle.com)
public @interface WebServlet {
/**
* The name of the servlet
* 相当于 servlet-name
* @return the name of the servlet
*/
String name() default "";
/**
* The URL patterns of the servlet
* 如果只配置一个url-pattern ,则通过该属性即可,和urlPatterns属性互斥
* @return the URL patterns of the servlet
*/
String[] value() default {
};
/**
* The URL patterns of the servlet
* 如果要配置多个url-pattern ,需要通过该属性,和value属性互斥
* @return the URL patterns of the servlet
*/
String[] urlPatterns() default {
};
/**
* The load-on-startup order of the servlet
* 配置Servlet是否在项目加载时实例化
* 默认值-1时,tomcat启动不会实例化该servlet
* 其他正整数,tomcat启动时实例化该servlet的顺序
* @return the load-on-startup order of the servlet
*/
int loadOnStartup() default -1;
/**
* The init parameters of the servlet
* 配置初始化参数
* @return the init parameters of the servlet
*/
WebInitParam[] initParams() default {
};
/**
* Declares whether the servlet supports asynchronous operation mode.
*
* @return {@code true} if the servlet supports asynchronous operation mode
* @see jakarta.servlet.ServletRequest#startAsync
* @see jakarta.servlet.ServletRequest#startAsync( jakarta.servlet.ServletRequest,jakarta.servlet.ServletResponse)
*/
boolean asyncSupported() default false;
/**
* The small-icon of the servlet
*
* @return the small-icon of the servlet
*/
String smallIcon() default "";
/**
* The large-icon of the servlet
*
* @return the large-icon of the servlet
*/
String largeIcon() default "";
/**
* The description of the servlet
*
* @return the description of the servlet
*/
String description() default "";
/**
* The display name of the servlet
*
* @return the display name of the servlet
*/
String displayName() default "";
}
@WebServlet注解使用
@WebServlet(
name = "userServlet",
//value = "/user",
urlPatterns = {
"/userServlet1","/userServlet2","/userServlet"},
initParams = {
@WebInitParam(name = "encoding",value = "UTF-8")},
loadOnStartup = 6
)
public class UserServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//......
}
}
Servlet常见容器
Tomcat, Jetty, resin, Oracle Application server, WebLogic Server, Glassfish, Websphere, JBoss 等等。(提供了 Servlet 功能的服务器,叫做 Servlet 容器。对 web 程序来说,Servlet 容器的作用就相当于桌面程序里操作系统的作用,都是提供一些编程基础设施)
Servlet 生命周期
简介
生命周期简述:对象在容器中从开始创建到销毁的过程。
应用程序中的对象不仅在空间上有层次结构的关系,在时间上也会因为处于程序运行过程中的不同阶段而表现出不同状态和不同行为——这就是对象的生命周期。
Servlet对象是Servlet容器创建的,生命周期方法都是由容器(目前我们使用的是Tomcat)调用的。这一点和我们之前所编写的代码有很大不同。在今后的学习中我们会看到,越来越多的对象交给容器或框架来创建,越来越多的方法由容器或框架来调用,开发人员要尽可能多的将精力放在业务逻辑的实现上。
生命周期 | 对应方法 | 执行时机 | 执行次数 |
---|---|---|---|
构造对象 | 构造器 | 第一次请求或者容器启动 | 1 |
初始化 | init() | 构造完毕后 | 1 |
处理服务 | service(HttpServletRequest req,HttpServletResponse resp) | 每次请求 | 多次 |
销毁 | destory() | 容器关闭 | 1 |
测试
运行服务器,在对应网址url后加上 /servletLifeCycle 进行访问测试。
发现只会在第一次请求时使用构造器、初始化方法和service方法,之后的刷新只会调用service方法。
服务器结束时候才会调用销毁方法。
package com.test.servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import