Servlet是JavaEE规范(接口)之一,是JavaWeb三大组件之一,三大组件分别是Servlet程序、Filter过滤器、Listener监听器。Servlet是运行在服务器上的小型java程序,通常通过Http(超文本传输协议)接受和响应来自Web客户端的请求。
1.编写一个类实现Servlet接口;
2.实现service方法,处理请求并响应数据;
package com.pero.servlet.servlet_for_web;import jakarta.servlet.*;
import jakarta.servlet.http.HttpServlet;import java.io.IOException;public class HelloServlet implements Servlet {public HelloServlet() {System.out.println("1构造器被调用");}@Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("2初始化方法init被调用");}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("3service方法被调用");}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {System.out.println("4销毁方法");}
}
3.到web.xml中配置Servlet程序访问地址
HelloServlet com.pero.servlet.servlet_for_web.HelloServlet HelloServlet /hello
4.在客户端(浏览器)输入http://ip地址:port端口号/工程路径/资源路径来访问服务器,通过IP地址定位服务器,通过端口号定位tomcat,通过工程路径确定访问工程(查找web.xml中的servlet和servletmapping,通过servlet和servletmapping找到相应的类执行功能代码)。
1.执行Servlet构造方法(在第一次访问时创建servlet程序会被调用,并且只会被调用一次)
2.执行inti初始化方法(在第一次访问时创建servlet程序会被调用,并且只会被调用一次)
3.执行service方法(每次访问都会调用)
4.执行destroy销毁方法(在Web工程停止时会被调用)
通过service方法中获取请求方式,然后根据不同的请求方式调用不同的请求方法
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {//类型转换HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;//获取请求方式String method = httpServletRequest.getMethod();if ("GET".equals(method)){doGet();} else if ("POST".equals(method)) {doPost();}}/*** doGet方法*/public void doGet(){System.out.println("get请求");System.out.println("get请求");}/*** doPost方法*/public void doPost(){System.out.println("post请求");System.out.println("post请求");}
Title
在实际开发过程中都是使用继承HttpServlet类的方式实现Servlet程序
1.编写一个类继承HttpServlet类
2.根据业务需求编写doGet或者doPost方法
package com.pero.servlet.servlet_for_web;import jakarta.servlet.*;
import jakarta.servlet.http.*;import java.io.IOException;public class HelloServlet2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("HelloServlet2的doGet方法");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("HelloServlet2的doPost方法");}
}
3.到web.xml中配置Servlet程序的访问地址
HelloServlet2 com.pero.servlet.servlet_for_web.HelloServlet2 HelloServlet2 /hello2
鼠标右键点击目标文件包->new->Servlet->编辑Servlet属性并创建
package com.pero.servlet;import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;import java.io.IOException;@WebServlet(name = "HelloServlet3", value = "/HelloServlet3")
public class HelloServlet3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("HelloServlet3的doGet方法");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("HelloServlet3的doPost方法");}
}
Interface Servlet | Servlet接口负责定义Servlet程序的访问规范 |
实现↑接口 | |
Class GenericServlet | GenericServlet类实现了Servlet接口,做了许多空实现 持有ServletConfig类的引用,对ServletConfig的使用做一些方法 |
继↑承 | |
Class HttpServlet | HttpServlet抽取类实现了Service()方法,实现了请求的分发处理 String method = req.getMethod(); ↓ ↓ GET POST ↓ ↓ doGet() doPost() 负责抛出异常,表达不支持Get/Post请求 |
继↑承 | ↑ 重写 ↑ |
自定义Servlet程序 | doGet() doPost() 根据业务需要重写doGet或doPost方法 |
ServletConfig类是Servlet程序的配置信息类,Servlet程序和ServletConfig对象都是由Tomcat负责创建,程序员负责使用,每一个Servlet程序创建时就创建一个对应的ServletConfig对象,主要有三个作用:
1.获取Servlet程序的别名servlet-name的值
2.获取初始化参数init-param
3.获取ServletContext对象
public void init(ServletConfig servletConfig) throws ServletException {System.out.println("2初始化方法init被调用");//1.获取Servlet程序的别名servlet-name的值System.out.println("HelloServlet程序的别名是:" + servletConfig.getServletName());//2.获取初始化参数init-paramSystem.out.println("HelloServlet程序初始化参数username:" + servletConfig.getInitParameter("username"));System.out.println("HelloServlet程序初始化参数url:" + servletConfig.getInitParameter("url"));//3.获取ServletContext对象System.out.println("HelloServlet程序的ServletContext对象:" + servletConfig.getServletContext());}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package jakarta.servlet;import java.util.Enumeration;public interface ServletConfig {String getServletName();ServletContext getServletContext();String getInitParameter(String var1);Enumeration getInitParameterNames();
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package jakarta.servlet;import java.io.IOException;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.ResourceBundle;public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {private static final long serialVersionUID = -8592279577370996712L;private static final String LSTRING_FILE = "jakarta.servlet.LocalStrings";private static ResourceBundle lStrings = ResourceBundle.getBundle("jakarta.servlet.LocalStrings");private transient ServletConfig config;......
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package jakarta.servlet;import jakarta.servlet.descriptor.JspConfigDescriptor;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.Map;
import java.util.Set;public interface ServletContext {String TEMPDIR = "jakarta.servlet.context.tempdir";String ORDERED_LIBS = "jakarta.servlet.context.orderedLibs";String getContextPath();ServletContext getContext(String var1);......
}
注意:重写init方法时必须添加super.init(config)
1.ServletContext接口表示Servlet程序的上下文对象
2.一个web工程只有一个ServletContext对象实例
3.ServletContext对象是一个域对象,是可以像Map对象一样存储数据的对象,存储数据用setAttribute()方法,取数据用getAttribute()方法,删除数据用removeAttribute()方法
4.ServletContext实在web工程部署启动的时候创建,在web工程停止的时候销毁
常见作用如下:
1.获取web.xml配置的上下文参数context.param
2.获取当前工程路径,格式:/工程路径
3.获取工程部署后在服务器硬盘上的绝对路径
4.像Map一样存取数据
username context password root
package com.pero.servlet.servlet_for_web;import jakarta.servlet.*;
import jakarta.servlet.http.*;import java.io.IOException;public class ContextServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {ServletContext servletContext = getServletContext();//1.获取web.xml配置的上下文参数context.paramString username = servletContext.getInitParameter("username");System.out.println(username);String password = servletContext.getInitParameter("password");System.out.println(password);//2.获取当前工程路径,格式:/工程路径String contextPath = servletContext.getContextPath();System.out.println(contextPath); // /Servlet_For_Web//3.获取工程部署后在服务器硬盘上的绝对路径String realPath = servletContext.getRealPath("/"); //E:\IdeaProjects\Web_Servlet\Servlet_For_Web\target\Servlet_For_Web-1.0-SNAPSHOT\System.out.println(realPath);//4.像Map一样存取数据System.out.println("存储数据之前获取数据"+servletContext.getAttribute("key")); //存储数据之前获取数据nullservletContext.setAttribute("key","value");System.out.println("存储数据之后获取数据"+servletContext.getAttribute("key")); //存储数据之后获取数据value
// servletContext.removeAttribute("key");
// System.out.println("删除数据之后获取数据"+servletContext.getAttribute("key"));System.out.println(servletContext); //org.apache.catalina.core.ApplicationContextFacade@2881b8a8}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
package com.pero.servlet.servlet_for_web;import jakarta.servlet.*;
import jakarta.servlet.http.*;import java.io.IOException;public class ContextServlet2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {ServletContext servletContext = getServletContext();System.out.println(servletContext); //org.apache.catalina.core.ApplicationContextFacade@2881b8a8System.out.println("存储数据之后获取数据"+servletContext.getAttribute("key")); //存储数据之后获取数据value}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
客户端和服务器端之间通信时发送数据需要遵守的规则称为HTTP协议,HTTP协议中的数据叫做报文。客户端给服务器发送数据叫做请求,服务器给客户端发送数据叫做响应。
①请求行:
请求方式:GET;
请求的资源路径[+?+请求参数];
请求的协议版本号:HTTP/1.1
②请求头:key:value组成,不同的键值对表示不同的含义
Accept:告诉服务器客户端可以接收的数据类型
Accept-Language:告诉服务器客户端可以接收的语言类型
zh_CN:中文中国
en_US:英文美国
User_Agent:浏览器的信息
Accept-Encoding:告诉服务器客户端可以接收的数据编码(压缩)格式
Host:表示请求的服务器ip和端口号
Connection:告诉服务器请求连接如何处理
Keep-Alive:告诉服务器回传数据不要马上关闭,保持一小段时间的链接
Closed:马上关闭
①请求行:
请求方式:POST;
请求的资源路径[+?+请求参数];
请求的协议版本号:HTTP/1.1
②请求头:key:value组成,不同的键值对表示不同的含义
Accept:表示客户端可以接收的数据类型
Accept-Language:表示客户端可以接收的语言类型
Referer:表示请求发起时浏览器地址栏中的地址(从哪里来的)
User-Agent:表示浏览器的信息
Content-Type:表示发送的数据类型
application/x-www-form-urlencoded:表示提交的数据格式是name=value&name=value,然后对其进行url编码,url编码就是把非英文内容转换为:%xx%xx
multipart/form-data:表示以多段的形式提交数据给服务器(以流的形式提交,用于上传)
Content-Length:表示发送数据的长度
Connection:告诉服务器请求连接如何处理
Cache-Control:表示如何控制缓存,no-cache不缓存
空行
③请求体:发送给服务器的数据
1.form标签method=get
2.a标签
3.link标签引入css
4.Script标签引入js文件
5.img标签引入图片
6.iframe引入html页面
7.在浏览器地址栏中输入地址后敲回车键
1.form标签method=post
1.相应行
①相应的协议和版本号 HTTP/1.1
②响应状态码 200
③响应状态描述符 OK
2.响应头
①key:value 不同响应头,有其不同含义
Server:表示服务器的信息
Content-Type:表示响应体的数据类型
Content-Length:响应体的长度
Date:请求响应的时间(格林时间)
空行
3.响应体(回传给客户端的数据)
①200:表示请求成功
②302:表示请求重定向
③404:表示请求服务器已收到,但是要的数据不存在
④500:表示服务器已经收到请求,但是服务器内部错误(代码错误)
MIME是HTTP协议中的数据类型,全称为“Multipurpose Internet Mail Extensions”多功能Internet邮件扩充服务,MIME类型的格式是“大类型/小类型”,并与某一种文件的扩展名相对应。
文件 | MIME类型 |
超文本标记语言文本 | .html,.htm text/html |
普通文本 | .txt text/plain |
RTF文本 | .rtf application/rtf |
GIF图形 | .gif image/gif |
JPEG图形 | .jpeg,.jpg image/jpeg |
AU声音文件 | .au audio/basic |
MIDI音乐文件 | .mid,.midi audio/midi,audio/x-midi |
RealAudio音乐文件 | .ra,.ram audio/x-pn-realaudio |
MPEG文件 | .mpg,.mpeg video/mpeg |
AVI文件 | .avi video/x-msvideo |
GZIP文件 | .gz application/x-gzip |
TAR文件 | .tar application/x-tar |
每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中,然后传递到service方法(doGet和doPost)中来使用,可以通过HttpServletRequest对象获取多有请求信息。
①getRequestURI():获取请求的资源路径
②getRequestURL():获取请求的统一资源定位符(绝对路径)
③getRemoteHost():获取客户端的ip地址
④getHeader():获取请求头
⑤getParameter():获取请求参数
⑥getParameterValues():获取请求参数(多个值的时候使用)
⑦getMethod():获取请求方式GET或POST
⑧setAttribute(key,value):设置域数据
⑨getAttribute(key):获取域数据
⑩getRequestDispatcher():获取请求转发对象
package com.pero.request.request_servlet;import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;public class RequestAPIServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//①getRequestURI():获取请求的资源路径System.out.println("URI:" + req.getRequestURI()); //URI:/Request_Servlet/request//②getRequestURL():获取请求的统一资源定位符(绝对路径)System.out.println("URL:" + req.getRequestURL()); //URL:http://localhost:8080/Request_Servlet/request//③getRemoteHost():获取客户端的ip地址System.out.println("客户端ip地址是:" + req.getRemoteHost()); //客户端ip地址是:0:0:0:0:0:0:0:1//④getHeader():获取请求头System.out.println("请求头:" + req.getHeader("User-Agent")); //请求头:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36//⑦getMethod():获取请求方式GET或POSTSystem.out.println("请求方式:"+req.getMethod()); //请求方式:GET}
}
package com.pero.request.request_servlet;import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;
import java.util.Arrays;public class ParameterServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取请求参数String username = req.getParameter("username");String password = req.getParameter("password");String[] hobbies = req.getParameterValues("hobby");System.out.println(username + password+ Arrays.asList(hobbies));}
}
Title
ParameterServlet com.pero.request.request_servlet.ParameterServlet
ParameterServlet /parameterServlet
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doPost");//设置请求体的字符集为utf-8,从而解决post请求的中文乱码问题//必须在获取请求参数之前调用该方法才有效req.setCharacterEncoding("UTF-8");//获取请求参数String username = req.getParameter("username");String password = req.getParameter("password");String[] hobbies = req.getParameterValues("hobby");System.out.println(username + password+ Arrays.asList(hobbies));}
服务器收到请求后,从一个资源跳转到另一个服务器资源的操作叫做请求转发
客户端 | 服务器端 | |||||
http://ip:port/工程名/servlet1 用户收到最终的结果 | Servlet1 | Servlet2 | ||||
→ | 1.有没有带请求的参数(办事材料) 2.处理完业务,加盖一个章(request.setAttribute("key",value)) 3.问路,Servlet2怎么走(request.getRequestDispatcher()) 4.走到Servlet2(requestDispatcher.forward()) | 从Servlet1到Servlet2的操作 → 叫做请求转发 | 1.获取请求参数(查看材料) 2.检查有没有Servlet1的章 3.处理自己的业务 | |||
← | Servlet1和Servlet2可以共同完成一项业务功能 ← (Servlet2处理完业务后响应是经过Servlet1后传递给客户端) | |||||
请求转发特点:
①浏览器地址栏没有变化
②Servlet1和Servlet2处理的请求是一次请求
③Servlet1和Servlet2共享Request域中的数据
④可以通过请求转发将请求访问地址转到WEB-INF目录下
⑤请求转发不能够访问工程以外的资源
package com.pero.request.request_servlet;import jakarta.servlet.*;
import jakarta.servlet.http.*;import java.io.IOException;public class Servlet1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取请求参数String username = request.getParameter("username");System.out.println("在Servlet1中查看参数:" + username);//给材料盖章并传递到Servlet2查看request.setAttribute("key","Servlet1的章");//问路:Servlet2怎么走/*** 请求转发必须要以"/"打头,斜杠表示地址为:http://ip:port/工程名/,映射到idea代码的web目录
*///RequestDispatcher requestDispatcher = request.getRequestDispatcher("/servlet2");//RequestDispatcher requestDispatcher = request.getRequestDispatcher("/WEB-INF/form.html");RequestDispatcher requestDispatcher = request.getRequestDispatcher("http://www.baidu.com");//走向Servlet2requestDispatcher.forward(request,response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
package com.pero.request.request_servlet;import jakarta.servlet.*;
import jakarta.servlet.http.*;import java.io.IOException;public class Servlet2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取请求参数String username = request.getParameter("username");System.out.println("在Servlet2中查看参数:" + username);//查看Servlet1中是否盖章Object key = request.getAttribute("key");System.out.println("查看Servlet1中是否有盖章" + key);//处理自己的业务System.out.println("Servlet2处理自己的业务");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
Servlet1 com.pero.request.request_servlet.Servlet1 Servlet2 com.pero.request.request_servlet.Servlet2 Servlet2 /servlet2 Servlet1 /servlet1
base标签可以设置当前页面中所有相对路径工作时,参照哪个路径来进行跳转。
package com.pero.request.request_servlet;import jakarta.servlet.*;
import jakarta.servlet.http.*;import java.io.IOException;public class ForWardC extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("经过ForWardC程序");request.getRequestDispatcher("/a/b/c.html").forward(request,response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
首页
这是web下的index.html页面
a/b/c.html请求转发:a/b/c.html
Title
这是a下的b下的c.html页面跳回首页
ForWardC com.pero.request.request_servlet.ForWardC ForWardC /forWardC
当点击a标签进行跳转时,浏览器地址栏中的地址为:http://localhost:8080/Request_Servlet/a/b/c.html 跳转回a标签路径是:../../index.html 所有相对路径在工作时候都会参照当前浏览器地址栏中的地址来进行跳转。 那么参照后得到的地址:http://localhost:8080/Request_Servlet/index.html 该路径为正确的路径 |
base标签可以设置当前页面中所有相对路径工作时,参照哪个路径来进行跳转。 |
当使用请求转发进行跳转时,浏览器地址栏中的地址是:http://localhost:8080/Request_Servlet/forWardC 跳转回a标签路径是:../../index.html 所有相对路径在工作时候都会参照当前浏览器地址栏中的地址来进行跳转。 那么参照后得到的地址:http://localhost:8080/index.html 该路径为错误路径 |
Title
这是a下的b下的c.html页面跳回首页
相对路径:
. 表示当前目录
.. 表示上一级目录
资源名 表示当前目录/资源名
绝对路径:
http://ip:port/工程路径/资源路径
在Web中 / 斜杠是一种绝对路径
/ 斜杠如果被浏览器解析,得到的地址是:http://ip:port/
例如:斜杠
/ 斜杠如果被服务器解析,得到的地址是:http://ip:port/工程路径
例如:①
②servletContext.getRealpath("/");
③request.getRequestDispatcher("/");
特殊情况:response.sendRediect("/"); 把斜杠发送给浏览器解析,得到http://ip:port/
每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序去使用,HttpServletRequest表示请求过来的信息,HttpServletResponse表示所有响应的信息,如果需要设置返回给客户端的信息,都需要通过HttpServletResponse对象来进行设置
①字节流: reponse.getOutputStream(); 常用于下载(传递二进制数据)
②字符流:response.getWriter(); 常用于回传字符串(常用)
★注意:两个流只能使用一个,使用了字符流就不能使用字节流,反之亦然,否则报错
package com.pero.request.request_servlet;import jakarta.servlet.*;
import jakarta.servlet.http.*;import java.io.IOException;public class ResponseIOServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getWriter();response.getOutputStream(); //报错}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
package com.pero.request.request_servlet;import jakarta.servlet.*;
import jakarta.servlet.http.*;import java.io.IOException;
import java.io.PrintWriter;public class ResponseIOServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {PrintWriter writer = response.getWriter();writer.write("reponse's content!");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
package com.pero.request.request_servlet;import jakarta.servlet.*;
import jakarta.servlet.http.*;import java.io.IOException;
import java.io.PrintWriter;public class ResponseIOServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println(response.getCharacterEncoding()); //UTF-8/*** setContentType()方法必须设置在响应流之前,否则会失效* 会同时设置服务器和客户端都是用UTF-8字符集,并且还设置了响应头*/response.setContentType("text/html;charset=UTF-8"); //解决中文乱码PrintWriter writer = response.getWriter();writer.write("reponse's content!");writer.write("我爱JavaWeb"); //出现乱码}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
客户端(浏览器) | 服务器(Tomcat) | |||
http://ip:port/工程路径/response1 解析Response1的响应结果,得知已经搬迁,再次发起新地址的请求 收到最终的返回响应,解析战士在页面上 | ||||
发送请求 → | Response1程序 随着时间的推移和项目的不断更新升级,Response1这个接口慢慢被废弃,有新的接口Response2所取代。 有义务告知客户端,该端口已经搬迁。=》响应码302 并且告知新的地址。=》响应头Location | |||
← 响应状态码:302 Location响应头,新地址 | ||||
根据新地址再次发送请求 → | Response2程序 Response2程序取代了Response1,功能更加完善,安全性更高。 | |||
← 回传响应 | ||||
package com.pero.request.request_servlet;import jakarta.servlet.*;
import jakarta.servlet.http.*;import java.io.IOException;public class Response1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("到此一游 Response1");request.setAttribute("key","value");//设置响应状态码302,表示重定向(已经搬迁)response.setStatus(302);//设置响应头说明新的地址response.setHeader("Location","http://localhost:8080/Request_Servlet/response2");//response.setHeader("Location","http://localhost:8080/Request_Servlet/WEB-INF/response2"); //不能访问//response.setHeader("Location","https://www.baidu.com"); //可以访问}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
package com.pero.request.request_servlet;import jakarta.servlet.*;
import jakarta.servlet.http.*;import java.io.IOException;public class Response2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println(request.getAttribute("key")); //nullresponse.getWriter().write("response2 result!");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
Response1 com.pero.request.request_servlet.Response1 Response2 com.pero.request.request_servlet.Response2 Response2 /response2 Response1 /response1
①浏览器地址栏会发生变化
②客户端实际是向服务器发送两次请求
③不共享Request域中的数据
④不能访问WEB-INF下的资源
⑤可以访问工程外的资源
package com.pero.request.request_servlet;import jakarta.servlet.*;
import jakarta.servlet.http.*;import java.io.IOException;public class Response1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("到此一游 Response1");request.setAttribute("key","value");//设置响应状态码302,表示重定向(已经搬迁)//response.setStatus(302);//设置响应头说明新的地址//response.setHeader("Location","http://localhost:8080/Request_Servlet/response2");//response.setHeader("Location","http://localhost:8080/Request_Servlet/WEB-INF/response2"); //不能访问//response.setHeader("Location","https://www.baidu.com"); //可以访问//第二种重定向方式response.sendRedirect("http://localhost:8080/Request_Servlet/response2");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}