一、和response相关的方法

1.文件下载

思路:

  1. 使用字节输入流将本地磁盘(服务器中的一个视频)写入到内存中,然后使用response(浏览器行为)字节
  1. package com.qfedu.a_response; /**
  2. * @author wodexinhuai
  3. * @create 2022-05-09-9:53
  4. */
  5. import javax.servlet.*;
  6. import javax.servlet.http.*;
  7. import javax.servlet.annotation.*;
  8. import java.io.BufferedInputStream;
  9. import java.io.File;
  10. import java.io.FileInputStream;
  11. import java.io.IOException;
  12. import java.nio.charset.StandardCharsets;
  13. //文件下载案例
  14. @WebServlet(name = "DownloadServlet", value = "/DownloadServlet")
  15. public class DownloadServlet extends HttpServlet {
  16. @Override
  17. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  18. doPost(request,response);
  19. }
  20. @Override
  21. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  22. //改进 通过url获取文件参数
  23. String file = request.getParameter("file");
  24. //1.获取下载文件的地址,被下载的资源文件一定在服务器里面
  25. ServletContext servletContext = request.getServletContext();
  26. //获取文件编译之后的真实路径
  27. //文件路径
  28. //E:\idea_workspace\day46_509\web\img\1.mp4
  29. //文件编译之后的路径
  30. //E:\idea_workspace\day46_509\out\artifacts\day46_509_war_exploded\img\1.mp4
  31. // String realPath = servletContext.getRealPath("/img/1.mp4");
  32. //改进
  33. String realPath = servletContext.getRealPath("/img/" + file);
  34. //E:\idea_workspace\day46_509\out\artifacts\day46_509_war_exploded\img\1.mp4
  35. System.out.println(realPath);
  36. //2.获取文件的名字 1.mp4
  37. //依靠上面的真实路径realPath 截取最后一个斜线后面的东西
  38. // substring以斜线开始截取 去最后一个斜线+1下标的字符串
  39. String filename = realPath.substring(realPath.lastIndexOf(File.separator) + 1);
  40. //1.mp4
  41. System.out.println(filename);
  42. // response.getWriter().append(filename);//输出在浏览器上会报错 因为response响应也是一个流 只能使用一次之后就关闭了
  43. //3.使用流进行下载,不要使用字符流 使用字节流 因为字符流不能对视频音频进行操作
  44. //将资源从磁盘写到java内存中
  45. BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath));
  46. //4.转换一下文件的名字,不然下载的时候会乱码
  47. //ISO-8859-1 是浏览器自己默认带的字符编码,浏览器的编码不是utf-8
  48. filename = new String(filename.getBytes("utf-8"),"ISO-8859-1");
  49. //5.设置响应头,因为浏览器要下载视频,告知浏览器当前的文件是什么类型,是以什么形式下载的
  50. //“content-disposition”,“attachment;filename=” + 文件名字
  51. //文件以附件的形式下载
  52. response.setHeader("content-disposition","attachment;filename=" + filename);
  53. //6.设置文件类型
  54. //getMimeType 浏览器会自动识别当前文件是什么类型的 比如.gif .mp4 .mp3
  55. String mimeType = request.getServletContext().getMimeType(filename);
  56. //为什么要获取文件类型?下载的文件类型一定要和原来资源文件类型保持一致
  57. response.setContentType(mimeType);
  58. // response.getWriter().append(mimeType);
  59. //7.从内存写入到浏览器
  60. //ServletOutputStream 浏览器的字节输入流
  61. ServletOutputStream os = response.getOutputStream();
  62. byte[] buf = new byte[1024 * 4];
  63. int length = -1;
  64. while ((length = bis.read(buf)) != -1){
  65. os.write(buf,0,length);
  66. }
  67. os.close();
  68. bis.close();
  69. }
  70. }

video.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div>
  9. <div>
  10. <video width="320" height="240" controls="controls">
  11. <source src="video/1什么是编程语言.mp4" type="video/mp4">
  12. </video>
  13. </div>
  14. <div>
  15. <a href="DownloadServlet?file=1什么是编程语言.mp4">下载</a>
  16. </div>
  17. <div>
  18. <video width="320" height="240" controls="controls">
  19. <source src="video/2为什么要学习java.mp4" type="video/mp4">
  20. </video>
  21. <div>
  22. <a href="DownloadServlet?file=2为什么要学习java.mp4">下载</a>
  23. </div>
  24. </div>
  25. </div>
  26. </body>
  27. </html>

简洁版

  1. package com.qfedu.a_fileDownload; /**
  2. * @author wodexinhuai
  3. * @create 2022-05-09-16:44
  4. */
  5. import javax.servlet.*;
  6. import javax.servlet.http.*;
  7. import javax.servlet.annotation.*;
  8. import java.io.BufferedInputStream;
  9. import java.io.File;
  10. import java.io.FileInputStream;
  11. import java.io.IOException;
  12. @WebServlet(name = "DownloadServlet", value = "/DownloadServlet")
  13. public class DownloadServlet extends HttpServlet {
  14. @Override
  15. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  16. String file = request.getParameter("file");
  17. //getRealPath 获取到web当前位置
  18. String realPath = request.getServletContext().getRealPath("/video/" + file);
  19. //获取文件名字 字符串截取
  20. String filename = realPath.substring(realPath.lastIndexOf(File.separator) + 1);
  21. //有真实路径,将文件以字节流形式写入到java内存中
  22. BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath));
  23. //将文件名字转为浏览器编码格式
  24. filename = new String(filename.getBytes("utf-8"),"ISO-8859-1");
  25. //浏览器以附件的形式下载
  26. response.setHeader("content-disposition","attachment;filename=" + filename);
  27. //设置文件类型 现在类型和原始类型一致
  28. String mimeType = request.getServletContext().getMimeType(filename);
  29. response.setContentType(mimeType);
  30. //从磁盘写入到浏览器
  31. ServletOutputStream outputStream = response.getOutputStream();
  32. byte[] bytes = new byte[1024 * 4];
  33. int length = -1;
  34. while((length=bis.read(bytes)) != -1){
  35. outputStream.write(bytes,0,length);
  36. }
  37. outputStream.close();
  38. bis.close();
  39. }
  40. @Override
  41. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  42. doGet(request,response);
  43. }
  44. }

二、会话控制 cookie和session

2.1无状态访问

http协议是一种无状态的访问

浏览器发送请求到服务器之后,服务器会给一定的响应,但是这次响应之后,下次在页面中访问其他页面的时候,服务器不会自动保存当前的状态的。这就是无状态访问

比如:

  1. 登录淘宝,登录上以后,在登陆状态时,点击商品,添加购物车的时候不会保持登陆状态的。
  2. 但是显示开发中保持了状态,登陆淘宝以后,点击购物车无需重新登陆,阿里使用了一种技术:**会话控制技术**

2.2会话技术

cookie

session

2.2.1Cookie

java代码中设置了Cookie以后,保存在浏览器中,每次访问服务器的时候,浏览器会自动把Cookie带到下一个页面,下一个页面直接取Cookie来用即可。

就相当于把用户名存到Cookie中,然后下一个页面再从浏览器中取Cookie

比如:浏览器登陆了百度账号,将用户名和密码存到浏览器中,在点击百度网盘,百度网盘从当前浏览器中取出来Cookie中的用户名和密码来保持登陆状态

Cookie:

  1. 1.保存在浏览器中,可以通过浏览器看到
  2. 2.Cookie的大小是有限制的 4096kb
  3. 3.Cookie信息不能带有中文
  4. 4.Cookie的保存形式是键值对

常用的API:

  1. 1.Cookie有构造方法
  2. CookieString name.String value 实例化,对Cookie设置值
  3. 2.设置Cookie
  4. setCookieString value 修改cookie的值
  5. setMakAgeint time 修改cookie过期时间
  6. 3.cookie发送给浏览器,因为是浏览器保存的cookie
  7. response.addCookiecookie

入门案例:

CookieServlet

  1. package com.qfedu.b_cookie; /**
  2. * @author wodexinhuai
  3. * @create 2022-05-09-11:26
  4. */
  5. import javax.servlet.*;
  6. import javax.servlet.http.*;
  7. import javax.servlet.annotation.*;
  8. import java.io.IOException;
  9. @WebServlet(name = "CookieServlet", value = "/CookieServlet")
  10. public class CookieServlet extends HttpServlet {
  11. @Override
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. doPost(request, response);
  14. }
  15. @Override
  16. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  17. //1.创建cookie对象 同时设置值
  18. Cookie cookie = new Cookie("java2204", "zzw");
  19. //2.对cookie设置过期时间
  20. /**
  21. * setMaxAge() 方法的参数
  22. * 正数:代表当前cookie的有效时间 单位是秒
  23. * 负数:当前浏览器一关闭,cookie就会失效,不关闭浏览器cookie就一直在
  24. * 0:销毁当前的cookie
  25. */
  26. cookie.setMaxAge(30);//cookie30秒后过期
  27. //3.直接发送给浏览器
  28. response.addCookie(cookie);
  29. //给浏览器cookie以后,如果我再次请求另外一个servlet资源的话
  30. //可以在另外一个servlet
  31. }
  32. }

GetCookieServlet

  1. package com.qfedu.b_cookie; /**
  2. * @author wodexinhuai
  3. * @create 2022-05-09-11:31
  4. */
  5. import javax.servlet.*;
  6. import javax.servlet.http.*;
  7. import javax.servlet.annotation.*;
  8. import java.io.IOException;
  9. @WebServlet(name = "GetCookieServlet", value = "/GetCookieServlet")
  10. public class GetCookieServlet extends HttpServlet {
  11. @Override
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. doPost(request, response);
  14. }
  15. @Override
  16. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  17. //1.获取cookie对象 返回值Cookie数组
  18. //JSESSIONID=A27A2061ED2699E1B8E191EB871D43EE; java2204=zzw; Idea-8a2bc478=084504fc-fbef-4082-a03a-05f25cb92dbb
  19. //JSESSIONID 是服务器默认自带的
  20. //java2204=zzw 是自己写的
  21. Cookie[] cookies = request.getCookies();
  22. //遍历
  23. for (Cookie cookie : cookies) {
  24. System.out.println(cookie.getName());//获取键
  25. System.out.println(cookie.getValue());//获取值
  26. }
  27. }
  28. }

DestroyServlet

  1. package com.qfedu.b_cookie; /**
  2. * @author wodexinhuai
  3. * @create 2022-05-09-11:45
  4. */
  5. import javax.servlet.*;
  6. import javax.servlet.http.*;
  7. import javax.servlet.annotation.*;
  8. import java.io.IOException;
  9. //销毁cookie
  10. @WebServlet(name = "DestroyServlet", value = "/DestroyServlet")
  11. public class DestroyServlet extends HttpServlet {
  12. @Override
  13. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  14. doPost(request, response);
  15. }
  16. @Override
  17. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  18. Cookie[] cookies = request.getCookies();
  19. for (Cookie cookie : cookies) {
  20. //销毁cookie
  21. if(cookie.getName().equals("java2204")){
  22. cookie.setMaxAge(0);
  23. //从新发送一次cookie
  24. response.addCookie(cookie);
  25. }
  26. }
  27. }
  28. }

2.2.2Session

和Cookie是一样的功能,都是为了保持状态的

开发中为什么不用Cookie,用Session呢?

1.Cookie保存的数据类型比较单一,只能保存字符串类型的数据

2.Cookie保存的数据最大为4096kb

3.Cookie不能保存中文

综上所诉,开发用Session

session是保存在服务器中的,不是在浏览器啊中,每一个session都会在服务器中都会有一个唯一的标识:JSESSSIONID,可以保存中文,没有大小限制的

Session的API

  1. getSession();获取session对象的
  2. getId();获取sessionID
  3. invalidate();销毁session
  4. setMaxInactiveInterval();设置session过期时间的
  5. setAttribute();设置session内容的
  6. getAttribute();获取session内容的

入门案例:

SessionServlet

  1. package com.qfedu.c_session; /**
  2. * @author wodexinhuai
  3. * @create 2022-05-09-14:18
  4. */
  5. import javax.servlet.*;
  6. import javax.servlet.http.*;
  7. import javax.servlet.annotation.*;
  8. import java.io.IOException;
  9. @WebServlet(name = "SessionServlet", value = "/SessionServlet")
  10. public class SessionServlet extends HttpServlet {
  11. @Override
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. doPost(request, response);
  14. }
  15. @Override
  16. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  17. //1.获取session对象 【重点】
  18. HttpSession session = request.getSession();
  19. System.out.println(session);
  20. //2.获取session唯一标识 JESSIONID【了解】
  21. System.out.println(session.getId());
  22. //3.设置过期时间
  23. session.setMaxInactiveInterval(30);
  24. //4.设置session的值 【重点】 在写一个servlet资源,可以通过name获取
  25. session.setAttribute("name","朱志伟");
  26. }
  27. }

GetSessionServlet

  1. package com.qfedu.c_session; /**
  2. * @author wodexinhuai
  3. * @create 2022-05-09-14:23
  4. */
  5. import javax.servlet.*;
  6. import javax.servlet.http.*;
  7. import javax.servlet.annotation.*;
  8. import java.io.IOException;
  9. @WebServlet(name = "GetSessionServlet", value = "/GetSessionServlet")
  10. public class GetSessionServlet extends HttpServlet {
  11. @Override
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. doPost(request, response);
  14. }
  15. @Override
  16. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  17. //1.获取session对象
  18. // HttpSession session = request.getSession();
  19. //getSession() 默认是true ,如果是false,不会自己新建session对象了
  20. //会使用之前第一次创建好的session对象
  21. HttpSession session = request.getSession(false);
  22. System.out.println(session);
  23. //2.获取session的内容 通过键
  24. Object name = session.getAttribute("name");
  25. System.out.println("这个是session的内容:" + name);
  26. }
  27. }

DestroySessionServlet

  1. package com.qfedu.c_session; /**
  2. * @author wodexinhuai
  3. * @create 2022-05-09-14:38
  4. */
  5. import javax.servlet.*;
  6. import javax.servlet.http.*;
  7. import javax.servlet.annotation.*;
  8. import java.io.IOException;
  9. @WebServlet(name = "DestroySessionServlet", value = "/DestroySessionServlet")
  10. public class DestroySessionServlet extends HttpServlet {
  11. @Override
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. doPost(request,response);
  14. }
  15. @Override
  16. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  17. //
  18. HttpSession session = request.getSession();
  19. session.invalidate();
  20. }
  21. }

三、登录案例

IndexServlet

  1. package com.qfedu.d_login; /**
  2. * @author wodexinhuai
  3. * @create 2022-05-09-14:49
  4. */
  5. import javax.servlet.*;
  6. import javax.servlet.http.*;
  7. import javax.servlet.annotation.*;
  8. import java.io.IOException;
  9. @WebServlet(name = "IndexServlet", value = "/IndexServlet")
  10. public class IndexServlet extends HttpServlet {
  11. @Override
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. response.setContentType("text/html;charset=utf-8");//设置响应编码格式
  14. //1.获取session对象 false 如果没有获取过session对象 就会是个null
  15. HttpSession session = request.getSession(false);
  16. System.out.println(session);//null
  17. // session.setAttribute("user","朱志伟");
  18. //证明设置过session
  19. if (session != null && session.getAttribute("user").equals("朱志伟")){
  20. //session有,且session的值等于朱志伟,才展示主页面
  21. String html = "<font size='7' color='red'>123" + session.getAttribute("user")+ "456</font>";
  22. String html1 = "<a href='LogoutServlet' style='color:pink;font-size:20px'>退出登陆</a>";
  23. response.getWriter().append(html);
  24. response.getWriter().append("<br>");
  25. response.getWriter().append(html1);
  26. }else {
  27. //session没有值挥着session的值没有对应上的情况,跳转到登陆页面
  28. //重定向
  29. response.sendRedirect("login.html");
  30. }
  31. }
  32. @Override
  33. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  34. doGet(request, response);
  35. }
  36. }

login.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>登陆</title>
  6. </head>
  7. <body>
  8. <form action="LoginServlet" method="post">
  9. 姓名:<input type="text" name="user"><br>
  10. 密码:<input type="password" name="pwd"><br>
  11. <input type="submit" name="登录">
  12. </form>
  13. </body>
  14. </html>

LoginServlet

  1. package com.qfedu.d_login; /**
  2. * @author wodexinhuai
  3. * @create 2022-05-09-15:04
  4. */
  5. import javax.servlet.*;
  6. import javax.servlet.http.*;
  7. import javax.servlet.annotation.*;
  8. import java.io.IOException;
  9. @WebServlet(name = "LoginServlet", value = "/LoginServlet")
  10. public class LoginServlet extends HttpServlet {
  11. @Override
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. //设置请求乱码 因为是post请求
  14. request.setCharacterEncoding("utf-8");
  15. String user = request.getParameter("user");
  16. String pwd = request.getParameter("pwd");
  17. //验证信息登陆
  18. //前端的数据会和数据库的数据做对比,如果数据库中有这个数据,
  19. //密码也能匹配成功,就让登陆,并把用户名存到session里,让下一个servlet资源能用
  20. //先不连接数据库 user是输入框中输入的
  21. if ("朱志伟".equals(user) && "123".equals(pwd)){
  22. //如果输入框中数据 是朱志伟和123 匹配上的话 就存到session里
  23. HttpSession session = request.getSession();
  24. session.setAttribute("user",user);
  25. // session.setAttribute("pwd",pwd);
  26. //跳转到IndexServlet
  27. response.sendRedirect("IndexServlet");
  28. }else {
  29. //没匹配成功,重新输入
  30. response.sendRedirect("login.html");
  31. }
  32. }
  33. @Override
  34. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  35. doGet(request, response);
  36. }
  37. }

LogoutServlet(退出,销毁)

  1. package com.qfedu.d_login; /**
  2. * @author wodexinhuai
  3. * @create 2022-05-09-15:19
  4. */
  5. import javax.servlet.*;
  6. import javax.servlet.http.*;
  7. import javax.servlet.annotation.*;
  8. import java.io.IOException;
  9. @WebServlet(name = "LogoutServlet", value = "/LogoutServlet")
  10. public class LogoutServlet extends HttpServlet {
  11. @Override
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. HttpSession session = request.getSession(false);
  14. if(session != null){
  15. //销毁session
  16. session.invalidate();
  17. //销毁完session之后(退出登陆之后),跳转到login.html页面
  18. response.sendRedirect("login.html");
  19. }
  20. }
  21. @Override
  22. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  23. doGet(request, response);
  24. }
  25. }

四、预习连接数据库的登陆

看预习视频