Request: 使用 request对象来获取请求数据
Response: 使用 response对象来设置响应数据
Response
Response体系结构
Response体系结构和Request体系结构是一样的
Response设置响应数据
响应数据同样分为3部分:
响应头
响应行
响应体
设置响应头的方法:
方法名 | 描述 |
---|---|
void setStatus(int sc) | 设置响应状态码 |
设置响应行的方法:
方法名 | 描述 |
---|---|
void setHeader(String name, String value) | 设置响应头键值对 |
设置响应体的方法:
方法名 | 描述 |
---|---|
PrintWriter getWriter() | 获取字符输出流 |
ServletOutputStream getOutputStream() | 获取字节输出流 |
Response完成重定向
重定向(Redirect):一种资源跳转方式
如下图: 浏览器向资源A发送请求, 资源A响应给浏览器, 响应状态码302告知浏览器资源A处理不了, 去找另一个资源, 通过location: xxx的方式告知浏览器去找哪一个资源; 浏览器收到响应后, 再向其他资源发送请求
实现方式:
基本方式
// 设置响应状态码
resp.setStatus(302);
// 设置另一个资源的访问路径
resp.setHeader(“location”,“资源B的路径");
简化方式
resp.sendRedirect("资源B的路径");
示例代码:
基本方式
@WebServlet("/reps1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("reps1...");
// 重定向基本方式
// 1. 设置响应状态码302
response.setStatus(302);
// 2. 设置响应头
response.setHeader("location", "/request-demo/reps2"); // 注意重定向需要添加虚拟目录
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
简化方式
@WebServlet("/reps1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("reps1...");
// 重定向简化方式
response.sendRedirect("/request-demo/reps2");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
重定向的特点:
重定向后浏览器地址栏路径发生变化
可以重定向到任意位置的资源(服务器内部、外部均可)
两次请求,不能在多个资源使用request共享数据
路径问题: 明确路径谁使用?
浏览器使用:需要加虚拟目录(项目访问路径)
服务端使用:不需要加虚拟目录
一旦虚拟路径发生了改变, 我们重定向的固定路径便无法访问, 所有我们需要动态获取虚拟路径:
@WebServlet("/reps1")
public class ResponseDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("reps1...");
// 动态获取虚拟路径
String contextPath = request.getContextPath();
// 重定向
response.sendRedirect(contextPath + "/reps2");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
Response响应字符数据
响应字符数据也就是设置字符数据的响应体, 通过Response对象获取字符输出流, 写数据
PrintWriter writer = resp.getWriter();
writer.write("aaa");
示例代码:
@WebServlet("/reps3")
public class ResponseDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取字符输出流
PrintWriter writer = response.getWriter();
// 告诉浏览器, 响应的数据是html的文件
response.setHeader("content-type", "text/html");
// 写入html数据
writer.write("<h1>abc</h1>");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
细节注意:
该流不需要关闭,随着响应结束,response对象销毁,由服务器关闭
中文数据乱码:原因通过Response获取的字符输出流默认编码:ISO-8859-1, 解决中文编码问题, 我们只需修改字符输出流的编码为: utf-8
@WebServlet("/reps3")
public class ResponseDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 告诉浏览器, 响应的数据是html的文件, 且设置输出流为utf-8编码
response.setHeader("content-type", "text/html;charset=utf-8");
// 获取字符输出流
PrintWriter writer = response.getWriter();
// 写入html数据
writer.write("<h1>你好啊</h1>");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
Response 响应字节数据
通过Response对象获取字节输出流, 写数据
ServletOutputStream outputStream = resp.getOutputStream();
outputStream.write(字节数据);
示例代码: 读取一张图片到网页
@WebServlet("/reps4")
public class ResponseDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 读取图片文件的字节输入流
FileInputStream fis = new FileInputStream("/Users/chenyq/Documents/a.png");
// 获取字节输出流
ServletOutputStream os = response.getOutputStream();
// 完成流的copy
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
fis.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
以前为了联系, 我们是自己编写的流的copy, 现在我们可以使用IOUtils工具类完成copy, 使用方式如下:
导入坐标
<!--IOUtils依赖坐标-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
使用IOUtils的copy方法, 该方法接收一个输入流和一个输出流
IOUtils.copy(输入流,输出流);
@WebServlet("/reps4")
public class ResponseDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 读取图片文件的字节输入流
FileInputStream fis = new FileInputStream("/Users/chenyq/Documents/a.png");
// 获取字节输出流
ServletOutputStream os = response.getOutputStream();
// IOUtils工具类完成流的复制
IOUtils.copy(fis, os);
fis.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}