栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JavaWeb--B站黑马程序员多多三连

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JavaWeb--B站黑马程序员多多三连

1.Servlet

Server applet : 运行在服务器端的小程序

public class ServletDemo implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

1.1 Servlet生命周期
  • init

    • 初始化方法 : 在Servlet被创建时执行,只会执行一次

  • service

    • 每一次Servlet被访问时,执行.执行多次

  • destory

    • 在服务器正常关闭时执行,执行一次.

  • getServletConfig

    • 获取Servlet的配置对象

  • getServletInfo

    • 获取Servlet的一些信息,版本,作者等等.

1.2 Servlet体系结构
@WebServlet("/httpServletTest")
public class HttpServletDemo extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

2 超文本传输协议 Http 2.1 简介
  • 传输协议 : 定义了 , 客户端和服务器端通信时,发送数据的格式

  • 特点

    • 基于TCP/IP的高级协议

    • 默认端口号为80

    • 基于请求/相应模型的 : 一次请求对应一次相应

    • 无状态的 : 每次请求之间相互独立,不能交互数据

  • 历史版本

    • 1.0 : 每一次请求响应都会建立新的连接

    • 1.1 : 复用连接

2.2 请求消息数据格式 2.2.1 请求行
请求方式请求url请求协议/版本
Get百度一下,你就知道HTTP/1.1
  • 请求方式 :

    • HTTP协议中一共有7种请求方式,常用有两种

      • GET :

        • 请求参数在请求行中 , 在url后 (?name=aoligei&age=22)

        • 请求的url长度是有限制的

        • 不太安全

      • POST :

        • 请求参数在请求体中

        • 请求的url长度没有限制的

        • 相对安全

  • 高级浏览器解析之后的结果 :

2.2.2 请求头

请求头 : (客户端浏览器告诉服务器自身的一些信息)

  • 高级浏览器解析之后的结果

User-Agent : 浏览器告诉服务器,我访问你使用的浏览器版本信息

  • 可以在服务器端获取该头信息,解决浏览器的兼容问题

  • Accept : 告诉服务器,我作为浏览器,我可以接受你给我什么样的相应的信息格式

  • Accept-Language : 告诉服务器,我作为浏览器,我支持的语言环境

  • Accept-Encoding : 告诉服务器,我作为浏览器,我支持的压缩

  • Referer : 告诉服务器,当前请求从哪里来(where i comes)

    • 作用

      • 防盗链

统计工作

  • Connection : 这个链接可以被复用

2.2.3 请求空行

空行 : 分隔请求头和请求体

2.2.4 请求体(正文 )
  • 封装POST请求的请求体的

  • get方式没有请求体

  • 请求消息的原始格式

2.3 Request
  • request对象和response对象的原理

    • request和respnse对象是由服务器创建,我们来使用他们

    • request对象是来获取请求消息,respinse对象是来设置相应消息的

2.3.1 request对象继承体系结构

ServletRequest -- 接口

| extends

HttpServletRequest -- 接口

| implements

org.apache.catalina.connector.RequestFacade 类 (tomcat实现)

2.3.2 功能

2.3.2.1 获取请求行数据

  • 获取请求行数据   : GET /day14/demo1?name=zhangsan HTTP/1.1

    • 获取请求方式 : GET

      • request.getMethod();

    • 获取虚拟目录 :  /day14

      • request.getContextPath();

    • 获取Servlet路径 : /demo1

      • request.getServletPath();

    • 获取get方式请求参数 :  name=zhangsan

      • request.getQueryString();

    • 获取请求URI /day14/demo1

      • request.getRequestURI();

      • request.getRequestURL();

        • http://localhost/day/demo1

    • 获取协议以及版本 : HTTP/1.1

      • request.getProtocol();

    • 获取客户机的IP地址 :

      • request.getRemoteAddr();

2.3.2.2 获取请求头数据 

  • 获取请求头数据 

    • 通过请求头的名称获取请求头的值

      • request.getHeader(String name)

      • request.getHeader("referer");//如果是直接通过浏览器地址栏输入的方式是获取不到referer头信息的(同过其他方式,比如超链接)

    • 获取所有请求头的名称

      • Enumeration request.getHeaderNames

2.3.2.3 获取请求体数据

  • 获取请求体数据

    • 只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数

    • 步骤

      • 获取流对象

        • BufferedReader getReader() : 获取字符输入流,只能操作字符数据

        • ServletInputStream getInputStream() : 获取字节输入流,可以操作所有类型数据

      • 再从流对象中拿数据

    @PostMapping("/test")
    public String test(HttpServletRequest request) throws IOException {
        
        //1.获取字符流
        BufferedReader br = request.getReader();

        //2.读取数据
        String line = null;
        while((line = br.readLine()) != null){
            System.out.println(line);
        }
        return "项目启动test";
    }

2.3.2.4 获取请求参数通用方式

  • 获取请求参数通用方式

    • 根据参数名称获取参数值

      • request.getParameter(String name)

    • 根据参数名称获取参数值的数组 (比如?hobby=swiming&hobby=basketball)

      • String[ ] request.getParameterValues(String name)

    • 获取所有所有请求的参数名称

      • Enumeration getParameterNames():

    • 获取所有参数的map集合

      • Map getParamterMap()

@PostMapping("/test")
    public String test(HttpServletRequest request) throws IOException {

        //获取参数age
        String age = request.getParameter("age");
        System.out.println("age===>"+age);
        
        //获取参数hobby参数数组
        String[] bobbies = request.getParameterValues("bobby");
        for (String bobby : bobbies) {
            System.out.println("hobby===>"+bobby);
        }

        //获取所有参数名
        Enumeration parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            System.out.println("参数名为"+parameterNames.nextElement());
        }
        
        //获取参数键值对
        Map parameterMap = request.getParameterMap();
        String[] ages = parameterMap.get("age");
        for (String s : ages) {
            System.out.println(s);
        }
        String[] bobbies1 = parameterMap.get("bobby");
        for (String s : bobbies1) {
            System.out.println(s);
        }
        return "项目启动test";
   
    }

POST请求方式乱码问题

  • 设置流的字符集

request.setCharacterEncoding("utf-8");

2.3.2.5 请求转发

  • 请求转发 : 一种在服务器内部的资源跳转方式

    • 步骤

      • 通过request对象获取请求转发器对象 : RequestDispatcher getRequestDispatcher(String path)

      • 使用RequestDispatcher对象来进行转发 : forward(ServletRequest request,ServletResponse response)

    • 特点

      • 浏览器地址栏路径不发生变化

      • 只能转发到当前服务器内部资源

      • 转发是一次请求

@RestController
public class TestController {

    @PostMapping("/test")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("test");
        //转到其他URL
        //RequestDispatcher requestDispatcher = request.getRequestDispatcher("toDestination");
        //requestDispatcher.forward(request, response);
        request.getRequestDispatcher("toDestination").forward(request, response);
    }


    @PostMapping("/toDestination")
    public void toDestination(){
        System.out.println("redirect to  ReachDestination");
    }
    
}

2.3.2.6 共享数据

  • 共享数据

    • 域对象 : 一个有作用范围的对象,可以在范围内共享数据

    • request域 : 代表一次请求的范围,一般用于一次请求转发的多个资源中共享数据

方法 :

  • void setAttribute(String name,Object obj) : 存储数据

  • Object getAttribute(String name) : 通过键获取值

  • void removeAttribute(String name) : 通过键移除键值对

@RestController
public class TestController {

    @PostMapping("/test")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("test");
        //转到其他URL
        //RequestDispatcher requestDispatcher = request.getRequestDispatcher("toDestination");
        //requestDispatcher.forward(request, response);
        request.setAttribute("messageKey", "messagevalue");
        request.getRequestDispatcher("toDestination").forward(request, response);
    }


    @PostMapping("/toDestination")
    public void toDestination(HttpServletRequest request){
        System.out.println("redirect to  ReachDestination");
        System.out.println(request.getAttribute("messageKey"));
    }
}

2.3.2.7 获取ServletContext

2.3.2.7 获取ServletContext

  • 获取ServletContext

@RestController
public class TestController {

    @PostMapping("/test")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = request.getServletContext();
        System.out.println(servletContext);

    }
}


2.4 Response
  • 数据格式

    • 相应行

    • 响应头

    • 响应空行

    • 响应体

  • 响应字符串格式

响应行

  • 组成 : 协议/版本 响应状态码 状态码描述

    • 状态码 : 都是三位数字

    • 分类 :

      • 1xx : 服务器接收客户端消息,但是没有接受完成,等待一段时间之后,发送1xx等状态码

      • 2xx : 成功.代表:200

      • 3xx :重定向.代表 : 302(重定向) : 客户端访问A , A说我办不了,去找C吧. 304:访问缓存.(图片)

  • 4xx : 客户端错误. 典型 : 404 请求路径没有对应资源 : 405 请求方式不匹配

  • 5xx : 服务器端错误 典型 : 500

响应头

  • 格式 : 头名称 : 值

  • 常见的响应头 :

    • Content-Type : 服务器告诉客户端本次响应体数据格式以及编码格式

    • Content-disposition : 服务器告诉客户端以什么格式打开响应体数据,值有如下

      • in-line : 默认值,在当前页面打开

      • attachment;filename=xxx :以附件形式打开响应体.文件下载.

    • Content - Length :页面字符长度

响应体 : 传输的数据

2.4.1 response对象功能

2.4.1.1 设置相应行

  • 设置相应行

    • 设置状态码 : void setStatus(int StatusCode)

2.4.1.2 设置响应头

  • 设置响应头

    • void setHeadr(String ,name,String value)

2.4.1.3 设置响应体

  • 使用步骤

    • 获取输出流

      • 字符输出流

        • PrintWriter getWriter();

      • 字节输出流

        • ServletOutPutStream getOutputStream();

    • 使用输出流

      • 将数据输出到客户端浏览器

2.4.2 重定向案例
  • 重定向 : 资源跳转的方式

    • 访问A资源,A告诉浏览器重定向,状态码302

    • 告诉浏览器B资源的路径,响应头location:B资源的路径

@RestController
public class TestController {

    @GetMapping("/test")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("servlet A");
        //设置状态码 302
        response.setStatus(302);
        //2.设置响应头
        response.setHeader("location", "/redirect");

    }


    @GetMapping("/redirect")
    public void test2(HttpServletRequest request, HttpServletResponse response){
        System.out.println("servlet B");
    }
} 

简化 response.sendRedirect(String url);

@RestController
public class TestController {

    @GetMapping("/test")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("servlet A");   
        //简化
        response.sendRedirect("/redirect");
    }

    @GetMapping("/redirect")
    public void test2(HttpServletRequest request, HttpServletResponse response){
        System.out.println("servlet B");
    }
}

  • 重定向的特点

    • 地址栏发送变化

    • 重定向可以访问其他站点(服务器)的资源

    • 重定向是两次请求.不能使用requse对象t共享数据

  • 路径

    • 分类

      • 相对路径 : 通过相对路径不可以确定唯一资源

      • 绝对路径 : 通过绝对路径可以确定唯一资源

        • 如htttp://www.baidu.com /day15/responseDemo2

        • 动态获取虚拟目录 : request.getContextPath();

2.4.3 服务器输出字节数据到浏览器案例
    @GetMapping("/test")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取字符输出流
        PrintWriter writer = response.getWriter();
        writer.write("hello print writer");
    }

中文乱码问题

  • 原因 : 编码和解码使用的字符集不一致

  • 解决 : 设置浏览器编码格式,并告知浏览器使用这种编码规则

  @GetMapping("/test")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //获取流对象之前,设置流的默认编码 : ISO-8859-1 GBK
        //response.setCharacterEncoding("utf-8");
        //告诉浏览器,服务器发送的消息体数据的编码.建议浏览器使用该编码解码
        response.setHeader("content-type", "text/html;charset=utf-8");
        //1.获取字符输出流
        PrintWriter writer = response.getWriter();
        writer.write("你好 print writer");
    }

简化 : 使用response的方法 setContentType

   @GetMapping("/test")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        //1.获取字符输出流
        PrintWriter writer = response.getWriter();
        writer.write("你好 print writer");

    }

2.4.4 服务器输出字节数据到浏览器案例
  • 步骤

    • 获取字节输出流

    • 输出数据

  @GetMapping("/test")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write("你还".getBytes());
    }

2.4.5 验证码
  • 创建一对象,在内存中的图片(验证码图片对象)

  • 美化图片

  • 将图片输出到页面

   @GetMapping("/test")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        int width = 200;
        int height = 100;

        //创建一对象,在内存中的图片(验证码图片对象)
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        //将图片输出到页面展示
        ImageIO.write(image, "jpg", response.getOutputStream());
    }

2.5 ServletContext
  • 概念 : 代表整个web应用,可以和程序的容器(服务器)来通信

  • 获取

    • 通过request对象获取 : request.getServletContext();

    • 通过HttpServlet获取 : this.getServletContext();

  • 功能

    • 获取MIME类型:

    • 域对象 : 共享数据

    • 获取文件的真实(服务器)路径

2.5.1 获取MIME类型
  • 获取MIME类型

    • MIME类型 : 在互联网通信过程中定义的一种文件数据类型

      • 格式 大类型/小类型 text/html image/jpeg

    • 获取 : getMimeType(String file)

    @GetMapping("/test")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取
        ServletContext servletContext = request.getServletContext();

        //定义文件名称
        String filename = "a.jpg";

        //获取MIME类型
        String mimeType = servletContext.getMimeType(filename);
        System.out.println(mimeType); //image/jpeg
    }

2.5.2 域对象 : 共享数据(慎用)

域对象 : 共享数据(慎用)

  • ServletContext对象范围 : 所有用户所有请求的数据

servletContext.setAttribute("messageKey", "messagevalue");
Object messageKey = servletContext.getAttribute("messageKey");
servletContext.removeAttribute("messageKey");

@RestController
public class TestController {

    @GetMapping("/test")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取
        ServletContext servletContext = request.getServletContext();
        servletContext.setAttribute("messageKey", "messagevalue");
    }


    @GetMapping("/redirect")
    public void test2(HttpServletRequest request, HttpServletResponse response){
        ServletContext servletContext = request.getServletContext();
        Object messageKey = servletContext.getAttribute("messageKey");
        System.out.println(messageKey);
    }
}

2.5.3 获取文件的真实(服务器)路径
  • 获取文件的真实(服务器)路径

    • servletContext.getRealPath(String path);

   @GetMapping("/test")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取
        ServletContext servletContext = request.getServletContext();
        //获取真实路径(tomcat)
        String realPath = servletContext.getRealPath("src\main\resources\application.properties");
        System.out.println(realPath);
    }

2.6 文件下载案例
  • 文件下载需求

    • 页面显示超链接

    • 点击超链接后弹出下载提示框

    • 完成图片文件下载

  • 分析

    • 超链接指向的资源如果能够被浏览器解析,则在浏览器中显示,如果不能解析,则弹出下载提示框.不满足需求.

    • 任何资源都必须弹出下载提示框

    • 使用响应头设置资源的打开方式 :

      • content-disposition : attachment;filename = xxx

  • 步骤

    • 定义页面 , 编辑超链接href属性,指向Servlet,传递资源名称filename

    • 定义Servlet

      • 获取文件名称

      • 使用字节输入流加载文件进内存

      • 指定reponse的响应头 : content-disposition:attach;filename=xxx

      • 将数据写出到response输出流

@GetMapping("/downServlet")
    public void test2(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //获取参数
        String fileName = request.getParameter("fileName");

        //获取服务器真实路径,使用字节输入流加载文件至内存
        ServletContext servletContext = request.getServletContext();
        String realPath = servletContext.getRealPath("src\main\resources\img\"+fileName);
        FileInputStream fileInputStream = new FileInputStream(realPath);

        //设置响应头,文件以附件形式下载和MIME类型
        response.setHeader("content-type",servletContext.getMimeType(fileName));
        response.setHeader("content-disposition", "attachment;filename="+fileName);

        //将输入流写到输出流
        ServletOutputStream servletOutputStream = response.getOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while((len=fileInputStream.read(buffer)) != -1){
            servletOutputStream.write(buffer,0,len);
        }
    }


中文文件名问题

  • 工具类

public class DownUtils {
    public static String getFileName(String agent,String filename) throws UnsupportedEncodingException {

        if(agent.contains("MSIE")){
            //IE
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+", " ");
        }else if(agent.contains("Firefox")){
            //火狐
            base64Encoder base64Encoder = new base64Encoder();
            filename = "?utf-8?B?" +base64Encoder.encode(filename.getBytes("utf-8"))+"?=";
        }else {
            //其他浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }
}

步骤

  • 获取user-agent请求头

  • 使用工具类,根据不同浏览器对文件名进行编码

@GetMapping("/downServlet")
    public void test2(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //获取参数
        String fileName = request.getParameter("fileName");

        //获取服务器真实路径,使用字节输入流加载文件至内存
        ServletContext servletContext = request.getServletContext();
        String realPath = servletContext.getRealPath("src\main\resources\img\"+fileName);
        FileInputStream fileInputStream = new FileInputStream(realPath);

        //设置响应头,文件以附件形式下载和MIME类型
        response.setHeader("content-type",servletContext.getMimeType(fileName));

        //解决中文文件名问题
        //获取user-agent请求头
        String agent = request.getHeader("user-agent");
        //根据不同浏览器对文件名进行编码
        fileName = DownUtils.getFileName(agent, fileName);
        response.setHeader("content-disposition", "attachment;filename="+fileName);

        //将输入流写到输出流
        ServletOutputStream servletOutputStream = response.getOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while((len=fileInputStream.read(buffer)) != -1){
            servletOutputStream.write(buffer,0,len);
        }
    }

3.会话技术 :cookie
  • 会话 : 一次会话中包含多次请求和响应

    • 一次会话 : 浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止(浏览器关闭,或服务器关闭等等)

    • 功能 : 在一次会话的范围内的多次请求间 ,共享数据.

    • 方式 :

      • 客户端会话技术 : cookie

      • 服务器端会话技术 : Session

3.1 概念
  • 概念 : 客户端会话技术 , 将数据保存到客户端.

    • 使用步骤

      • 创建cookie对象,绑定数据

        • new cookie(String name,String value);

      • 发送cookie对象

        • response.addcookie(cookie cookie);

      • 获取cookie,拿到数据

        • cookie[] request.getcookie();

@RestController
public class TestController {

    @GetMapping("/cookieTest")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建cookie对象
        cookie cookie = new cookie("cookieKey", "cookievalue");
        //向客户端浏览器发送cookie
        response.addcookie(cookie);
    }


    @GetMapping("/getcookie")
    public void test2(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //获取cookie
        cookie[] cookies = request.getcookies();

        //获取数据,遍历cookies
        if(cookies != null){
            for (cookie cookie : cookies) {
                String cookieKey = cookie.getValue();
                System.out.println(cookieKey);
            }
        }

    }
}


3.2 一次发送多个cookie+
  • 一次发送多个cookie

  @GetMapping("/cookieTest")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建cookie对象
        cookie cookie = new cookie("cookieKey", "cookievalue");
        cookie cookie1 = new cookie("cookieKey2", "cookievalue2");
        //向客户端浏览器发送cookie
        response.addcookie(cookie);
        response.addcookie(cookie1);
    }

3.3 cookie的存活时间
  • 默认情况下,当浏览器关闭后,cookie数据被销毁

  • 持久化存储 :

    • setMaxAge(int seconds)

      • 正数 : 将cookie数据写到硬盘的文件中.持久化存储.cookie存活时间.(浏览器关闭之后开始计时)

      • 负数 : 默认值

      • 零 : 删除cookie信息

3.4 cookie 存储中文
  • cookie的键名不能为中文

  • 在tomcat8之前 cookie中不能直接存储中文数据.

    • 需要将中文(特殊字符)数据转码 --- 一般采用URL编码()

3.5 cookie获取范围
  • cookie的共享问题

    • 假设在一个tomcat服务器中,部署了多个web应用,那么在这些web项目中cookie能不能共享?

      • 默认情况下cookie不能共享

      • cookie.setPaht(String path) : 设置cookie的获取范围.默认情况下,设置当前的虚拟目录

        • 如果要当前服务器所有项目共享,则可以将path设置为 "/"

 @GetMapping("/cookieTest")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建cookie对象
        cookie cookie = new cookie("cookieKey", "cookie值");
        
        //设置共享范围 服务器范围
        cookie.setPath("/");
        
        //向客户端浏览器发送cookie
        response.addcookie(cookie);
    }

  • 不同的tomcat服务器见cookie共享问题?

    • cookie.setDomain(String path) : 如果设置一级域名相同,那么多个服务器之前cookie是可以共享数据的

    • cookie.setDomain(".baidu.com"),那么tieba.baidu.com 和 news.baidu.com中cookie时可以共享的

    • 多用于分布式

3.6 cookie的特点和作用
  • 特点 :

    • cookie存储数据在客户端浏览器 (安全性相对较低)

    • 浏览器对于单个cookie的大小也有限制(4kb)以及对同一域名下的总cookie数量也有限制(20个)

  • 作用 :

    • 在cookie一般用于存储少量的不太敏感的数据

    • 在不登录的情况下,完成服务器对客户端的身份识别

3.7 案例
  • 需求

    • 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问.

    • 如果不是第一次访问.则提示 : 欢迎回来,您上次访问时间为 : 显示时间字符串.

  • 分析 :

    • 可以采用cookie来完成

    • 服务器中的Servlet判断是否有一个名为lastTime的cookie

      • 有 : 不是第一次访问

        • 响应数据 : 欢迎回来 , 您上次访问时间为 : 2018年6月10日11:50:20

        • 写回cookie : lastTime = 2018年6月12日11:50:20

      • 没有

        • 响应数据 : 您好,欢迎您首次访问

        • 写回cookie : lastTime = 2018年6月12日11:50:20

@RestController
public class TestController {


    public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public static Date now = new Date();

    @GetMapping("/cookieLastTime")
    public String testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Boolean flag = false;

        //1.获取所有cookie
        cookie[] cookies = request.getcookies();

        //遍历cookie数组
        if (cookies != null  || cookies.length != 0){
            for (cookie cookie : cookies) {
                String cookieName = cookie.getName();
                if("lastTime".equals(cookieName)){        //有lastTime cookie
                    flag = true;
                    //set
                    String format = sdf.format(now);

                    System.out.println("编码前:"+format);
                    //URL编码
                    format = URLEncoder.encode(format, "utf-8");
                    cookie.setValue(format);
                    cookie.setMaxAge(60*60*24*30); // 一个月
                    response.addcookie(cookie);

                    //get
                    String lastTimevalue = cookie.getValue();
                    //解码
                    System.out.println("解码前:"+lastTimevalue);
                    //URL解码
                    lastTimevalue = URLDecoder.decode(lastTimevalue, "utf-8");
                    System.out.println("解码后:"+lastTimevalue);
                    return "您上次访问的时间为"+lastTimevalue;
                }
            }
        }


        if(cookies == null || cookies.length == 0 || flag ==false){
            //没有,第一次访问
            String format = URLEncoder.encode(sdf.format(now), "utf-8");
            cookie cookie = new cookie("lastTime", format);
            cookie.setMaxAge(60*60*24*30);
            response.addcookie(cookie);
            return "您好,欢迎您您首次访问";
         }


        return null;
    }
}

4.会话技术 : Session
  • 概念 : 服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中.HttpSession

  • 快速入门 :

    • 获取HttpSession对象

    • 使用HttpSession对象

    • HttpSession对象 :

      • Object getAttribute(String name)

      • void setAttribute(String name,Object value)

      • void removeAttribute(String name)

@RestController
public class TestController {
    
    @GetMapping("/sessionSet")
    public void testController(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //获取Session对象
        HttpSession session = request.getSession();
        //set
        session.setAttribute("sessionKey","sessionValue");
    }


    @GetMapping("/sessionGet")
    public void test2(HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpSession session = request.getSession();
        //get
        Object sessionValue = session.getAttribute("sessionKey");
        System.out.println(sessionValue);
    }
}

4.1 Session原理
  • 服务器如何确保在一次会话范围你,多次获取的Session对象是同一个?

  • Session是依赖于cookie的!

4.2 Session的统一性X
  • 当客户端关闭后,服务器不关闭,两次获取Session是否为一个?

    • 默认情况下,不是.因为上一次会话已经结束了

    • 如果需要相同,可以创建cookie,键位JSESSIONID,设置最大存活时间,让cookie持久化保存.

cookie c = new cookie("JSESSIONID",session.getId());
c.setMaxAge(60*60);
response.addcookie(c);

4.3 Session的统一性Ω
  • 当服务器关闭后,Session不唯一

    • 虽然Session对象不是同一个,但是要确保数据不丢失

      • Session的钝化 :

        • 在服务器正常关闭之前,将session对象序列化到硬盘上

      • Session的活化 :

        • 在服务器启动之后,将Session文件转化为内存中的session对象即可

4.4 Session的时效
  • Session什么时候被销毁

    • 服务器关闭

    • session对象调用invalidate();

    • session默认失效时间 30min(页面打开无任何操作)

4.5 Session的特点
  • session用于存储一次会话的多次请求的数据,存在服务器端

  • session可以存储任意类型数据,任意大小的数据

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/309696.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号