01-资源跳转的路径问题
- 请求转发
- 相对路径 : OK
- 绝对路径 : 直接找资源 “/资源名”
- 重定向
- 相对路径 : OK
- 绝对路径 : 先找项目,再找资源 。 “/项目名/资源名”
02-响应对象之文件下载
-
开发步骤
- 设置文件的mimeType,告诉浏览器响应正文的类型
- 设置响应头Content-Disposition,告诉浏览器显示下载窗口
- 文件拷贝(服务器 -> 浏览器)
-
代码实现
@WebServlet("/demo05") public class Demo05Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //下载文件名称 String fileName = "美女.jpg"; //1,设置文件的mimeTYpe //1.1,获取文件的mimeType类型 String mimeType = request.getServletContext().getMimeType(fileName); System.out.println(mimeType); //1.2,告诉浏览器响应正文的mimeType response.setHeader("Content-Type", mimeType); //2,显示下载窗口 //2.1,文件名中文乱码 : 浏览器是Chrome就是以utf-8编码,不是Chrome就是以base64编码 String userAgent = request.getHeader("User-Agent"); String newFileName = null; if (userAgent.contains("Chrome")) { //谷歌浏览器 newFileName = URLEncoder.encode(fileName,"utf-8"); } else { //非谷歌浏览器 newFileName = base64EncodeFileName(fileName); } response.setHeader("Content-Disposition", "attachement;filename=" + newFileName); //3,文件拷贝(服务器 -> 浏览器) //3.1,获取服务器文件对应的字节输入流 //D:\workspace\2103\day38\web\download\girl.jpg : 错误! //D:\workspace\2103\day38\out\artifacts\day38_war_exploded\download\girl.jpg : 正确! String realPath = request.getServletContext().getRealPath("download" + File.separator + fileName); BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath)); BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); byte[] bys = new byte[8192]; int len = -1; while ((len = bis.read(bys)) != -1) { bos.write(bys, 0, len); } bis.close(); bos.close(); } /** * base64编码 * @param fileName * @return */ public String base64EncodeFileName(String fileName) { BASE64Encoder base64Encoder = new BASE64Encoder(); try { return "=?UTF-8?B?" + new String(base64Encoder.encode(fileName .getBytes("UTF-8"))) + "?="; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
03-Servlet线程安全问题
-
问题说明
@WebServlet("/demo06") public class Demo06Servlet extends HttpServlet { private String name ; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { name = request.getParameter("name"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
代码实现
@WebServlet("/demo06") public class Demo06Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
@WebServlet("/demo07") public class Demo07Servlet extends HttpServlet { private String name; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { synchronized (this) { name = request.getParameter("name"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
总结
- 在Servlet尽量避免使用成员变量
- 在Servlet如果使用成员变量,尽量只使用不赋值
04-会话技术
-
概述
- 用于存储数据,并实现数据共享的技术,Cookie、Session
- 类似于ServletRequest、ServletContext域对象
-
为什么?
-
分类
- Cookie : 基于浏览器的会话技术
- Sesson : 基于服务器的会话技术
05-cookie介绍
- 概述
- 本质就是缓存文件,可以存储客户端访问网站的一些信息。
- 也是请求头、响应头的一部分。
- 常用属性
- name : cookie名称
- value : cookie值
- maxAge : cookie有效期
- path : cookie访问名称
06-cookie基本使用
-
基本使用
- 创建Cookie对象
- 浏览器添加Cookie信息
- 服务器获取Cookie信息
-
代码实现
@WebServlet("/demo08") public class Demo08Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //创建Cookie对象 Cookie cookie = new Cookie("test","helloworld"); //浏览器添加Cookie //操作响应头Set-Cookie:test=helloworld response.addCookie(cookie); //response.setHeader("Set-Cookie","test=helloworld"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
@WebServlet("/demo09") public class Demo09Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取Cookie Cookie myCookie = null; Cookie[] cookies = request.getCookies(); if (null != cookies && 0 != cookies.length) { for (Cookie cookie : cookies) { if (cookie.getName().equals("test")) { myCookie = cookie; } } } if (null != myCookie) { System.out.println(myCookie.getName() + "," + myCookie.getValue()); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response);
public class CookieUtils { public static Cookie getCookie(Cookie[] cookies , String cookieName){ if (null == cookies || 0 == cookies.length) { return null; } for (Cookie cookie : cookies) { if (cookieName.equals(cookie.getName())) { return cookie; } } return null; } }
09-cookie执行流程
- 执行流程
- 浏览器发起第一次请求,服务器Servlet创建Cookie对象
- 通过响应头Set-Cookie将Cookie信息携带回浏览器保存
- 浏览器发起第二次请求,Cookie信息随着请求头Cookie携带到服务器
- 服务器通过requst.getCookie获取对应的Cookie信息
10-cookie相关设置
-
概述
- 默认情况下,cookie随着会话的关闭而销毁。
- 默认情况下,访问当前项目中任何资源都会携带cookie
-
代码实现
@WebServlet("/demo10") public class Demo10Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie cookie = new Cookie("test","helloworld"); //设置有效期为7天 cookie.setMaxAge(7 * 24 * 60 * 60 ); //设置Cookie访问路径 cookie.setPath("/"); response.addCookie(cookie); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
11-cookie练习
-
需求
- 显示商品浏览记录
-
代码实现
@WebServlet("/demo11") public class Demo11Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id"); Cookie myCookie = CookieUtils.getCookie(request.getCookies(), "history"); if (null == myCookie) { //第一次请求 myCookie = new Cookie("history",id); } else { //不是第一次请求 //0-1-2 String historyStr = myCookie.getValue(); //判断原来是否已经浏览过 if (!historyStr.contains(id)) { historyStr = historyStr + "-" + id; myCookie.setValue(historyStr); } } response.addCookie(myCookie); //跳转 response.sendRedirect("/day38/demo12"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
@WebServlet("/demo12") public class Demo12Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); //显示浏览记录 Cookie myCookie = CookieUtils.getCookie(request.getCookies(), "history"); if (null == myCookie) { //没有浏览记录 response.getWriter().write("您还没有浏览任何商品,<a href='/day38/demo01.html'>请浏览商品</a>"); return ; } //有浏览记录 //0-1-2 String historyStr = myCookie.getValue(); //0、1、2 String[] names = {"红楼梦","西游记","三国演义","水浒传"}; String[] indexs = historyStr.split("-"); StringBuilder sb = new StringBuilder(); sb.append("您的浏览记录如下:<br>"); for (String index : indexs) { String name = names[Integer.parseInt(index)]; sb.append(name + "<br>"); } response.getWriter().write(sb.toString()); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
12-session介绍
- 概述
- 服务器端的会话技术
- 是一个域对象
- 域对象
- ServletRequest
- ServletContext
- HttpSession
13-session基本使用
-
代码实现
@WebServlet("/demo13") public class Demo13Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取session对象 HttpSession session = request.getSession(); session.setAttribute("test","helloworld"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
@WebServlet("/demo14") public class Demo14Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取session对象 HttpSession session = request.getSession(); Object msg = session.getAttribute("test"); System.out.println(msg); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
@WebServlet("/demo15") public class Demo15Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取session对象 HttpSession session = request.getSession(); session.removeAttribute("test"); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
14-session执行流程
- 执行流程
- 浏览器发起第一次请求Demo13Servlet
- request.getSession()创建新session对象
- 通过Set-Cookie响应头将session的唯一标识携带到浏览器保存
- 浏览器发起第二次请求Demo14Servlet
- 通过Cookie请求头将session的唯一标识携带到服务器
- request.getSession()匹配session的唯一标识
- 如果匹配上了,直接使用原有的session对象
- 如果匹配不上,就创建新的session对象
- request.getSession()匹配session的唯一标识
- 浏览器发起第一次请求Demo13Servlet
15-session相关设置
-
生命周期
- session默认的生命期为30分钟
- 关闭浏览器并不会销毁session,只是会销毁session存放在cookie中的唯一标识
- 关闭服务器
-
代码实现
<!-- web.xml --> <session-config> <session-timeout>1</session-timeout> </session-config>
@WebServlet("/demo16") public class Demo16Servlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取session对象 HttpSession session = request.getSession(); //销毁session session.invalidate(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
16-session练习
-
需求
- 登录成功后跳转到首页并显示用户信息
-
代码实现
@WebServlet("/login") public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); if ("root".equals(username) && "root".equals(password)) { //登录成功,将用户信息存储到session request.getSession().setAttribute("existUser",new User(username,password)); response.sendRedirect(request.getContextPath() + "/showIndex"); } else { //登录失败 response.sendRedirect(request.getContextPath() + "/login.html"); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
@WebServlet("/showIndex") public class ShowIndexServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); //显示用户信息 HttpSession session = request.getSession(); User existUser = (User) session.getAttribute("existUser"); //清理了浏览器的缓存、没有登录直接访问首页 if (null == existUser) { //不在登录状态 response.getWriter().write("您还没有登录,<a href='/day38/login.html'>去登录</a>"); response.setHeader("Refresh","3;URL=/day38/login.html"); return; } //在登录状态 String username = existUser.getUsername(); response.getWriter().write("欢迎回来," + username ); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
注意事项
理了浏览器的缓存、没有登录直接访问首页
if (null == existUser) {
//不在登录状态
response.getWriter().write(“您还没有登录,去登录”);
response.setHeader(“Refresh”,“3;URL=/day38/login.html”);
return;
}
//在登录状态
String username = existUser.getUsername();response.getWriter().write("欢迎回来," + username ); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
}
-
注意事项
- 现阶段,无法在html中获取java程序数据,暂时使用Servlet显示页面。