1.简介
- HttpServletResponse继承了ServletResponse接口,并提供了与Http协议有关的方法,这些方法的主要功能是设置HTTP状态码和管理Cookie。
2.下载文件
public class ResponseTest01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、要获取下载文件的路径
String realPath = "D:\\JAVA\\JavaWebLearnProject\\JavaWebProjectModule\\servlet-02\\src\\main\\resources\\光明.png";
//2、下载的文件名
String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
//3、设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,让URLEncoder.encode(filename,"utf-8")编码支持中文格式,否则有可能乱码
resp.setHeader("Content-Disposition","attachment;filename"+ URLEncoder.encode(filename,"utf-8"));
//4、获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
//5、创建缓冲区
int len=0;
byte[] buffer=new byte[1024];
//6、获取对象
ServletOutputStream os = resp.getOutputStream();
//7、将流写入到buffer缓冲区,使用将缓冲区中的数据输出到客户端
while((len=in.read(buffer))!=0){
os.write(buffer,0,len);
}
in.close();
os.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3.验证码功能实现
public class ImageResponseTest02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//让浏览器3秒自动刷新一次;
resp.setHeader("refresh","3");
//在内存中创建一张图片
BufferedImage bufferedImage = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D graphics = (Graphics2D) bufferedImage.getGraphics();//画笔
//设置图片的背景颜色
graphics.setColor(Color.white);
graphics.fillRect(0,0,80,20);
//给图片写数据
graphics.setColor(Color.blue);
graphics.setFont(new Font(null,Font.BOLD,20));
graphics.drawString(makeNum(),0,20);
//告诉浏览器,这个请求用图片的方式打开
resp.setContentType("image/jpeg");
//网站存在缓存,不让浏览器缓存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(bufferedImage,"jpg",resp.getOutputStream());
}
//生成随机数据
private String makeNum(){
Random random=new Random();
String num=random.nextInt(999999)+"";
StringBuffer stringBuffer=new StringBuffer();
for (int i = 0; i <6-num.length() ; i++) {
stringBuffer.append("0");
}
num=stringBuffer.toString()+num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4.重定向
一个web资源B收到客户端A请求后,然后B会通知客户端A去访问另外一个web资源C,这个过程叫重定向;例如:用户登录、注册账号等。
void sendRedirect(String var1) throws IOException;
public class RedirectResponseTest03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
重定向原理:
resp.setHeader("Location","test07");
resp.setStatus(302);
*/
resp.sendRedirect("test07");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
public class RequestTest03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入了这个请求");
//处理请求
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+":"+password);
//重定向
resp.sendRedirect("success.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<%--
Created by IntelliJ IDEA.
User: 光辉岁月
Date: 2021/1/31
Time: 15:41
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>success</h1>
</body>
</html>
<html>
<body>
<h2>Hello World!</h2>
<%--注意:这里提交的路径,需要寻找到项目的路径,${pageContext.request.contextPath}代表当前的项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
用户名:<input type="text" name="username"> <br>
密码:<input type="password" name="password"> <br>
<input type="submit">
</form>
</body>
</html>
5.转发与重定向中的具体讨论:
-
转发:(状态码:307)
- 转发当中使用带“/”的绝对路径时,表示的是当前web应用的根目录再加上传入的目录,因为转发是在服务器内部进行的,写绝对路径/开头指的是当前的Web应用程序 ;例如:假设当前的web应用目录为http://localhost:8080/web-app 执行req.getRequestDispatcher("/login.jsp") 则这个时候转到的目录为 http://localhost:8080/web-app/login.jsp
- 而当转发中使用的是不带“/”的相对路径的时候,表示的是当前的路径再加上传入的路径;例如假如当前的路径为http://localhost:8080/web-app/abc 执行req.getRequestDispatcher(“login.jsp”) 则这个时候转到的目录为 http://localhost:8080/web-app/abc/login.jsp
-
重定向:(状态码:302)
- 重定向中使用带“/”的绝对路径时,表示的是当前服务器的根目录再加上传入的目录!假设当前的web应用目录为http://localhost:8080/web-app 执行 resp.sendRedirect("/login.jsp") 则这个时候转到的目录为 http://localhost:8080/login.jsp
- 而当重定向中使用的是不带“/”的相对路径的时候,表示的是当前的路径再加上传入的路径(和转发的时候一样);假如当前的路径为http://localhost:8080/web-app/abc 执行req.getRequestDispatcher(“login.jsp”) 则这个时候转到的目录为 http://localhost:8080/web-app/abc/login.jsp
面试题:请您聊聊重定向和转发的区别?
相同点:页面都会实现跳转;
不同点:请求转发的时候,url不会发生变化;重定向的时候,url会发生改变。