黑马就业班(02.JavaWeb+项目实战\08.Cookie和Session)——part2:JSP改造Cookie

1、JSP:入门学习
  JSP概念

* Java Server Pages: java服务器端页面
		* 可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码
		* 用于简化书写!!!(为什么可以简化书写?视频12-3.30解析)
对于一些页面,里面既有静态的html标签显示的数据,又有需要通过java代码动态生成的数据。我们需要使用java代码,使用Response对象往页面响应动态数据以及静态HTML标签,这样通过java响应各种HTML静态标签相当麻烦。
而JSP可以让我们在一个页面里面使用HTML写静态内容以及java代码写动态内容,这样就很方便。

  相应的代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>

    <%--JSP页面既可以写Java代码,也可以写html标签--%>
    <%
      //JSP写java代码
      System.out.println("hello JSP");//访问index.jsp,这一句会打印到控制台
    %>

    <%--JSP写HTML标签
    访问index.jsp,这一句会显示到浏览器页面
    --%>
    <h1>hi JSP</h1>

  </body>
</html>

  原理:JSP本质上就是一个Servlet。(见视频13解析)
  我们将访问JSP页面的服务器启动,控制台第一行的Using CATALINA_BASE: 的属性,就是当前项目的配置目录:C:\Users\Administrator.IntelliJIdea2017.3\system\tomcat_java-demo1。里面有2个文件夹,一个是conf一个是logs。我们访问index.jsp,里面多了一个文件夹:work,这个work里面放的就是我们JSP对应的java文件以及class文件。
  我们发现JSP生成的类index_jsp继承HttpJspBase,HttpJspBase是Apache内部提供的类,前面的资料提供了JSP的源码,在:D:\资源\黑马就业班\00.讲义+笔记+资料\JavaWeb\19.会员版(2.0)-就业课(2.0)-Servlet和HTTP请求协议\day05_Servlet&HTTP&Request\资料\tomcat-src\apache-tomcat-8.5.31-src\java\org\apache\jasper\runtime 可以找到这个类的源码。发现HttpJspBase继承HttpServlet。因此我们可以说JSP就是一个Servlet。
  将来我们可以把HTML标签定义在JSP中,这个index_jsp类会将HTML标签自动输出到页面上,这样我们就不需要自己去输出HTML标签。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  JSP的脚本:JSP定义Java代码的方式

1. <%  代码 %>:定义的java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。

2. <%! 代码 %>:定义的java代码,在jsp转换后的java类的成员位置。可以定义成员变量或者成员方法、代码块,静态代码块等(用的比较少,我们为了避免线程安全问题,一般不定义成员信息)

3. <%= 代码 %>:定义的java代码,会输出到浏览器页面上。输出语句中可以定义什么,该脚本中就可以定义什么。相当于使用Response的getWriter().write()方法将java定义的数据输出到浏览器页面上,这个输出语句定义在service方法里面。

   相应代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>

    <%
      //在这个脚本中定义index_jsp.java类中service方法内可以定义的内容
      System.out.println("hello JSP");
      int i = 5;//定义service方法内局部变量
    %>

    <%--这个脚本定义的是index_jsp.java类成员位置的信息,可以定义成员变量或者成员方法、代码块,静态代码块等--%>
    <%!
      int i = 3;
    %>

    <%--这个脚本定可以将其里面的值输出到浏览器页面上--%>
    <%--就近原则,输出局部变量i=5,因为i=5是定义在service方法的局部变量,而这个脚本也是定义在service方法里面,因此i=5 会被先访问到--%>
    <%=
      i
    %>
  </body>
</html>

   JSP的内置对象:在jsp页面中不需要获取和创建,可以直接使用的对象,jsp一共有9个内置对象。

* 今天学习3个:
	* request
	* response
	* out:字符输出流对象。可以将数据输出到页面上。和response.getWriter()类似
		* response.getWriter()和out.write()的区别:
			* 在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。
			* response.getWriter()数据输出永远在out.write()之前
原因:视频15-5.40。为了避免混乱,我们只只有out往页面输出就可以。

  代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>

    <%
      //out与Request对象是JSP的内置对象,可以直接使用
      String contextPath = request.getContextPath();
      out.print(contextPath);//contextPath被打印浏览器页面上
    %>

    <%
      //后使用response.getWriter()对象输出数据
      response.getWriter().write("hahaha");
    %>

    <%--发现response.getWriter()始终会在out对象前面输出数据--%>
  </body>
</html>

在这里插入图片描述

案例:改造Cookie的显示访问时间的案例

  首先,可以先修改JSP的模板,视频16-00.50的介绍。代码如下(建议黏贴到JSP页面,比较容易看)。下面这种代码写法较难阅读,且难写,我们一般不会这样写。

<%@ page import="java.net.URLDecoder" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
<%--
   将前面显示访问时间的案例转换为JSP的代码,需要注意几点
   1)所有通过Response对象的getWriter()方法要输出到浏览器页面的java代码中的变量,如value,它是java代码的变量,
    输出要通过<%= %>脚本输出;(当然也可以在<% %>脚本中使用getWriter()直接输出)
   2)所有通过Response对象的getWriter()方法要输出到浏览器页面纯文本或者HTML语言,可以直接写在当前JSP页面上,
   不需要写在上面脚本中(当然也可以在<% %>脚本中使用getWriter()直接输出这些HTML,就是很麻烦)
   3)其他的所有java的代码要写在<% %>脚本中

doPost与doGet方法也是在service方法中,他们里面的代码也可以写在脚本<% %>中,且doPost与doGet方法体不需要写上去,写方法内容即可
--%>

        <%--
        我们将前面doPost的方法体全部复制到<%%>中,没有报错。说明所有java代码都可以写到<%%>里面
        --%>

        <%--首先,普通java代码--%>
        <%
            //由于我们要使用Response返回文字到浏览器上显示,先设置Response的编码方式并告知浏览器数据的数据格式以及编码
            //response.setContentType("text/html;charset=utf-8");
            //不需要设置response的编码,上面设置了

            boolean flag = false;//判断有没有名为“lastTime”的Cookie存在,开始没有Cookie存在
            //获取Cookie
            Cookie[] cookies = request.getCookies();

            //如果Cookie存在
            if(cookies != null && cookies.length > 0)
            {
                //对由于的Cookie进行遍历
                for (Cookie cookie : cookies)
                {
                    String name = cookie.getName();//获取Cookie的名字
                    //可能有多个Cookie,我们想操作哪个封装时间的Cookie,那么先判断Cookie的名字是否为lasttime
                    if("lastTime".equals(name))
                    {
                        //如果找到lasttime的Cookie,首先将flag设置为true,表示之前已经创建了Cookie,已经存在,
                        // 如果不设置,那么flag=false,访问的时候还是就会进入上面的循环创建Cookie,注意
                        flag = true;

                        String encodeTime = cookie.getValue();//获取上一次访问的时间
                        System.out.println("解码前时间:"+encodeTime);
                        String decodeTime = URLDecoder.decode(encodeTime, "utf-8");//使用同一个编码方式解码时间
                        System.out.println("解码后时间:"+decodeTime);
        %>
                <%--HTML语言直接写在页面上,而通过getWriter()方法写到浏览器页面的java变量写在输出脚本上--%>
            <h1>欢迎回来,您上次访问时间为:<%=decodeTime%></h1>

        <%--其他普通java代码同样写到普通脚本--%>
        <%
                        /**
                         * 我们也可以先设置Cookie的新值,再获取Cookie上一次的值。
                         * 因为只有浏览器访问后响应,Cookie的值才会被更新。因此这里先设置新的Cookie值再将旧的值取出来也是可以的
                         */

                        //再次获取当前时间并编码
                        Date date = new Date();
                        SimpleDateFormat sd = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                        String time = sd.format(date);
                        System.out.println("编码前:" + time);
                        String encodeTime_2 = URLEncoder.encode(time, "utf-8");
                        System.out.println("编码后:"+encodeTime_2);

                        cookie.setValue(encodeTime_2);//将当前时间设置到Cookie中
                        //设置cookie的存活时间
                        cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
                        response.addCookie(cookie);//再次将Cookie写入Response

                        break;//获取到时间Cookie后达到目的,我们不再遍历,跳出循环
                    }
                }
            }

            /**
             * 注意,判断Cookie不存在一个放在Cookie存在后面。因为每次进来,虽然前面已经设置了Cookie,但是每次进来我们都将flag设置为false
             * 如果先判断Cookie不存在,每次都满足flag == false,每次都会执行首次访问的代码
             * 如果先判断Cookie存在,里面会把flag设置为true,这样就不会每次都执行首次访问的代码
             */

            //Cookie不存在。
            if(cookies == null || cookies.length == 0 || flag == false)//这三种情况代表Cookie不存在,flag == false表示有Cookie但是没有lastTime的Cookie
            {
                //没有Cookie,第一次访问

                //设置Cookie的value
                //获取当前时间的字符串,重新设置Cookie的值,重新发送cookie
                Date date = new Date();
                SimpleDateFormat sd = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                String time = sd.format(date);
                System.out.println("编码前:" + time);

                //直接将时间字符串写入Cookie会报错,我们使用URL编码编码时间
                String encodeTime = URLEncoder.encode(time, "utf-8");
                System.out.println("编码后:"+encodeTime);

                //创建一个Cookie,设置值为当前时间
                Cookie ck = new Cookie("lastTime", encodeTime);
                ck.setMaxAge(60*60*24*30);//设置Cookie在硬盘中保存30天
                //将Cookie添加到Response
                response.addCookie(ck);
                //使用Response返回浏览器文字,前面设置过编码,这里不需要再次设置
        %>

        <%--html标签同样直接写到JSP页面上--%>
        <h1>您好,欢迎您首次访问</h1>
        <%
            }
        %>
    </body>
</html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值