目录
1、设置响应数据的流程
- 业务处理完后,后台就需要给前端返回业务处理的结果,即响应数据
- 把响应数据封装到Response对象中
- 后台服务器Tomcat会解析Response对象,按照 响应行+响应头+响应体 格式拼接结果
- 浏览器最终解析结果,把内容展示在浏览器给用户浏览
2、客户端与服务器的通信过程
当Web服务器收到客户端的HTTP请求时,它会为每一次请求分别创建一个用于代表请求的request对象和一个用于代表响应的response对象。这是Servlet容器(如Tomcat)处理HTTP请求的标准过程。
Request对象封装了客户端发送的所有请求信息,包括请求行(请求方法、请求URI、协议版本)、请求头(如User-Agent、Accept-Language等)以及请求体(如表单数据、JSON数据等)。Servlet可以通过Request对象来获取这些信息,并根据这些信息执行相应的业务逻辑。
Response对象用于构建并发送服务器的响应给客户端。Servlet可以通过Response对象设置响应状态码、设置响应头、输出响应体等。一旦Servlet完成了响应的构建,Response对象会将响应发送回客户端。
这个过程允许Web服务器与客户端进行交互,处理客户端的请求,并返回相应的数据或资源。这也是Servlet技术能够动态生成Web内容的核心机制。

3、Response对象
Response对象是Servlet容器(Tomcat)创建的 HttpServletResponse接口的实例。
当客户端发送HTTP请求到Servlet容器时,容器会:
- 解析请求(包括请求行、请求头、请求体等)。
- 根据请求的URL和请求方法(GET、POST等)确定要调用的Servlet。
- 创建一个
HttpServletResponse实例,该实例封装了响应的详细信息(例如状态码、响应头、响应体等)。 - 调用Servlet的相应方法(如
doGet()或doPost()),并将创建的HttpServletResponse实例作为参数传递。
使用Response对象可以设置响应的状态码、添加响应头、写入响应体(即发送给客户端的数据,如 HTML、JSON 等)。
4、方法
Response对象:设置响应消息
1)设置响应行

- void setStatus(int sc):设置HTTP响应的状态码(如200表示OK,404表示Not Found)
2)设置响应头

- void setHeader(String name,String value):设置响应头键值对
3)设置响应体
对于响应体,是通过字符、字节输出流的方式往浏览器写。
3.1)设置字符数据的响应体
要想将字符数据写回到浏览器,需要两个步骤:
第一步:通过Response对象获取字符输出流:
- response.getWriter():返回值为PrintWriter类型的值 writer
第二步:通过字符输出流写数据
- writer.write(String s)
应用举例:返回字符串 乌托邦
@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//content-type,告诉浏览器返回的数据类型是HTML类型数据,这样浏览器才会解析HTML标签
//设置响应的数据格式及数据的编码
response.setContentType("text/html;charset=utf-8");
//1. 获取字符输出流
PrintWriter writer = response.getWriter();
writer.write("乌托邦");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
启动后访问localhost:8080/response-demo/resp1 页面显示 乌托邦
3.2)设置字节数据的响应体
将字节数据写回到浏览器,需要两个步骤:
第一步:通过Response对象获取字节输出流
- resp.getOutputStream():返回值ServletOutputStream os
第二步:通过字节输出流写数据 有2种方法:
- 方法一:os.write(字节数据)
- 方法二:使用工具类IOUtils (更简单易用)
应用举例1:返回一个图片文件到浏览器,使用方法一:
@WebServlet("/resp2")
public class ResponseDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 读取文件
FileInputStream fis = new FileInputStream("d://a.jpg");
//2. 获取response字节输出流
ServletOutputStream os = response.getOutputStream();
//3. 完成流的copy
byte[] buff = new byte[1024];
int len = 0;
while ((len = fis.read(buff))!= -1){
os.write(buff,0,len);
}
fis.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
启动后访问localhost:8080/response-demo/resp1 页面显示 要返回的图片
应用举例2:返回一个图片文件到浏览器,使用方法二:
pom.xml添加依赖
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
@WebServlet("/resp2")
public class ResponseDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 读取文件
FileInputStream fis = new FileInputStream("d://a.jpg");
//2. 获取response字节输出流
ServletOutputStream os = response.getOutputStream();
//3. 完成流的copy
IOUtils.copy(fis,os);
fis.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
启动后访问localhost:8080/response-demo/resp1 页面显示 要返回的图片
5、重定向(redirect)
是一种资源跳转方式:
- 浏览器发送请求给服务器,服务器中对应的资源A接收到请求,但资源A现在无法处理该请求,就会给浏览器响应一个302的状态码+location的一个访问资源B的路径;
- 浏览器接收到响应状态码为302就会重新发送请求到location对应的访问地址去访问资源B;
- 资源B接收到请求后进行处理并最终给浏览器响应结果。
特点:
- 浏览器地址栏路径发生变化:当进行重定向访问的时候,由于是由浏览器发送的两次请求,所以地址会发生变化。
- 可以重定向到任何位置的资源(服务内容、外部均可):因为第一次响应结果中包含了浏览器下次要跳转的路径,所以这个路径是可以任意位置资源。
- 是两次请求,不能在多个资源使用request共享数据:因为浏览器发送了两次请求,是两个不同的request对象,不能通过request对象进行共享数据。
重定向的实现:
- 第一种方式:使用
setStatus和setHeader手动实现重定向:
resp.setStatus(302); // 设置HTTP状态码为302,表示临时重定向
resp.setHeader("Location", "资源B的访问路径"); // 设置Location响应头,指示重定向的目标URL
- 第二种方式(推荐):使用
sendRedirect方法实现重定向,是Servlet API提供的便捷方法来实现重定向,它在内部调用了setStatus和setHeader,并可能处理了其他相关的逻辑。
response.sendRedirect("/request-demo/resp2");
应用举例:
需要创建2个servlet:
@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("这是resp1");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
@WebServlet("/resp2")
public class ResponseDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("这是resp2");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
重定向:在ResponseDemo1的doGet方法中给前端响应数据
@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("这是resp1");
//重定向 方式一
//1.设置响应状态码 302
response.setStatus(302);
//2. 设置响应头 Location
response.setHeader("Location","/request-demo/resp2");
//重定向 方式二
// resposne.sendRedirect("/request-demo/resp2");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
启动访问 http://localhost:8080/response-demo/resp1 控制台打印:
这是resp1
这是resp2
说明/resp1、/resp2都被访问到了,重定向已经完成了。
6、请求转发与重定向的区别

7、路径里是否需要加虚拟目录

浏览器使用:需要加虚拟目录(项目访问路径),
如超链接 <a href='路径'>、form表单 <form action='路径'>、重定向(路径最终是由浏览器发送请求) resp.sendRedirect("路径")。
服务端使用:不需要加虚拟目录,
如请求转发(在服务端进行) req.getRequestDispatcher("路径")。
8、动态获取虚拟目录
推荐动态获取虚拟目录,防止之后用Tomcat插件重新配置项目的访问路径时,需要修改所有重定向的访问地址。

方法:
- 使用request对象方法:request.getContextPath()
- 这个方法返回的是当前请求的上下文路径(Context Path)。
- 上下文路径是部署在 Web 应用程序服务器上的 Web 应用程序的 URL 的一部分。例如,如果 Web 应用程序被部署在
http://example.com/myapp/,那么myapp就是上下文路径。request.getContextPath()通常用于构建相对于上下文路径的资源 URL。
动态获取虚拟目录 修改之后的重定向应用举例:
@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("resp1....");
//方式二完成重定向
//动态获取虚拟目录
String contextPath = request.getContextPath();
response.sendRedirect(contextPath+"/resp2");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
JavaServlet中的响应处理:设置、通信与重定向
本文详细阐述了在JavaServlet中设置响应数据的流程,包括响应行、响应头和响应体的设置,以及客户端与服务器的通信过程。重点介绍了Response对象的使用、重定向与请求转发的区别,以及如何动态获取虚拟目录以适应Web应用程序部署的变化。
891

被折叠的 条评论
为什么被折叠?



