Javaweb——Servlet 技术

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: Javaweb——Servlet 技术

1.1 什么是 Servlet

1、Servlet 是 JavaEE的规范之一。(规范就是接口)

2、Servlet是 三大组件之一。

JavaWeb 三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器

3、Servlet 是运行在服务器上的一个 java 小程序,它可以接收客户端发送过来的请求,并响应 数据给客户端。


1.2 手动实现 Servlet 程序

1、编写一个类去实现 Servlet 接口

public class HelloServlet implements Servlet

2、实现 service 方法,处理请求,并响应数据

3、到 web.xml 中去配置 servlet 程序的访问地址

  • Servlet 程序的示例代码:
public class HelloServlet implements Servlet {
  @Override
  public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
  System.out.println("Hello Servlet  被访问了");
  }
}
  • web.xml 中的配置:
<?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_4_0.xsd"
version="4.0">
<!-- servlet 标签给 Tomcat 配置 Servlet 程序 -->
<servlet>
<!--servlet-name 标签 Servlet 程序起一个别名(一般是类名) -->
<servlet-name>HelloServlet</servlet-name>
<!--servlet-class 是 Servlet 程序的全类名 -->
<servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
</servlet>
<!--servlet-mapping 标签给 servlet 程序配置访问地址 -->
<servlet-mapping>
<!--servlet-name 标签的作用是告诉服务器,我当前配置的地址给哪个 Servlet 程序使用 -->
<servlet-name>HelloServlet</servlet-name>
<!--url-pattern 标签配置访问地址 <br/>
/ 斜杠在服务器解析的时候,表示地址为: http://ip:port/ 工程路径 <br/>
/hello 表示地址为: http://ip:port/ 工程路径 /hello <br/>
-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>

执行原理:

  1. 当服务器接受到浏览器的请求后,会解析URL路径,获取访问的Servlet的资源路径
  2. 查找web.xml文件,是否有对应的标签体内容。
  3. 如果有,则在找到对应的全类名
  4. tomcat会将字节码文件加载进内存,并且创建其对象
  5. 调用其方法
  • 在浏览器中添加指定的标签体内容即hello,就可以在idea控制台中看到Hello Servlet 被访问了这句话。

常见的错误 1:url-pattern 中配置的路径没有以斜杠打头。

常见错误 2:servlet-name 配置的值不存在:

常见错误 3:servlet-class 标签的全类名配置错误:


1.3 url 地址到 Servlet 程序的访问图析


1.4 Servlet 的生命周期

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。

以下是 Servlet 遵循的过程:

  • Servlet 通过调用 init () 方法进行初始化。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 通过调用 destroy() 方法终止(结束)。
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

1.5 GET 和 POST 请求的分发处理

public class HelloServlet implements Servlet {
//service 方法是专门用来处理请求和响应的
  @Override
  public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
  System.out.println("3 service === Hello Servlet  被访问了");
  // 类型转换(因为它有 getMethod() 方法)
  HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
  // 获取请求的方式
  String method = httpServletRequest.getMethod();
  if ("GET".equals(method)) {
  doGet();
  } else if ("POST".equals(method)) {
  doPost();
  }
}
//做 get 请求的操作
public void doGet(){
System.out.println("get  请求");
  }
//做 post 请求的操作
public void doPost(){
System.out.println("post  请求");
  }
}

1.6 通过继承 HttpServlet 实现 Servlet 程序

一般在实际项目开发中,都是使用继承 HttpServlet 类的方式去实现 Servlet 程序。

以下是使用继承 HttpServlet 类的过程:

1、编写一个类去继承 HttpServlet 类

2、根据业务需要重写 doGet 或 doPost 方法

3、到 web.xml 中的配置 Servlet 程序的访问地址

  • Servlet 类的代码:
public class HelloServlet2 extends HttpServlet {
// doGet()在 get 请求的时候调用
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
  System.out.println("HelloServlet2 的  doGet  方法");
  }
// doPost()在 post 请求的时候调用
  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
  System.out.println("HelloServlet2 的  doPost  方法");
  }
}
  • web.xml 中的配置:
<servlet>
<servlet-name>HelloServlet2</servlet-name>
<servlet-class>com.atguigu.servlet.HelloServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet2</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>

1.7 使用 IDEA 创建 Servlet 程序

菜单:new ->Servlet 程序

配置 Servlet 的信息:


1.8 Servlet 类的继承体系


2.ServletConfig 类

ServletConfig 类从类名上来看,就知道是 Servlet 程序的配置信息类。

Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建,我们负责使用。

Servlet 程序默认是第一次访问的时候创建,ServletConfig 是每个 Servlet 程序创建时,就创建一个对应的 ServletConfig 对象。

2.1 ServletConfig 类的三大作用

1、可以获取 Servlet 程序的别名 servlet-name 的值

2、获取初始化参数 init-param

3、获取 ServletContext 对象

  • web.xml 中的配置:
<!-- servlet 标签给 Tomcat 配置 Servlet 程序 -->
<servlet>
<!--servlet-name 标签 Servlet 程序起一个别名(一般是类名) -->
<servlet-name>HelloServlet</servlet-name>
<!--servlet-class 是 Servlet 程序的全类名 -->
<servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
<!--init-param 是初始化参数 -->
<init-param>
<!-- 是参数名 -->
<param-name>username</param-name>
<!-- 是参数值 -->
<param-value>root</param-value>
</init-param>
<!--init-param 是初始化参数 -->
<init-param>
<!-- 是参数名 -->
<param-name>url</param-name>
<!-- 是参数值 -->
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</init-param>
</servlet>
<!--servlet-mapping 标签给 servlet 程序配置访问地址 -->
<servlet-mapping>
<!--servlet-name 标签的作用是告诉服务器,我当前配置的地址给哪个 Servlet 程序使用 -->
<servlet-name>HelloServlet</servlet-name>
<!--
url-pattern 标签配置访问地址 <br/>
/ 斜杠在服务器解析的时候,表示地址为: http://ip:port/ 工程路径 <br/>
/hello 表示地址为: http://ip:port/ 工程路径 /hello <br/>
-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
  • Servlet 中的代码:
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2 init  初始化方法");
// 1 、可以获取 Servlet 程序的别名 servlet-name 的值
System.out.println("HelloServlet  程序的别名是:" + servletConfig.getServletName());
// 2 、获取初始化参数 init-param
System.out.println(" 初始化参数 username  的值是;" + servletConfig.getInitParameter("username"));
System.out.println(" 初始化参数 url  的值是;" + servletConfig.getInitParameter("url"));
// 3 、获取 ServletContext 对象
System.out.println(servletConfig.getServletContext());
}

注意点:


3.ServletContext 类

3.1 什么是 ServletContext?

1、ServletContext 是一个接口,它表示 Servlet 上下文对象

2、一个 web 工程,只有一个 ServletContext 对象实例。

3、ServletContext 对象是一个域对象。

4、ServletContext 是在 web 工程部署启动的时候创建。在 web 工程停止的时候销毁。

  • 什么是域对象?
    域对象,是可以像 Map 一样存取数据的对象,叫域对象。
    这里的域指的是存取数据的操作范围,整个 web 工程。
存数据 取数据 删除数据
Map put() get() remove()
域对象 setAttribute() getAttribute() removeAttribute();

3.2 ServletContext 类的四个作用

1、获取 web.xml 中配置的上下文参数 context-param

2、获取当前的工程路径,格式: /工程路径

3、获取工程部署后在服务器硬盘上的绝对路径

4、像 Map 一样存取数据

  • ServletContext 演示代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1 、获取 web.xml 中配置的上下文参数 context-param
ServletContext context = getServletConfig().getServletContext();
String username = context.getInitParameter("username");
System.out.println("context-param  参数 username  的值是:" + username);
System.out.println("context-param  参数 password  的值是:" +
context.getInitParameter("password"));
// 2 、获取当前的工程路径,格式 : / 工程路径
System.out.println( " 当前工程路径:" + context.getContextPath() );
// 3 、获取工程部署后在服务器硬盘上的绝对路径
 /* 斜杠被服务器解析地址为 :http://ip:port/ 工程名 / 映射到 IDEA 代码的 web 目录 <br/>
*/
System.out.println(" 工程部署的路径是:" + context.getRealPath("/"));
System.out.println(" 工程下 css  目录的绝对路径是:" +context.getRealPath("/css"));
System.out.println(" 工程下 imgs  目录 1.jpg  的绝对路径是:" + context.getRealPath("/imgs/1.jpg"));
  }
  • web.xml 中的配置:
<!--context-param 是上下文参数 ( 它属于整个 web 工程 )-->
<context-param>
<param-name>username</param-name>
<param-value>context</param-value>
</context-param>
<!--context-param 是上下文参数 ( 它属于整个 web 工程 )-->
<context-param>
<param-name>password</param-name>
<param-value>root</param-value>
</context-param>

ServletContext 像 Map 一样存取数据:

  • ContextServlet1 代码:
public class ContextServlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
// 获取 ServletContext 对象
ServletContext context = getServletContext();
System.out.println(context);
System.out.println(" 保存之前: Context1 取 获取 key1  的值是:"+ context.getAttribute("key1"));
context.setAttribute("key1", "value1");
System.out.println("Context1  中获取域数据 key1  的值是:"+ context.getAttribute("key1"));
}
}
  • ContextServlet2 代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
ServletContext context = getServletContext();
System.out.println(context);
System.out.println("Context2  中获取域数据 key1  的值是:"+ context.getAttribute("key1"));

Servlet入门篇的总结

执行原理

  1. 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径。在上图的URL中,获取的资源路径就是/demo01
  2. 查找web.xml文件,是否有对应的标签体内容。
  3. 如果有,则在找到对应的全类名,获取到的全路径是:cn.itcast.web.servlet.ServletDemo
  4. tomcat会将字节码文件加载进内存,并且创建其对象
  5. 调用其方法(主要调用service方法)

反射(补充)

类:模板,一堆代码的集合,类里面有:属性(字段)、方法等等。

对象:基于类来创建对象,通过对象来描述现实世界。就是要调用对象相关的方法。

创建类对象和调用方法一般用在两种地方:

  • 编译时:其实就是在编写代码时候创建类对象,并调用。
// Person为p的编译时类型,Student为p的运行时类型
Person p = new Student();
  • 运行时:在运行时,动态创建类对象,调用类方法
  • 实现手段:主要通过Java的java.lang.Class类来完成。
  • 获取java.lang.Class对象有三种方法:
  • 使用Class的forName(String clazzName)方法,传入字符串,传入为类的全限定名。
  • 调用某个类的class属性
  • 调用getClass方法获得。
  • 在反射中,通常采用Class.forName(String clazzName)方法动态获取类对象。
    1.调用getClass()
//通过getClass()方法获得
Boolean b = true;
Class<?> clazz = b.getClass();
System.out.println(clazz); //输出结果为:java.lang.Boolean
  • 2.调用某个类的class属性
//通过class方法获得。
Class<?> clazz = Boolean.class;
System.out.println(clazz); //输出结果为:java.lang.Boolean
  • 3.通过Class.forName(String clazzName)获得
Class<?> clazz = Class.forName("java.lang.Boolean");
System.out.println(clazz); //输出结果为:java.lang.Boolean

根据字节码文件创建对象

  1. 根据字节码文件,调用无参构造方法,创建对象
Class<?> clazz = Class.forName("java.lang.Boolean");
System.out.println(clazz); //输出结果为:java.lang.Boolean
Object o=clazz.newInstance();
  1. 根据字节码文件,调用有参数构造方法,创建对象
Class<?> clazz= Class.forName("java.lang.Integer");
System.out.println(clazz);
//根据字节码获取构造函数
Constructor con= clazz.getConstructor(int.class);
Object o=con.newInstance(10);
System.out.println(o);

创建方法

if(args.length!=1){
  System.out.println("参数错误");
  return;
}
Class<?> clazz= Class.forName(args[0]);
Object o=clazz.newInstance();
Method service=clazz.getMethod("service");
service.invoke(o);

生命周期详解

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。

以下是 Servlet 遵循的过程:

  • Servlet 通过调用 init () 方法进行初始化。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 通过调用 destroy() 方法终止(结束)。
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

现在让我们详细讨论生命周期的方法。

init() 方法

init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。

Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。

当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。

init 方法的定义如下:

public void init() throws ServletException {
  // 初始化代码...
}

service() 方法

service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。

每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。

下面是该方法的特征:

public void service(ServletRequest request, ServletResponse response) 
      throws ServletException, IOException{
}

service() 方法由容器调用,service 方法在适当的时候调用 doGet、doPost、doPut、doDelete 等方法。所以,您不用对 service() 方法做任何动作,您只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可。


doGet() 和 doPost() 方法是每次服务请求中最常用的方法。下面是这两种方法的特征。

doGet() 方法

GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。

public void doGet(HttpServletRequest request,HttpServletResponse response)
    throws ServletException, IOException {
    // Servlet 代码
}

doPost() 方法

POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。

public void doPost(HttpServletRequest request,HttpServletResponse response)
    throws ServletException, IOException {
    // Servlet 代码
}

destroy() 方法

destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。

在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。destroy 方法定义如下所示:

public void destroy() {
    // 终止化代码...
  }

架构图

下图显示了一个典型的 Servlet 生命周期方案。

  • 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。
  • Servlet 容器在调用 service() 方法之前加载 Servlet。
  • 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。


Servlet的体系结构

Servlet – 接口

|

GenericServlet – 抽象类

|

HttpServlet – 抽象类

  • GenericServlet:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象
  • 将来定义Servlet类时,可以继承GenericServlet,实现service()方法即可
  • HttpServlet:对http协议的一种封装,简化操作
  1. 定义类继承HttpServlet
  2. 复写doGet/doPost方法
  • Servlet相关配置
  • urlpartten:Servlet访问路径
  • 一个Servlet可以定义多个访问路径 : @WebServlet({“/d4”,“/dd4”,“/ddd4”})
  • 路径定义规则:
  1. /xxx:路径匹配
  2. /xxx/xxx:多层路径,目录结构
  3. *.do:扩展名匹配
相关文章
|
1月前
|
Java 容器
【学习笔记】Jsp与Servlet技术
【学习笔记】Jsp与Servlet技术
66 0
|
2月前
|
Java 应用服务中间件 Maven
JavaWeb基础5——HTTP,Tomcat&Servlet
JavaWeb技术栈、HTTP、get和post区别、响应状态码、请求响应格数据式、IDEA使用Tomcat、报错解决、Servlet的体系结构、IDEA使用模板创建Servlet
JavaWeb基础5——HTTP,Tomcat&Servlet
|
3月前
|
缓存 安全 Java
Java服务器端技术:Servlet与JSP的集成与扩展
Java服务器端技术:Servlet与JSP的集成与扩展
33 3
|
3月前
|
前端开发 Java 开发工具
servlet技术--使用注解模拟用户登录实现页面跳转
该文章介绍了Servlet技术的使用,通过注解方式开发Servlet来模拟用户登录功能,并在登录成功后实现页面跳转,展示用户的用户名和密码。
servlet技术--使用注解模拟用户登录实现页面跳转
|
5月前
|
自然语言处理 前端开发 Java
Servlet与JSP:Java Web开发的基石技术详解
【6月更文挑战第23天】Java Web的Servlet与JSP是动态网页的核心。Servlet是服务器端的Java应用,处理HTTP请求并响应;JSP则是结合HTML与Java代码的页面,用于动态内容生成。Servlet通过生命周期方法如`init()`、`service()`和`destroy()`工作,而JSP在执行时编译成Servlet。两者在MVC架构中分工,Servlet处理逻辑,JSP展示数据。尽管有Spring MVC等框架,Servlet和JSP仍是理解Web开发基础的关键。
104 12
|
5月前
|
缓存 小程序 前端开发
Java服务器端技术探秘:Servlet与JSP的核心原理
【6月更文挑战第23天】Java Web开发中的Servlet和JSP详解:Servlet是服务器端的Java小程序,处理HTTP请求并响应。生命周期含初始化、服务和销毁。创建Servlet示例代码展示了`doGet()`方法的覆盖。JSP则侧重视图,动态HTML生成,通过JSP脚本元素、声明和表达式嵌入Java代码。Servlet常作为控制器,JSP处理视图,遵循MVC模式。优化策略涉及缓存、分页和安全措施。这些技术是Java服务器端开发的基础。
61 9
|
5月前
|
缓存 安全 Java
Java服务器端技术:Servlet与JSP的集成与扩展
【6月更文挑战第23天】Java Web开发中,Servlet和JSP是构建动态Web应用的基础。Servlet处理逻辑,JSP专注展示。示例展示了Servlet如何通过`request.setAttribute`传递数据给JSP渲染。JSP自定义标签提升页面功能,如创建`WelcomeTag`显示欢迎消息。Servlet过滤器,如`CacheControlFilter`,用于预处理数据或调整响应头。这些集成和扩展技术增强了应用效率、安全性和可维护性,是Java服务器端开发的关键。
66 7
|
5月前
|
存储 设计模式 搜索推荐
早期javeweb技术 JSP JDBC JSTJ Servlet BooStrap(下)
早期javeweb技术 JSP JDBC JSTJ Servlet BooStrap(下)
34 1
|
6月前
|
存储 安全 Java
Java的servlet和jsp技术
Java的servlet和jsp技术
65 11
序-Servlet和SpringMVC的联系和区别-配置路径先想好使用的使用的方法,然后匹配的需要的技术
序-Servlet和SpringMVC的联系和区别-配置路径先想好使用的使用的方法,然后匹配的需要的技术