一、Response 概述
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。
request和response对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向容器或者客户机输出数据,只需要找response对象就行了。
二、Response常用API
HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应报文
response.setStatus(404);
response.setHeader("content-type","text/html;charset=utf-8");
response.getWriter().println("<h1 style='color:red'>File Not Found</h1>");
}
}
三、Response常见应用
1.向客户端输出中文数据
用OutputStream(字节流)发送数据:
1、response.getOutputStream().write(“中国”.getBytes());//以默认本地编码发送数据
2、response.getOutputStream().write(“中国”.getBytes(“UTF-8”));//以UTF-8编码发送数据,浏览器(默认用GB2312)会出现乱码
解决办法:
-
通过更改浏览器的编码方式:IE/”查看”/”编码”/”UTF-8”(不可取)
-
通过设置响应头告知客户端编码方式:response.setHeader(“Content-type”, “text/html;charset=UTF-8”);//告知浏览器数据类型及编码
-
通过meta标签模拟请求头:out.write(“<meta charset=utf-8’ />".getBytes());
-
通过以下方法:response.setContentType(“text/html;charset=UTF-8”);
总结:程序以什么编码输出,就需要告知客户端以什么编码显示。
几个path之间的关系
2.输出字节数据到客户端
传输二进制文件。音视频、图片、文档
四、Response 重定向
1.定时刷新
利用一个refresh响应头,介导浏览器重新跳转到一个新的页面或者刷新当前页面
获取应用名request.getContextPath
其中一个知识点:地址的写法,三种
@WebServlet("/refresh")
public class RefreshServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//第一种写法:每隔多少秒刷新当前页面
response.getWriter().println(new Date());
//response.setHeader("refresh","1");
//第二种用法:指定一个路径,经过指定秒数以后跳转至该页面
//路径的写法:1.全路径
//response.setHeader("refresh","1;url=http://www.cskaoyan.com");
//2.相对路径
response.setHeader("refresh","2;url=1.html");
//3. /应用名/资源路径
response.setHeader("refresh","2;url=" + request.getContextPath() + "/1.html");
}
}
2.重定向
重定向的实现方式:
状态码和Location响应头
其中一个知识点:地址的写法,三种
看到307 302,一定要去reponse header里面找location,这个location的值就是要跳转到的url。
@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setStatus(302);
//地址的写法:3种写法均可以,给浏览器看的
response.setHeader("Location","http://www.cskaoyan.com");
}
}
重定向的简化版API
response.sendRedirect(“地址”),就是上面代码的封装
//response还给我们提供了一个简化版的API
response.sendRedirect("1.html");
页面跳转的比较
转发、定时更新、重定向
区别:
- 转发,浏览器只发送一次请求,其他发送多次请求。
- 转发执行主体是服务器,其他执行主体是浏览器。
- 转发只可以在应用内跳转,其他不受影响。
- 转发是request对象介导的,其他是response介导的。
- 转发可以共享request域,其他不可以。
- 重定向状态码是302,307,其他的都是200。
- 转发地址栏不发生变化,其他发生变化。
登录案例:
loginServlet
package com.cskaoyan.response.login;
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;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//MIME类型有没有写错,如果写错,浏览器不认识,没法解析,就只能下载
//response.setContentType("test/html;charset=utf-8");
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
//JDBC
if("admin".equals(username) && "admin".equals(password)){
//登录成功
//跳转到一个登录成功页面
response.getWriter().println("登录成功,即将跳转至成功页面");
response.setHeader("refresh","2;url=success.html");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/app/login" method="post">
<input type="text" name="username"><br>
<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
五、下载
浏览器的默认行为:
对于可以打开的文件,比如html,TXT,css,js,图片等,默认帮你执行打开操作。
对于无法打开的文件,比如audio,video,exe,zip,默认帮你执行下载操作,
下载功能,针对的是那些浏览器可以打开的部分,如果你不想浏览器打开而是执行将文件下载下来,那么就可以使用下载响应头。
downloadServlet.java
package com.cskaoyan.response.download;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//content-disposition 内容组织方式;attachment:附件
response.setHeader("Content-Disposition","attachment;filename=1.jpg");
//IO流
String realPath = getServletContext().getRealPath("1.jpg");
File file = new File(realPath);
FileInputStream inputStream = new FileInputStream(file);
//还需要有一个outputStream
ServletOutputStream outputStream = response.getOutputStream();
//和下面的我们熟悉的FileOutputStream是兄弟关系
//FileOutputStream
int length = 0;
byte[] bytes = new byte[1024];
while ((length = inputStream.read(bytes)) != -1){
outputStream.write(bytes, 0, length);
}
outputStream.flush();
//关闭流信息
//其中servletOutputStream可以不关,响应结束之前tomcat会帮我们关闭
inputStream.close();
}
}
应用场景:管理系统的统计报表的导出功能,导出需要用到下载响应头。