Servlet
一、Http协议
1.1、概念
Hypertext Transfer Protocol,HTTP超⽂本传输协议,是⼀个简单的请求-响应协议。
规定了客户端和服务器之间 传输数据的⼀种格式
HTTP底层协议:TCP 协议
TCP 的特点:⾯向连接,保证可靠性
TCP三次握⼿,因为HTTP是基于TCP协议的,所有也可以认为是HTTP的三次握⼿:
第⼀次握⼿:客户端向服务端发送⼀个请求消息,服务端收到信息后知道⾃⼰与客户端是可以连接成功的;
第⼆次握⼿:此时客户端并不知道服务端是否已经接收到了它的请求,所以服务端接收到消息后要向客户端做出响应,客户端得到服务端的反馈后,才确定⾃⼰与服务端是可以连接上的。
第三次握⼿:客户端确认与服务器建⽴连接后,才开始向服务器端发送数据。
1.2、特点
基于TCP/IP的⾼级协议
默认端⼝号:80
基于请求/响应模型:⼀次请求对应⼀次响应
特点:
1、简单快速。客户端向服务器请求服务时,只需要传送请求⽅法和路径。
2、灵活。HTTP协议允许传送任意格式的数据。正在传输的类型由,content-type标明。
3、⽆连接。就是每个请求都建⽴⼀个连接,请求处理完毕并发送⾄客户端之后就断开连接。这样明显有其缺点,就是在需要连续发送请求时,需要为每⼀个请求单独的再次建⽴连接,很浪费时间和资源。于是在HTTP协议1.1版本之后引⼊了可持续连接,也就是再每⼀个请求处理完毕后,它不会⽴刻就断开连接,⽽是再等待⼀段时间,如果在此期间⼜有新的请求过来,那么等待时间刷新,如果没有,则等待时间完毕后,连接关闭。
4、⽆状态。是指协议对于每次请求的处理没有记忆能⼒,它不知道之前是否已经访问过,不保留访问痕迹。主要⽬的是为了保证数据传输的安全性。
1.3、传输数据的特点
1.3.1、请求
请求分为三部分:
请求⾏ : 请求⾏中,我们可以通过request对象的相应⽅法获取到⽐如协议名、服务名、端⼝号、项⽬名称、请求⽅式、参数列表等信息。
请求头 : 请求头是当前对⽤户发送的数据的描述信息。请求头信息在请求的时候不需要程序员⼿动添加,是浏览器发送的时候已经处理好的。
请求体 : 请求体就是请求中携带的数据,也就是我们需要获取的参数。
1.3.2、响应
响应分为三部分:
响应⾏ : 响应⾏中包含协议和版本
响应头 : 服务器想要告诉浏览器 的⼀些信息。写法格式:头名称:值
响应体 : 服务器响应给浏览器的源码信息和状态码
1xx -信息,服务器收到请求,需要请求者继续执⾏操作
2xx -成功,操作被成功接收并处理
3xx -重定向,需要进⼀步的操作以完成请求
4xx -客户端错误,请求包含语法错误或⽆法完成请求
5xx -服务器错误,服务器在处理请求的过程中发⽣了错误
二、Servlet详解
2.1、概念
servlet 是运⾏在 Web 服务器中的⼩型 Java 程序。servlet 通常通过 HTTP(超⽂本传输协议)接收和响应来⾃ Web 客户端的请求
简单理解:
我们之前讲的JDBC技术是⽤来实现Java语⾔和数据库之间的连接技术,⽽现在⼜涉及到Java和HTML进⾏连接,此时可以由HTML做前台,java做后台进⾏连接,这时候就需要⼀个中间件(Servlet)。
2.2、使用
2.2.1、准备工作
需求:写⼀个HTML⻚⾯将⼀个表单中的账号和密码传递到java类中并打印输出到控制台。
2.2.2、编写步骤
编写步骤:
1、创建HTML⻚⾯并设计⼀个表单
2、创建⼀个普通类, 并继承HTTPServlet抽象类, 并重写Service⽅法
3、在web.xml⽂件中注册servlet, 作为前后台连接的中间件
4、 修改前台表单中action的请求地址
5、 通过浏览器输⼊对应的地址来访问测试
2.2.3、实现方式
1、创建HTML⻚⾯并设计⼀个表单
<!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title>
</head> <body>
<!-- 设计⼀个⻚⾯, 并设计表单 /项⽬名/访问地址 -->
<form action="" method="post">
<p>
账号: <input type="text" name="username" id="username">
</p>
<p>
密码: <input type="password" name="password" id="password">
</p>
<p>
<input type="submit" value="登录">
</p>
</form>
</body>
</html>
2、创建⼀个普通类, 并继承HTTPServlet抽象类, 并重写Service⽅法
public class LoginServlet extends HttpServlet {
//并重写Service⽅法
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("账号为: " + username + " ==> 密码为: " + password);
}}
3、 在web.xml⽂件中注册servlet, 作为前后台连接的中间件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<!--注册servlet-->
<servlet>
<servlet-name>login</servlet-name><!--servlet名称-->
<servlet-class>com.ujiuye.servlet.LoginServlet</servlet-class><!--全路径-->
</servlet>
<!--映射路径/虚拟路径-->
<servlet-mapping>
<servlet-name>login</servlet-name><!--servlet名称-->
<url-pattern>/login</url-pattern><!--访问路径, 以 / 开头-->
</servlet-mapping>
</web-app
4、修改前台表单中action的请求地址
<!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title>
</head> <body>
<!-- 设计⼀个⻚⾯, 并设计表单 /项⽬名/访问地址 -->
<form action="login" method="post">
<p>
账号: <input type="text" name="username" id="username">
</p>
<p>
密码: <input type="password" name="password" id="password">
</p>
<p>
<input type="submit" value="登录">
</p>
</form>
</body>
</html>
5、通过浏览器输⼊对应的地址来访问测试
2.3、实现过程
实现过程:
① 当服务器接收到客户端浏览器的请求后,先解析请求的url路径,获取访问Servelt的资源路径
② 查找项⽬的web.xml,根据资源路径匹配web.xml中的 中的
③ 如果没有匹配到报 404 如果匹配到了 根据中的
④ 再去匹配 中的 如果没有匹配到 404
⑤ 如果匹配到了执⾏ 中的 从⽽以反射的⽅式访问到指定的Servlet,调⽤其⽅法
2.4、生命周期
servlet⽣命周期:从创建到销毁的全过程。共分为三个阶段:
1、初始化
2、使⽤(提供服务)
3、销毁
1、 编写Servlet
package com.ujiuye.servlet;
import javax.servlet.*;
import java.io.IOException;
public class LifeCycleServlet implements Servlet {
//初始化
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("servlet初始化了...");
}
@Override
public ServletConfig getServletConfig() {
return null; }
//服务
@Override
public void service(ServletRequest request, ServletResponse response) throws
ServletException, IOException {
System.out.println("servlet中的service⽅法执⾏了....");
}
@Override
public String getServletInfo() {
return null; }
//销毁
@Override
public void destroy() {
System.out.println("servlet销毁了...");
}}
- 配置Servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<!--注册servlet-->
<servlet>
<servlet-name>lifeCycle</servlet-name><!--servlet名称-->
<servlet-class>com.ujiuye.servlet.LifeCycleServlet</servlet-class><!--全路径-->
</servlet>
<!--映射路径/虚拟路径-->
<servlet-mapping>
<servlet-name>lifeCycle</servlet-name><!--servlet名称-->
<url-pattern>/lifeCycle</url-pattern><!--访问路径, 以 / 开头-->
</servlet-mapping>
</web-app>
3、测试观察:
当我们启动tomcat服务器时,观察控制台并⽆打印消息,表示Servlet默认情况下在启动服务器时并未被创建。在浏览器地址栏中直接输⼊MyServlet的虚拟访问地址:http://localhost:8080/day10_servlet/lifeCycle 此时观察控制台打印输出初始化与服务的相关信息,当多次访问该地址,发现服务⽅法被多次调⽤执⾏。
通过以上案例发现Servlet默认情况下是在第⼀次访问时被创建并初始化的,为了减少内存的压⼒,我们可否改变它的创建时机呢?
答案是肯定的。我们可以在web.xml⽂件中进⾏配置,使得Servlet在服务器启动时直接创建并初始化。load-on-startup节点必须写在servlet节点的内部,且作为最后⼀个节点。取值必须是整数,如果是⼤于等于0的整数表示在服务器启动时就被创建并初始化,如果有多个Servlet设置了load-on-startup节点的值,那么值越⼩越优先执⾏;如果是负数则表示第⼀次被访问时创建并初始化,也就是默认情况,可以省略不写。
2.5、进化史
Servlet也是由复杂难⽤、功能单⼀,逐步发展到⽬前的操作简单,功能强⼤的。Servlet的发展史,完全就是⼀部⼈类由猿⼈的进化史。
2.5.1、第一阶段
案例:
package com.ujiuye.servlet;
import javax.servlet.*;
import java.io.IOException;
public class ApeManStageServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest request, ServletResponse response) throws
ServletException, IOException {
}
@Override
public String getServletInfo() {
return null; }
@Override
public void destroy() {
}
}
2.5.2、第二阶段
package com.ujiuye.servlet;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class AncientSocialStageServlet extends GenericServlet {
@Override
public void service(ServletRequest request, ServletResponse response) throws
ServletException, IOException {
}}
2.5.3、第三阶段
package com.ujiuye.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ModernityStage extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}}
2.6、注解使用Servlet
2.6.1、介绍
Java 注解(Annotation)⼜称 Java 标注,是 JDK1.5 引⼊的新特性。其主要作⽤是简化复杂的编码⼯作。Java 语⾔中的类、⽅法、变量、参数和包等都可以被标注,被标注的元素就具有了⼀些特定的功能。
Servlet的注解(@WebServlet)是Servlet3.0及以上版本⽀持的,主要⽬的是简化web.xml配置。
2.6.2、实现
package com.ujiuye.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*此注解配置相当于web.xml⽂件中url-pattern设置的访问路径*/
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("注解版Servlet更加简明");
}}
2.6.3、注意事项
1、 ⼀个Servlet的配置可以使⽤注解,也可以使⽤web.xml⽂件,但⼆者不能共存,只能任选其⼀,否则会报错。
2、为什么可以执⾏servlet?
Servlet被实例化了
3、 谁实例化的servlet?
tomcat(servlet容器)实例化的Servlet
4、servlet什么时候实例化的?
第⼀次访问servlet的时候实例化的
5、Servlet被实例化了⼏次?
只被实例化⼀次
6、访问路径 ⼀个servlet可以指定多少个访问路径?
可以指定多个访问路径
2.7、多元化路径
问题 : ⼀个Servlet是否可以配置多个访问路径? 答案是可以的
url-pattern配置⽅式共有三种:
1、完全路径匹配(⼀层路径/指定多层路径) :以 / 开始
例如: /hello , /hello1, /aa/hello2
2、⽬录匹配(多种路径都可以访问 排除已经指定的路径) :以 / 开始 需要以 * 结束.
例如: /(所有), /aaa/ (aaa⽬录下的所有), /aaa/bbb/*
3、 扩展名匹配(后缀名) :不能以 / 开始 以 * 开始的.
例如: *.do , .action 注意: 错误的写法 : /.do
案例
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<!--注册servlet-->
<servlet>
<servlet-name>hello</servlet-name><!--servlet名称-->
<servlet-class>com.ujiuye.servlet.HelloServlet</servlet-class><!--全路径-->
</servlet>
<!--映射路径/虚拟路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name><!--servlet名称-->
<url-pattern>/hello</url-pattern><!--访问路径, 以 / 开头-->
<!-- ⽬录匹配 -->
<url-pattern>/aa/bb/cc</url-pattern>
<url-pattern>/aa/bb/cc/dd/*</url-pattern>
<!-- 扩展名匹配 -->
<url-pattern>*.do</url-pattern>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
三、Servlet处理请求
3.1、介绍
Servlet处理请求是由核⼼⽅法中的request参数处理,处理响应是由核⼼⽅法的response参数处理。
request:定义⼀个向servlet提供客户端请求信息的对象。servlet容器创建⼀个ServletRequest对象,并将其作为参数传递给servlet的服务⽅法。
3.2、作用
接收客户端的请求,获取请求中的信息。除了可以获取请求中携带的数据之外,还可以获取⽐如主机地址、端⼝、请求⽅式、项⽬名称等⼀系列信息。
请求分类:
请求⾏、请求头、请求体。
3.3、体系
ServletRequest 接⼝
↑继承
HttpServletRequest ⼦接⼝
↑ 实现
org.apache.catalina.connector.RequestFacade 实现类
3.4、使用
3.4.1、获取请求行数据
// 1、获取请求信息
//================= 1.1、 获取请求行信息
String scheme = request.getScheme();
System.out.println("协议名:"+scheme);
String serverName = request.getServerName();
System.out.println("服务名:"+serverName);
int serverPort = request.getServerPort();
System.out.println("端口号:"+serverPort);
String contextPath = request.getContextPath();
System.out.println("项目名:"+contextPath);
String method = request.getMethod();
System.out.println("请求方式:"+method);
String queryString = request.getQueryString();
System.out.println("参数字符串:" + queryString);
String requestURI = request.getRequestURI();
System.out.println("项⽬名+具体地址:" + requestURI);
StringBuffer requestURL = request.getRequestURL();
System.out.println("获取请求的URL:" + requestURL);
String servletPath = request.getServletPath();
System.out.println("获取请求的URL:" + servletPath);
3.4.2、获取请求头数据
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//获取请求体信息
String username = request.getParameter("username");
String pswd = request.getParameter("pswd");
// System.out.println(username+"=="+pswd);
String[] hobbys = request.getParameterValues("hobbys");
System.out.println(username+"==="+pswd+"==="+hobbys);
// 获取所有的名字,然后遍历
Enumeration<String> names = request.getParameterNames();
while(names.hasMoreElements()){
String name = names.nextElement();
String[] parameterValues = request.getParameterValues(name);
System.out.println(name+":\t"+ Arrays.toString(parameterValues));
}
System.out.println("======================================================");
// 获取所有的name 和 对应的 value 封装到集合中
Map<String, String[]> map = request.getParameterMap();
for (Map.Entry<String, String[]> entry : map.entrySet()) {
System.out.println(entry.getKey()+"-----"+Arrays.toString(entry.getValue()));
}
}
3.4.3、获取请求正文数据
① get⽅式提交 将数据拼接在url后⾯
http://IP地址:端⼝号/项⽬名/⽂件名?name=xiaoming&password=123
② post⽅式提交
使⽤form表单
③ 常⽤⽅法
1、request.getParameter(“name值”); 获取⼀个name值对应单个数据
2、 request.getParameterValues(“name值”); 获取⼀个name值对应多个数据
3、 request.getParameterNames(); 获取所有的name值
4、request.getParameterMap(); 获取所有信息 放⼊map中
④ 将form数据封装到实体类对象中
BeanUtils ⼯具类
BeanUtils.populate(bean,map);
⑤ 其他⽅法
1、getContextPath() ; 获取当前访问的项⽬名
2、getCookies(); 获取浏览器请求时携带的cookie
3、 getMethod() ; 获取请求⽅式
4、getSession(); 获取session对象
5、request.setCharacterEncoding(“UTF-8”); 设置请求编码
3.4.4、转发
① 理解
⼀种在服务器内部资源跳转的⽅式。浏览器请求ServletA资源时,ServletA资源不⾜或者没有资源,ServletA请求其他的资源然后响应给浏览器,这个过程叫转发;
② 实现
request.getRequestDispatcher("转发路径").forward/include(request, response);
③ 场景
借钱:
1、 全部直接借
2、 ⼀部分⾃⼰的钱 ⼀部分找别⼈借
3、全部找别⼈借
④ 特点:
1、 转发发⽣在服务器内部
2、转发的过程中url地址不变 浏览器不知道
3、转发可以访问到 WEB-INF 中的资源
4、转发的路径是当前项⽬下 因此转发不可以访问项⽬以外的资源
5、 转发的路径⼀般是相对路径
6、转发发⽣⼀次请求中
⑤ 作⽤
实现Servlet与⻚⾯的跳转
四、Servlet处理响应
4.1、介绍
response:定义⼀个对象来帮助servlet向客户端发送响应。servlet容器创建⼀个ServletResponse对象,并将其作为参数传递给servlet的服务⽅法。
4.2、作用
针对⻚⾯发送的请求做出数据响应,向⻚⾯输出信息,包括⽂本、图⽚、视频等。
响应分类:
响应⾏、响应头、响应体。
4.3、体系
ServletResponse 接⼝
↑继承
HttpServletResponse ⼦接⼝
↑ 实现
org.apache.catalina.connector.ResponseFacade 实现类
4.4、使用
4.4.1、设置响应行
设置响应⾏:响应⾏中包含协议和状态码
可以通过response.sendError(sc, msg)来设置状态信息,但⼀般不会⼿动设置,仅⽤来做测试。
// ============== 3.1 响应行信息 ==============
try {
int i = 10/0;
} catch (Exception e) {
response.sendError(500, "除数不能为零呀!");
}
4.4.2 、设置响应头
设置响应头信息可以通过以下两种⽅法:
response.setHeader(“Content-Type”, “text/html;charset=utf-8”);
response.addHeader(“Content-Type”, “text/html;charset=utf-8”);
⼆者的区别:
response.setHeader(String name, String value);⼀个关键字对应⼀个值,如果设置了多个值,则
会覆盖。
response.addHeader(String name, String value);⼀个关键字可以对应多个值
在实际开发中,同⼀个响应头信息只会对应⼀个值,所以在使⽤时⼀般没什么区别。
// =============== 3.2 响应头信息 服务器告诉浏览器做什么 ===============
response.setHeader("xxx", "heihei");
response.setContentType("text/html; charset=utf-8");
4.4.3、 设置响应体
响应的数据就是响应体。响应对象response在返回数据、响应数据的时候,会将⼀些HTML、text、流数据等信息通过响应主体返回给⻚⾯,⽽响应体绝⼤多数都是⽂本类型。
响应数据需要通过流来进⾏数据传输,⽽response⾃带的流有两个:
response.getWriter() ==> PrintWriter 输出⽂本信息
response.getOutputStream ==> ServletOutputStream 输出字节信息,⽐如图⽚、⾳频、视频
需要注意:这两个流不能同时存在。
// =============== 3.3 响应正文信息 ==============
// 3.3.1 响应文本信息
PrintWriter writer = response.getWriter();
writer.print("<h2>hello, I am Tomcat!</h2>");
响应流下载案例
// 3.3.2 响应流信息 (图片下载的案例)
// 文件 从服务器 通过浏览器 下载到磁盘
// 1. 读取文件到内存中
// 根据web目录下的相对路径 获取真实路径
String realPath = request.getServletContext().getRealPath("img/slj.jpeg");
// System.out.println("真实路径:"+realPath);
FileInputStream fis = new FileInputStream(realPath);
// 2. 告诉浏览器该文件要下载
response.setHeader("Content-disposition", "attachment; filename=slj.jpeg");
// 3. 写出到客户端(响应流)
ServletOutputStream sos = response.getOutputStream();
byte[] buff = new byte[1024*2];
int len = 0;
while((len=fis.read(buff))!=-1){
sos.flush();
sos.write(buff, 0, len);
}
// 4. 关流
sos.close();
fis.close();
4.4.4、重定向
① 理解
重定向是客户端⾏为,当客户端浏览器向AServlet发送⼀个请求,经过处理后向客户端做出响应,这个响应就是向服务器再次发送新的请求,去请求BServlet,⽽这个新请求的地址将为浏览器做出第⼆次响应,此时浏览器地址栏会发⽣改变,由于⼀次请求/响应结束后,request对象会⾃动销毁,所以两次请求的request对象并⾮同⼀个,所以两次请求域中的数据信息不会共享。由此可⻅,重定向是做了两次请求和响应。
② 实现
response.sendRedirect("重定向地址");
③ 场景
借钱:
不借,但告诉你谁有钱并指定地址
④ 特点
1、 重定向发⽣在浏览器和服务器之间
2、重定向的过程url地址发⽣变化
3、重定向发⽣⾄少两次请求中
4、 重定向访问不到WEB-INF的资源第5节:域对象
5、重定向可以访问当前应⽤外的资源
6、 重定向⼀般使⽤绝对路径
⑤ 作⽤
实现Servlet与⻚⾯的跳转
五、域对象
5.1、理解
可以共享的对象 提供给servlet之间数据共享 作⽤于服务器
5.2、分类
1、ServletContext 最⼤的共享域 作⽤范围整个项⽬
2、 session 作⽤范围⼀次会话
3、 request 作⽤范围⼀次请求
5.3、使用
1、给共享域中放值 setAttribute(“string”,“object”);
2、获取共享域的值 getAttribute(“string”);
3、删除共享域的值 removeAttribute(“string”);
示例:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 域对象中保存数据
ServletContext servletContext = request.getServletContext();
servletContext.setAttribute("sc", "最大域对象中的数据");
HttpSession session = request.getSession();
session.setAttribute("se", "一次会话中数据共享");
request.setAttribute("req", "一次请求中数据共享");
request.getRequestDispatcher("getYuObj").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取域对象中数据
ServletContext servletContext = request.getServletContext();
String sc = (String) servletContext.getAttribute("sc");
System.out.println("sc中的数据:"+sc);
HttpSession session = request.getSession();
String se = (String) session.getAttribute("se");
System.out.println("session中的数据:"+se);
String req = (String) request.getAttribute("req");
System.out.println("request中的数据:"+req);
}
session = request.getSession();
session.setAttribute(“se”, “一次会话中数据共享”);
request.setAttribute("req", "一次请求中数据共享");
request.getRequestDispatcher("getYuObj").forward(request, response);
}
```java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取域对象中数据
ServletContext servletContext = request.getServletContext();
String sc = (String) servletContext.getAttribute("sc");
System.out.println("sc中的数据:"+sc);
HttpSession session = request.getSession();
String se = (String) session.getAttribute("se");
System.out.println("session中的数据:"+se);
String req = (String) request.getAttribute("req");
System.out.println("request中的数据:"+req);
}