一、和response相关的方法
1.文件下载
思路:
使用字节输入流将本地磁盘(服务器中的一个视频)写入到内存中,然后使用response(浏览器行为)字节
package com.qfedu.a_response; /*** @author wodexinhuai* @create 2022-05-09-9:53*/import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.BufferedInputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.nio.charset.StandardCharsets;//文件下载案例@WebServlet(name = "DownloadServlet", value = "/DownloadServlet")public class DownloadServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request,response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//改进 通过url获取文件参数String file = request.getParameter("file");//1.获取下载文件的地址,被下载的资源文件一定在服务器里面ServletContext servletContext = request.getServletContext();//获取文件编译之后的真实路径//文件路径//E:\idea_workspace\day46_509\web\img\1.mp4//文件编译之后的路径//E:\idea_workspace\day46_509\out\artifacts\day46_509_war_exploded\img\1.mp4// String realPath = servletContext.getRealPath("/img/1.mp4");//改进String realPath = servletContext.getRealPath("/img/" + file);//E:\idea_workspace\day46_509\out\artifacts\day46_509_war_exploded\img\1.mp4System.out.println(realPath);//2.获取文件的名字 1.mp4//依靠上面的真实路径realPath 截取最后一个斜线后面的东西// substring以斜线开始截取 去最后一个斜线+1下标的字符串String filename = realPath.substring(realPath.lastIndexOf(File.separator) + 1);//1.mp4System.out.println(filename);// response.getWriter().append(filename);//输出在浏览器上会报错 因为response响应也是一个流 只能使用一次之后就关闭了//3.使用流进行下载,不要使用字符流 使用字节流 因为字符流不能对视频音频进行操作//将资源从磁盘写到java内存中BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath));//4.转换一下文件的名字,不然下载的时候会乱码//ISO-8859-1 是浏览器自己默认带的字符编码,浏览器的编码不是utf-8filename = new String(filename.getBytes("utf-8"),"ISO-8859-1");//5.设置响应头,因为浏览器要下载视频,告知浏览器当前的文件是什么类型,是以什么形式下载的//“content-disposition”,“attachment;filename=” + 文件名字//文件以附件的形式下载response.setHeader("content-disposition","attachment;filename=" + filename);//6.设置文件类型//getMimeType 浏览器会自动识别当前文件是什么类型的 比如.gif .mp4 .mp3String mimeType = request.getServletContext().getMimeType(filename);//为什么要获取文件类型?下载的文件类型一定要和原来资源文件类型保持一致response.setContentType(mimeType);// response.getWriter().append(mimeType);//7.从内存写入到浏览器//ServletOutputStream 浏览器的字节输入流ServletOutputStream os = response.getOutputStream();byte[] buf = new byte[1024 * 4];int length = -1;while ((length = bis.read(buf)) != -1){os.write(buf,0,length);}os.close();bis.close();}}
video.html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><div><div><video width="320" height="240" controls="controls"><source src="video/1什么是编程语言.mp4" type="video/mp4"></video></div><div><a href="DownloadServlet?file=1什么是编程语言.mp4">下载</a></div><div><video width="320" height="240" controls="controls"><source src="video/2为什么要学习java.mp4" type="video/mp4"></video><div><a href="DownloadServlet?file=2为什么要学习java.mp4">下载</a></div></div></div></body></html>
简洁版
package com.qfedu.a_fileDownload; /*** @author wodexinhuai* @create 2022-05-09-16:44*/import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.BufferedInputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;@WebServlet(name = "DownloadServlet", value = "/DownloadServlet")public class DownloadServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String file = request.getParameter("file");//getRealPath 获取到web当前位置String realPath = request.getServletContext().getRealPath("/video/" + file);//获取文件名字 字符串截取String filename = realPath.substring(realPath.lastIndexOf(File.separator) + 1);//有真实路径,将文件以字节流形式写入到java内存中BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath));//将文件名字转为浏览器编码格式filename = new String(filename.getBytes("utf-8"),"ISO-8859-1");//浏览器以附件的形式下载response.setHeader("content-disposition","attachment;filename=" + filename);//设置文件类型 现在类型和原始类型一致String mimeType = request.getServletContext().getMimeType(filename);response.setContentType(mimeType);//从磁盘写入到浏览器ServletOutputStream outputStream = response.getOutputStream();byte[] bytes = new byte[1024 * 4];int length = -1;while((length=bis.read(bytes)) != -1){outputStream.write(bytes,0,length);}outputStream.close();bis.close();}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request,response);}}
二、会话控制 cookie和session
2.1无状态访问
http协议是一种无状态的访问
浏览器发送请求到服务器之后,服务器会给一定的响应,但是这次响应之后,下次在页面中访问其他页面的时候,服务器不会自动保存当前的状态的。这就是无状态访问
比如:
登录淘宝,登录上以后,在登陆状态时,点击商品,添加购物车的时候不会保持登陆状态的。但是显示开发中保持了状态,登陆淘宝以后,点击购物车无需重新登陆,阿里使用了一种技术:**会话控制技术**
2.2会话技术
cookie
session
2.2.1Cookie
java代码中设置了Cookie以后,保存在浏览器中,每次访问服务器的时候,浏览器会自动把Cookie带到下一个页面,下一个页面直接取Cookie来用即可。
就相当于把用户名存到Cookie中,然后下一个页面再从浏览器中取Cookie
比如:浏览器登陆了百度账号,将用户名和密码存到浏览器中,在点击百度网盘,百度网盘从当前浏览器中取出来Cookie中的用户名和密码来保持登陆状态
Cookie:
1.保存在浏览器中,可以通过浏览器看到2.Cookie的大小是有限制的 4096kb3.Cookie信息不能带有中文4.Cookie的保存形式是键值对
常用的API:
1.Cookie有构造方法Cookie(String name.String value) 实例化,对Cookie设置值2.设置CookiesetCookie(String value) 修改cookie的值setMakAge(int time) 修改cookie过期时间3.将cookie发送给浏览器,因为是浏览器保存的cookieresponse.addCookie(cookie)
入门案例:
CookieServlet
package com.qfedu.b_cookie; /*** @author wodexinhuai* @create 2022-05-09-11:26*/import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.IOException;@WebServlet(name = "CookieServlet", value = "/CookieServlet")public class CookieServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.创建cookie对象 同时设置值Cookie cookie = new Cookie("java2204", "zzw");//2.对cookie设置过期时间/*** setMaxAge() 方法的参数* 正数:代表当前cookie的有效时间 单位是秒* 负数:当前浏览器一关闭,cookie就会失效,不关闭浏览器cookie就一直在* 0:销毁当前的cookie*/cookie.setMaxAge(30);//cookie30秒后过期//3.直接发送给浏览器response.addCookie(cookie);//给浏览器cookie以后,如果我再次请求另外一个servlet资源的话//可以在另外一个servlet}}
GetCookieServlet
package com.qfedu.b_cookie; /*** @author wodexinhuai* @create 2022-05-09-11:31*/import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.IOException;@WebServlet(name = "GetCookieServlet", value = "/GetCookieServlet")public class GetCookieServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.获取cookie对象 返回值Cookie数组//JSESSIONID=A27A2061ED2699E1B8E191EB871D43EE; java2204=zzw; Idea-8a2bc478=084504fc-fbef-4082-a03a-05f25cb92dbb//JSESSIONID 是服务器默认自带的//java2204=zzw 是自己写的Cookie[] cookies = request.getCookies();//遍历for (Cookie cookie : cookies) {System.out.println(cookie.getName());//获取键System.out.println(cookie.getValue());//获取值}}}
DestroyServlet
package com.qfedu.b_cookie; /*** @author wodexinhuai* @create 2022-05-09-11:45*/import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.IOException;//销毁cookie@WebServlet(name = "DestroyServlet", value = "/DestroyServlet")public class DestroyServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {Cookie[] cookies = request.getCookies();for (Cookie cookie : cookies) {//销毁cookieif(cookie.getName().equals("java2204")){cookie.setMaxAge(0);//从新发送一次cookieresponse.addCookie(cookie);}}}}
2.2.2Session
和Cookie是一样的功能,都是为了保持状态的
开发中为什么不用Cookie,用Session呢?
1.Cookie保存的数据类型比较单一,只能保存字符串类型的数据
2.Cookie保存的数据最大为4096kb
3.Cookie不能保存中文
综上所诉,开发用Session
session是保存在服务器中的,不是在浏览器啊中,每一个session都会在服务器中都会有一个唯一的标识:JSESSSIONID,可以保存中文,没有大小限制的
Session的API
getSession();获取session对象的getId();获取sessionID的invalidate();销毁sessionsetMaxInactiveInterval();设置session过期时间的setAttribute();设置session内容的getAttribute();获取session内容的
入门案例:
SessionServlet
package com.qfedu.c_session; /*** @author wodexinhuai* @create 2022-05-09-14:18*/import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.IOException;@WebServlet(name = "SessionServlet", value = "/SessionServlet")public class SessionServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.获取session对象 【重点】HttpSession session = request.getSession();System.out.println(session);//2.获取session唯一标识 JESSIONID【了解】System.out.println(session.getId());//3.设置过期时间session.setMaxInactiveInterval(30);//4.设置session的值 【重点】 在写一个servlet资源,可以通过name获取session.setAttribute("name","朱志伟");}}
GetSessionServlet
package com.qfedu.c_session; /*** @author wodexinhuai* @create 2022-05-09-14:23*/import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.IOException;@WebServlet(name = "GetSessionServlet", value = "/GetSessionServlet")public class GetSessionServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.获取session对象// HttpSession session = request.getSession();//getSession() 默认是true ,如果是false,不会自己新建session对象了//会使用之前第一次创建好的session对象HttpSession session = request.getSession(false);System.out.println(session);//2.获取session的内容 通过键Object name = session.getAttribute("name");System.out.println("这个是session的内容:" + name);}}
DestroySessionServlet
package com.qfedu.c_session; /*** @author wodexinhuai* @create 2022-05-09-14:38*/import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.IOException;@WebServlet(name = "DestroySessionServlet", value = "/DestroySessionServlet")public class DestroySessionServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request,response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//HttpSession session = request.getSession();session.invalidate();}}
三、登录案例
IndexServlet
package com.qfedu.d_login; /*** @author wodexinhuai* @create 2022-05-09-14:49*/import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.IOException;@WebServlet(name = "IndexServlet", value = "/IndexServlet")public class IndexServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");//设置响应编码格式//1.获取session对象 false 如果没有获取过session对象 就会是个nullHttpSession session = request.getSession(false);System.out.println(session);//null// session.setAttribute("user","朱志伟");//证明设置过sessionif (session != null && session.getAttribute("user").equals("朱志伟")){//session有,且session的值等于朱志伟,才展示主页面String html = "<font size='7' color='red'>123" + session.getAttribute("user")+ "456</font>";String html1 = "<a href='LogoutServlet' style='color:pink;font-size:20px'>退出登陆</a>";response.getWriter().append(html);response.getWriter().append("<br>");response.getWriter().append(html1);}else {//session没有值挥着session的值没有对应上的情况,跳转到登陆页面//重定向response.sendRedirect("login.html");}}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}
login.html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>登陆</title></head><body><form action="LoginServlet" method="post">姓名:<input type="text" name="user"><br>密码:<input type="password" name="pwd"><br><input type="submit" name="登录"></form></body></html>
LoginServlet
package com.qfedu.d_login; /*** @author wodexinhuai* @create 2022-05-09-15:04*/import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.IOException;@WebServlet(name = "LoginServlet", value = "/LoginServlet")public class LoginServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//设置请求乱码 因为是post请求request.setCharacterEncoding("utf-8");String user = request.getParameter("user");String pwd = request.getParameter("pwd");//验证信息登陆//前端的数据会和数据库的数据做对比,如果数据库中有这个数据,//密码也能匹配成功,就让登陆,并把用户名存到session里,让下一个servlet资源能用//先不连接数据库 user是输入框中输入的if ("朱志伟".equals(user) && "123".equals(pwd)){//如果输入框中数据 是朱志伟和123 匹配上的话 就存到session里HttpSession session = request.getSession();session.setAttribute("user",user);// session.setAttribute("pwd",pwd);//跳转到IndexServletresponse.sendRedirect("IndexServlet");}else {//没匹配成功,重新输入response.sendRedirect("login.html");}}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}
LogoutServlet(退出,销毁)
package com.qfedu.d_login; /*** @author wodexinhuai* @create 2022-05-09-15:19*/import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.annotation.*;import java.io.IOException;@WebServlet(name = "LogoutServlet", value = "/LogoutServlet")public class LogoutServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {HttpSession session = request.getSession(false);if(session != null){//销毁sessionsession.invalidate();//销毁完session之后(退出登陆之后),跳转到login.html页面response.sendRedirect("login.html");}}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}
四、预习连接数据库的登陆
看预习视频
