目录
1) 在实际开发中,往往业务比较复杂,需要在一次请求中,使用到多个 Servlet 完成一个任务
一.介绍
介绍
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
特点
- 由服务器端调用和执行(Tomcat解析和执行)
- 用java语言编写的, 本质就是Java类
- 按照Servlet规范开发的(除了tomcat->Servlet weblogic->Servlet)
- 功能强大,可以完成几乎所有的网站功能
二.功能
- 读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。
- 读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。
- 处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。
- 发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。
- 发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务。
三.使用
1.开发方式说明
servlet3.0 前使用 web.xml , servlet3.0 版本以后(包括 3.0)支持注解, 同时支持 web.xml 配置
原生 的 Servlet 在项目中使用很少
2.加载
在web-inf目录下添加lib,加载servlet-api-jar,即完成servlet加载
3.servlet接口说明
package com.Leon.servlet;
import javax.servlet.*;
import java.io.IOException;
/**
* Date:2023/8/14 12:23
* Description:TODO
*
* @author Leon
* @version 1.0
*/
//开发servlet需要实现servlet接口
public class HelloServlet implements Servlet {
/**
* 初始化servlet
* 当tomcat创建Helloservlet实例时,调用init方法
* @param servletConfig
* @throws ServletException
*/
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("初始化");
}
/**
* 返回servlet的配置
* @return
*/
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* service方法接收两个对象(包括get和post)
* 当浏览器每次请求servlet时,就会调用一次serve
* 当tomcat调用该方法时,会把HTTP请求的数据封装成ServletRequest接口对象
* 通过Request对象得到用户提交的数据
* servletResponse对象可以用于返回数据给tomcat->浏览器
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
/**
* 返回servlet信息
* @return
*/
@Override
public String getServletInfo() {
return null;
}
/**
* 销毁servlet实例
*/
@Override
public void destroy() {
}
}
4.web.xml配置servlet
<?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>
<!--servlet的唯一名-->
<servlet-name>HelloServlet|</servlet-name>
<!--为反射提供类的全路径-->
<servlet-class>com.Leon.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--name保持一致-->
<servlet-name>HelloServlet|</servlet-name>
<!--servlet访问匹配路径-->
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
</web-app>
5.浏览器请求Servlet流程UML分析
6.生命周期
三个阶段
- init()初始化阶段
- service()处理浏览器请求阶段
- destroy()终止阶段
示意图
-
初始化阶段
Servlet 容器(比如: Tomcat)加载 Servlet,加载完成后,Servlet 容器会创建一个 Servlet 实例 并调用 init()方法,init()方法只会调用一次, Servlet 容器在下面的情况装载 Servle
- Servlet 容器(Tomcat)启动时自动装载某些 servlet,实现这个需要在 web.xml 文件中添加 1 1 表示装载的顺序
- 在 Servlet 容器启动后,浏览器首次向 Servlet 发送请求(这个前面说过)
- Servlet 重新装载时(比如 tomcat 进行 redeploy【redeploy 会销毁所有的 Servlet 实例】), 浏览器再向 Servlet 发送第一次请求
-
处理阶段
- 每收到一个 http 请求,服务器就会产生一个新的线程去处理[线程]
- 创建一个用于封装 HTTP 请求消息的 ServletRequest 对象和一个代表 HTTP 响应消息的 ServletResponse 对象
- 然后调用 Servlet 的 service()方法并将请求和响应对象作为参数传递进去
-
终止阶段
当web 应用被终止,或者Servlet 容器终止运行,或者Servlet 类重新装载时,会调用 destroy() 方法 , 比如重启 tomcat ,或者 redeploy web 应用
7.GET&POST请求分发处理
//通过 ServletRequest 对象来获取请求方式
//将servletRequest转成HttpServletRequest引用
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String method = httpServletRequest.getMethod();
if ("GET".equals(method)){
doGet();
}else if("POST".equals(method)){
doPost();
}
8.HttpServlet开发Servlet
实际开发中,继承Servlet较为不便,使用继承HttpServlet类来开发更为方便
Servlet注意事项与细节
- Servlet 是一个供其他 Java 程序(Servlet 引擎)调用的 Java 类,不能独立运行
- 针对浏览器的多次 Servlet 请求,通常情况下,服务器只会创建一个 Servlet 实例对象, 也就是说 Servlet 实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至 web 容器退出/或者 redeploy 该 web 应用,servlet 实例对象才会销毁
- 在 Servlet 的整个生命周期内,init 方法只被调用一次。而对每次请求都导致 Servlet 引 擎调用一次 servlet 的 service 方法
- . 对于每次访问请求,Servlet 引擎都会创建一个新的 HttpServletRequest 请求对象和一个 新的 HttpServletResponse 响应对象,然后将这两个对象作为参数传递给它调用的 Servlet 的 service()方法,service 方法再根据请求方式分别调用 doXXX 方法
- 如果在元素中配置了一个元素,那么 WEB 应用程序在启动时, 就会装载并创建 Servlet 的实例对象、以及调用 Servlet实例对象的init()方法
四. servlet注解方式
@WebServlet(urlPatterns = {"/ok1","/ok2"})
public class OkServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
urlPatterns数组存放对应web.xml的<url-patterns>进行匹配
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
String name() default "";
String[] value() default {};
String[] urlPatterns() default {};
int loadOnStartup() default -1;
WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
可以用同样的办法配置其他属性 如loadOnStartup等
1.Servlet urlPattern配置
精确匹配
配置路径 : @WebServlet("/ok/zs")
访问文件: servlet: localhost:8080/servlet/ok/zs- 目录匹配
配置路径 : @WebServlet("/ok/*")
访问文件: localhost:8080/servlet/ok/aaa localhost:8080/servlet/ok/bbb- 扩展名匹配
配置路径 : @WebServlet("*.action")
访问文件: localhost:8080/hsp/zs.action localhost:8080/hsp/ls.action- 任意匹配(避免)
配置路径 : @WebServlet("/") @WebServlet("/*")
访问文件: localhost:8080/hsp/aaa localhost:8080/hsp/bbb localhost:8080/hsp/cc
2.注意事项
- 当 Servlet 配置了 "/", 会覆盖 tomcat 的 DefaultServlet, 当其他的 utl-pattern 都匹配不上时 ,都会走这个Servlet, 这样可以拦截到其他静态资源
- 这个默认的 servlet 是处理静态资源的,一旦拦截,静态资源不能处理
- 优先级遵守: 精确路径 > 目录路径 > 扩展名路径 > /* > /
五.ServletConfig
1.基本介绍
1. ServletConfig 类是为 Servlet 程序的配置信息的类
2. Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建
3. Servlet 程序默认是第 1 次访问的时候创建,ServletConfig 在 Servlet 程序创建时,就创 建一个对应的 ServletConfig 对象
2.功能
1. 获取 Servlet 程序的 servlet-name的值
2. 获取初始化参数 init-param
3. 获取 ServletContext 对象
六. ServletContext
1.基本介绍
- ServletContext 是一个接口,它表示 Servlet 上下文对象
- 一个 web 工程,只有一个 ServletContext 对象实例
- ServletContext 对象 是在 web 工程启动的时候创建,在 web 工程停止的时销毁
- ServletContext 对象可以通过 ServletConfig.getServletContext 方法获得对 ServletContext 对象的引用,也可以通过 this.getServletContext()来获得其对象的引用。
- 由于一个 WEB 应用中的所有 Servlet 共享同一个 ServletContext 对象,因此 Servlet 对象 之间可以通过 ServletContext 对象来实现多个 Servlet 间通讯。ServletContext 对象通常也被 称之为域对象
2.功能
- 获取 web.xml 中配置的上下文参数 context-param [信息和整个 web 应用相关,而不是 属于某个 Servlet]
- 获取当前的工程路径,格式: /工程路径,如 /servlet getContexPath()
- 获取工程部署后在服务器硬盘上的绝对路径
- 像Map一样存取数据, 多个 Servlet共享数据
七.HttpServletRequest
1.基本介绍
- HttpServletRequest 对象代表客户端的请求
- 当客户端/浏览器通过 HTTP 协议访问服务器时,HTTP 请求头中的所有信息都封装在这个对象中
- 通过这个对象的方法,可以获得客户端这些信息
2.常用方法
3.请求转发
1) 在实际开发中,往往业务比较复杂,需要在一次请求中,使用到多个 Servlet 完成一个任务
2) 请求转发说明
- 实现请求转发:请求转发指一个 web 资源收到客户端请求后,通知服务器去调用另外 一个 web 资源进行处理,请求转发不用新的request对象
- HttpServletRequest 对象(也叫 Request 对象)提供了一个 getRequestDispatcher 方法,该 方法返回一个 RequestDispatcher 对象,调用这个对象的 forward 方法可以实现请求转发
- request 对象同时也是一个域对象,开发人员通过 request 对象在实现转发时,把数据 通过 request 对象带给其它 web 资源处理
setAttribute方法
getAttribute方法
removeAttribute方法
getAttributeNames方法
3) 实现请求转发示意图
4) 注意事项
- 浏览器地址不会变化(地址会保留在第 1 个 servlet 的 url)
- 在同一次 HTTP 请求中,进行多次转发,仍然是一次 HTTP 请求
- 在同一次 HTTP 请求中,进行多次转发,多个 Servlet 可以共享 request 域/对象的数据(因 为始终是同一个 request 对象)
- 可以转发到 WEB-INF 目录下(后面做项目使用)
- 不能访问当前 WEB 工程外的资
- 因为浏览器地址栏会停止在第一个 servlet ,如果你刷新页面,会再次发出请求(并且会 带数据), 所以在支付页面情况下,不要使用请求转发,否则会造成重复支付
八.HttpServletResponse
1.基本介绍
- 每次 HTTP 请求,Tomcat 会创建一个 HttpServletResponse 对象传递给 Servlet 程序去 使用。
- HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息, 如果需要设置返回给客户端的信息,通过 HttpServletResponse 对象来进行设置即可
2.类图
3.向客户端返回数据方法
1. 字节流 getOutputStream(); 常用于下载(处理二进制数据)
2. 字符流 getWriter(); 常用于回传字符串
3. (细节:)两个流同时只能使用一个。
4.处理中文乱码
5.请求重定向
1) 重定向介绍
- 请求重定向指:一个 web 资源收到客户端请求后,通知客户端去访问另外一个 web 资源
- 请求重定向示意图
2) 注意事项
- 请求重定向由浏览器解析,解析时将主机和Location拼接成为重定向地址
- 最佳应用场景:网站迁移,比如原域名是 www. abc.com 迁移到 www.abc.cn ,但是浏览器抓取的还是原来网址.
- 浏览器地址会发生变化,本质是两次http 请求. 同时不能共享 Request 域中的数据,会生成两个 HttpServletRequest 对象
- 不能重定向到 /WEB-INF 下的资源
- 可以重定向到 Web 工程以外的资源, 比如 到 www.baidu.com
- 重定向有两种方式, 推荐使用第 1 种
//1 response.sendRedirect("/projectUri/redirectUri"); //2 response.setStatus(302); response.setHeader("Location","/projectUri/redirectUri"); //3 动态获取 String contextPath = getServletContext().getContextPath(); response.sendRedirect(contextPath + "/redirectUri");
6.重定向与转发的区别
- 重定向发生两次请求;而转发只有一次。
- 转发不会改变访问的地址;而重定向会更改。
- 请求转发发生在服务器端,由服务器(比如servlet)控制;重定向发生在客户端,由客户(通常是浏览器)控制。
- 转发只能将请求转发给同一个WEB应用中的组件;而重定向方法不仅可以重定向到当前应用程序中的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。(重新定向可以访问外部网站 转发只能访问内部资源)
- 请求转发相对快:因为请求转发过程在同一请求中;重定向相对慢:因为重定向过程发生在两个不同的请求中。转发的性能要优于重定向。