Response || CookieSession || JSPELJSTL ->(个人学习记录笔记)

news/2024/5/18 15:45:50 标签: java, servlet, session, cookie, jsp

文章目录

  • 1. HTTP协议:
    • 1.1 请求消息:客户端发送给服务器端的数据
    • 1.2 响应消息:服务器端发送给客户端的数据
      • 1.2.1 数据格式:
        • 1.2.1.1 响应行
        • 1.2.1.2 响应头:
        • 1.2.1.3 响应空行
        • 1.2.1.4 响应体:传输的数据
  • 2. Response对象
      • 2.1功能:设置响应消息
      • 2.2 案例:
        • 2.2.1. 完成重定向
        • 2.2.2 服务器输出字符数据到浏览器
          • 步骤:
          • 注意:
        • 2.2.3 服务器输出字节数据到浏览器
        • 2.2.4 验证码
  • 3. ServletContext对象:
    • 1. 概念:
    • 2. 获取:
    • 3. 功能:
  • 4. 案例:
  • -----------------------------------------------------------------------------
  • 5. Cookie&Session
    • 5.1
      • 什么是会话?
      • 有什么功能?
      • 有什么区别对于他们的方式?
    • 5.2 Cookie
      • 注意:
        • 1. 可以单次多条cookie
        • 2. 浏览器存储的cookie时间
        • 3. cookie是否可以存储中文
        • 4. cookie共享问题
        • 5. 主要特点与作用
    • 5.3 Session:翻译为(主菜)
      • 注意:
        • 1. 客户端关闭服务器不关闭,session不是同一个
        • 2. 客户端不关闭服务器关闭,session不同一个
        • 3. 失效时间
        • 4. 主要特点
        • 5. 差异不同
    • 案例:验证码
  • -----------------------------------------------------------------------------
  • 1. JSP
    • 1.1 概念:
    • 1.2 原理
    • 1.3 JSP的脚本:JSP定义Java代码的方式
    • 1.4 JSP的内置对象:
    • 1.5 指令
      • 1.5.1 作用:
      • 1.5.2 格式:
      • 1.5.3 分类:
        • 1. `page`: 配置`JSP`页面的
        • 2. `include` : 页面包含的。导入页面的资源文件
        • 3. `taglib` : 导入资源
    • 1.6 注释:
    • 1.7 内置对象
  • 2. MVC:开发模式
    • 2.1. jsp演变历史
    • 2.2 MVC
  • 3. EL表达式
    • 3.1 概念:
    • 3.2 作用:
    • 3.3 语法:
    • 3.4 注意:
    • 3.5 使用:
      • 3.5.1 运算:
        • 1. 运算符:
        • 2. 获取值
        • 3. 隐式对象:
  • 4. JSTL
    • 4.1 概念:
    • 4.2 作用:
    • 4.3 使用步骤:
    • 4.4 常用的JSTL标签
    • 4.5 练习:
  • 5. 三层架构:软件设计架构
  • 案例:用户信息列表展示
    • 1. 需求:用户信息的增删改查操作
    • 2. 设计:
    • 3. 开发:
    • 4. 测试
    • 5. 部署运维

1. HTTP协议:

1.1 请求消息:客户端发送给服务器端的数据

  • 数据格式:
    1. 请求行
    2. 请求头
    3. 请求空行
    4. 请求体

1.2 响应消息:服务器端发送给客户端的数据

1.2.1 数据格式:

1.2.1.1 响应行

  1. 组成:协议/版本 响应状态码 状态码描述
  2. 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。
    1. 状态码都是3位数字
    2. 分类:
      1. 1xx:服务器就收客户端消息,但没有接受完成,等待一段时间后,发送1xx多状态码

      2. 2xx:成功。代表:200

      3. 3xx:重定向。代表:302(重定向),304(访问缓存)

      4. 4xx:客户端错误。

        404(请求路径没有对应的资源)
        405:请求方式没有对应的doXxx方法

      5. 5xx:服务器端错误。代表:500(服务器内部出现异常)

1.2.1.2 响应头:

  1. 格式:头名称: 值
  2. 常见的响应头:
    1. Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
    2. Content-disposition:服务器告诉客户端以什么格式打开响应体数据
      值:
      in-line:默认值,在当前页面内打开
      attachment;filename=xxx:以附件形式打开响应体。文件下载

1.2.1.3 响应空行

1.2.1.4 响应体:传输的数据

  • 响应字符串格式
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 101
Date: Wed, 06 Jun 2018 07:08:42 GMT
	
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  hello , response
  </body>
</html>

2. Response对象

2.1功能:设置响应消息

  1. 设置响应行
    • 格式:HTTP/1.1 200 ok
    • 设置状态码:setStatus(int sc)
  2. 设置响应头:setHeader(String name, String value)
  3. 设置响应体:
    使用步骤:
    1. 获取输出流
      字符输出流:PrintWriter getWriter()
      字节输出流:ServletOutputStream getOutputStream()
    2. 使用输出流,将数据输出到客户端浏览器

2.2 案例:

2.2.1. 完成重定向

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

代码实现:

java">//1. 设置状态码为302
response.setStatus(302);
//2.设置响应头location
response.setHeader("location","/day15/responseDemo2");
//简单的重定向方法
response.sendRedirect("/day15/responseDemo2");
  • 重定向的特点:redirect

    1. 地址栏发生变化
    2. 重定向可以访问其他站点(服务器)的资源
    3. 重定向是两次请求。不能使用request对象来共享数据
  • 转发的特点:forward

    1. 转发地址栏路径不变
    2. 转发只能访问当前服务器下的资源
    3. 转发是一次请求,可以使用request对象来共享数据
  • forwardredirect 区别

  • 路径写法:

    路径分类

    1. 相对路径:通过相对路径不可以确定唯一资源
      • 如:./index.html
      • 不以/开头,以.开头路径
      • 规则:找到当前资源和目标资源之间的相对位置关系
        ./:当前目录
        ../:后退一级目录
    2. 绝对路径:通过绝对路径可以确定唯一资源
      • 如:http://localhost/day15/responseDemo2 /day15/responseDemo2

      • /开头的路径

      • 规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出

        • 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
          建议虚拟目录动态获取:request.getContextPath()
          <a> , <form> 重定向...
        • 给服务器使用:不需要加虚拟目录
          转发路径

2.2.2 服务器输出字符数据到浏览器

步骤:
  1. 获取字符输出流
  2. 输出数据
注意:
  • 乱码问题:
    1. PrintWriter pw = response.getWriter();获取的流的默认编码是ISO-8859-1
    2. 设置该流的默认编码
    3. 告诉浏览器响应体使用的编码
  • 简单的形式,设置编码,是在获取流之前设置
java">response.setContentType("text/html;charset=utf-8");
java">@WebServlet("/responseDemo4")
public class ResponseDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取流对象之前,设置六的默认编码,ISO-8859-1 设置为:GBK
//        resp.setCharacterEncoding("utf-8");

        // 设置编码 告诉浏览器,服务器发送的消息体数据的彪马。建议浏览器使用该编码
//        resp.setHeader("content-type","text/html;charset=utf-8");

        //简单的形式设置编码
        resp.setContentType("text/html;charset=utf-8");

        // 1.获取字符输出流
        PrintWriter pw = resp.getWriter();
        // 2.输出数据
//        pw.write("<h1>hello,response<h1>");
        pw.write("你好!");
    }
}

2.2.3 服务器输出字节数据到浏览器

步骤:

  1. 获取字节输出流
  2. 输出数据
java">@WebServlet("/responseDemo5")
public class ResponseDemo5 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

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

        resp.setContentType("text/html;charset=utf-8");
        // 1.获取字符输出流
        ServletOutputStream sos = resp.getOutputStream();
        // 2.输出数据
        sos.write("你好".getBytes("utf-8"));
    }
}

2.2.4 验证码

  1. 本质:图片
  2. 目的:防止恶意表单注册
java">@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {

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

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

        int wigth = 100;
        int height = 50;
        //1.创建一对象,在内存中图片(验证码图片对象)
        BufferedImage image = new BufferedImage(wigth,height,BufferedImage.TYPE_INT_RGB);
        //2.美化图片

        //2.1 填充背景色
        Graphics g = image.getGraphics(); //画笔对象
        g.setColor(Color.PINK);//设置画笔颜色
        g.fillRect(0,0,wigth,height);

        //2.2 画边框
        g.setColor(Color.BLUE);
        g.drawRect(0,0,wigth-1,height-1);

        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

        //生成随机角标
        Random ran = new Random();


        //2.3 写验证码
        for (int i = 1; i <= 4; i++) {
            int index = ran.nextInt(str.length());
            //获取字符
            char ch = str.charAt(index);
            g.drawString(ch+"", wigth/5*i,height/2);
        }
        //2.4 画干扰线
        g.setColor(Color.GREEN);

        //随机生成坐标点


        for (int i = 0; i < 10; i++) {
            int x1 = ran.nextInt(wigth);
            int x2 = ran.nextInt(wigth);
            int y1 = ran.nextInt(height);
            int y2 = ran.nextInt(height);
            g.drawLine(x1,y1,x2,y2);
        }


        //3.将图片输入到图片展示
        ImageIO.write(image,"jpg",resp.getOutputStream());
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>javascript">
    window.onload = function (){
        // 1. 获取图片对象
        var img = document.getElementById("checkCode");
        //2.绑定单击事件
        img.onclick = function (){
            //加时间戳
            var date = new Date().getTime();
            img.src = "/day15/checkCodeServlet?"+date;
        }

        // 1. 获取图片对象
        var cha = document.getElementById("change");
        var imga = document.getElementById("checkCode");
        //2.绑定单击事件
        cha.onclick = function (){
            //加时间戳
            var date = new Date().getTime();
            imga.src = "/day15/checkCodeServlet?"+date;
        }
    }

    </script>
</head>
<body>
    <img id="checkCode" src="/day15/checkCodeServlet"/>
    <a id="change" href="javascript:void(0);" >看不清换一张</a>
</body>
</html>

3. ServletContext对象:

1. 概念:

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

2. 获取:

  1. 通过request对象获取
    request.getServletContext();
  2. 通过HttpServlet获取
    this.getServletContext();

3. 功能:

  1. 获取MIME类型:
    • MIME类型:在互联网通信过程中定义的一种文件数据类型
      格式: 大类型/小类型 text/html image/jpeg
    • 获取:String getMimeType(String file)
  2. 域对象:共享数据
    1. setAttribute(String name,Object value)
    2. getAttribute(String name)
    3. removeAttribute(String name)
      ServletContext对象范围:所有用户所有请求的数据
  3. 获取文件的真实(服务器)路径
    1. 方法:String getRealPath(String path)
java">String b = context.getRealPath("/b.txt");//web目录下资源访问
System.out.println(b);
String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问
System.out.println(c);
String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问
System.out.println(a);
java">@WebServlet("/servletcontentdemo1")
public class ServletContentDemo1 extends HttpServlet {

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.通过request对象获取
        ServletContext context1 = req.getServletContext();
        //2.通过HttpServlet获取
        ServletContext context2 = this.getServletContext();

        System.out.println(context1);
        System.out.println(context2);

        System.out.println(context1 == context2);
    }
}
java">@WebServlet("/servletcontentdemo2")
public class ServletContentDemo2 extends HttpServlet {

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

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

        //2.通过HttpServlet获取
        ServletContext context = this.getServletContext();

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

        //4.获取MIME类型
        String mimeType = context.getMimeType(filename);
        System.out.println(mimeType);

    }
}

4. 案例:

  • 文件下载需求:

    1. 页面显示超链接
    2. 点击超链接后弹出下载提示框
    3. 完成图片文件下载
  • 分析:

    1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
    2. 任何资源都必须弹出下载提示框
    3. 使用响应头设置资源的打开方式:
      • content-disposition:attachment;filename=xxx
  • 步骤:

    1. 定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
    2. 定义Servlet
      1. 获取文件名称
      2. 使用字节输入流加载文件进内存
      3. 指定response的响应头: content-disposition:attachment;filename=xxx
      4. 将数据写出到response输出流
  • 问题:

    • 中文文件问题
      • 解决思路:
        1. 获取客户端使用的浏览器版本信息
        2. 根据不同的版本信息,设置filename的编码方式不同
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <a href="/day15/img/1.jpg">图片1</a>

    <a href="/day15/img/1.avi">视频</a>
    <hr>


    <a href="/day15/downloadServlet?filename=九尾.jpg">图片1</a>

    <a href="/day15/downloadServlet?filename=1.avi">视频</a>

</body>
</html>
java">@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取请求参数,文件名称
        String filename = request.getParameter("filename");
        //2.使用字节输入流加载文件进内存
        //2.1找到文件服务器路径
        ServletContext servletContext = this.getServletContext();
        String realPath = servletContext.getRealPath("/img/" + filename);
        //2.2用字节流关联
        FileInputStream fis = new FileInputStream(realPath);

        //3.设置response的响应头
        //3.1设置响应头类型:content-type
        String mimeType = servletContext.getMimeType(filename);//获取文件的mime类型
        response.setHeader("content-type",mimeType);
        //3.2设置响应头打开方式:content-disposition

        //解决中文文件名问题
        //1.获取user-agent请求头、
        String agent = request.getHeader("user-agent");
        //2.使用工具类方法编码文件名即可
        filename = DownLoadUtils.getFileName(agent, filename);

        response.setHeader("content-disposition","attachment;filename="+filename);
        //4.将输入流的数据写出到输出流中
        ServletOutputStream sos = response.getOutputStream();
        byte[] buff = new byte[1024 * 8];
        int len = 0;
        while((len = fis.read(buff)) != -1){
            sos.write(buff,0,len);
        }

        fis.close();


    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

注意: 这个可能不能用,因为,click

java">import sun.misc.BASE64Encoder;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;


public class DownLoadUtils {

    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;
    }
}

-----------------------------------------------------------------------------

5. Cookie&Session

5.1

  • 他们是一种会话技术

什么是会话?

  • 在一次会话过程中包含多次的请求和响应。
  • 一次会话就是浏览器第一次给服务器资源发送请求,会话开始建立,直到有一方断开为止

有什么功能?

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

有什么区别对于他们的方式?

  1. Cookie是客户端的会话技术:
  2. Session是服务器端的会话技术:

5.2 Cookie

  • 客户端的会话技术,cookie将数据信息保存到客户端中
  1. 首先来创建Cookie对象,然后绑定相关数据
    new Cookie(String name, String value)
  2. 进而发送Cookie对象
    response.addCookie(Cookie cookie)
  3. 最后获取得Cookie,然后拿到数据
    Cookie[] request.getCookies()
java">package xyz.slienceme.cookie;
@WebServlet(name = "CookieDemo1", value = "/CookieDemo1")
public class CookieDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 创建Cookie对象
        Cookie c = new Cookie("msg", "hello");
        //2. 发送Cookie
        response.addCookie(c);
    }
}
java">package xyz.slienceme.cookie;
@WebServlet(name = "CookieDemo2", value = "/CookieDemo2")
public class CookieDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //3. 获取Cookie
        Cookie[] cs = request.getCookies();
        // 获取数据,遍历Cookies
        if(cs != null){
            for (Cookie c : cs) {
                String name = c.getName();
                String value = c.getValue();
                System.out.println(name+":"+value);
            }
        }
    }
}
  • 他是基于响应头set-cookie和请求头cookie的前提来实现的

注意:

cookie_563">1. 可以单次多条cookie

  • 同时创建多个Cookie对象,利用response调用多次addCookie方法发送cookie可达到可以单次多条cookie的目的。
java">package xyz.slienceme.cookie;
@WebServlet(name = "CookieDemo3", value = "/CookieDemo3")
public class CookieDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 创建Cookie对象
        Cookie c1 = new Cookie("msg", "hello");
        Cookie c2 = new Cookie("name", "zhangsan");
        //2. 发送Cookie
        response.addCookie(c1);
        response.addCookie(c2);
    }
}

cookie_586">2. 浏览器存储的cookie时间

  1. 默认Cookie数据被销毁在浏览器关闭时
  2. 为了持久化存储cookie数据:
  • setMaxAge(int seconds)
    1. 正数:指定cookie存活时间,到期失效
    2. 负数:默认值
    3. 零:删除cookie信息
java">package xyz.slienceme.cookie;
@WebServlet("/cookieDemo4")
public class CookieDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.创建Cookie对象
        Cookie c1 = new Cookie("msg","setMaxAge");
        //2.设置cookie的存活时间
        //c1.setMaxAge(30);//将cookie持久化到硬盘,30秒后会自动删除cookie文件
        //c1.setMaxAge(-1);
        //c1.setMaxAge(300);
        c1.setMaxAge(0);//删除Cookie
        //3.发送Cookie
        response.addCookie(c1);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

cookie_614">3. cookie是否可以存储中文

  • tomcat 8版本之前需要将中文数据转码—一般采用URL编码(%E3)
  • tomcat 8 版本之后,支持中文数据。不支持特殊字符
    可以URL编码存储,URL解码解析
java">package xyz.slienceme.cookie;
@WebServlet("/cookieDemo5")
public class CookieDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.创建Cookie对象
        Cookie c1 = new Cookie("msg","你好");
        //设置path,让当前服务器下部署的所有项目共享Cookie信息
        c1.setPath("/");
        //3.发送Cookie
        response.addCookie(c1);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

cookie_637">4. cookie共享问题

  1. tomcat服务器,部署多个web项目默认情况下cookie不能共享
    setPath(String path):设置cookie的获取的范围。
    默认情况下,设置当前的虚拟目录
    * 如果想要共享,则可以将path设置为"/"

  2. 不同的tomcat服务器间cookie如何共享?
    setDomain(String path): 设置一级域名相同,则多个服务器之间cookie可以共享
    setDomain(".baidu.com"),那么tieba.baidu.comnews.baidu.comcookie可以共享

5. 主要特点与作用

  1. cookie客户端浏览器中存储数据
  2. 单个cookie 的大小限制(4kb)
  3. 同一个域名下的总cookie数量限制(20个)
  • 作用:
    1. cookie 用于存储少量的较为不敏感的数据
    2. 在不登录的条件下,来完成服务器对客户端的身份识别认证
java">package xyz.slienceme.cookie;
@WebServlet("/cookieTest")
public class CookieTest extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应的消息体的数据格式以及编码
        response.setContentType("text/html;charset=utf-8");
        //1.获取所有Cookie
        Cookie[] cookies = request.getCookies();
        boolean flag = false;//没有cookie为lastTime
        //2.遍历cookie数组
        if(cookies != null && cookies.length > 0){
            for (Cookie cookie : cookies) {
                //3.获取cookie的名称
                String name = cookie.getName();
                //4.判断名称是否是:lastTime
                if("lastTime".equals(name)){
                    //有该Cookie,不是第一次访问
                    flag = true;//有lastTime的cookie
                    //设置Cookie的value
                    //获取当前时间的字符串,重新设置Cookie的值,重新发送cookie
                    Date date  = new Date();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                    String str_date = sdf.format(date);
                    System.out.println("编码前:"+str_date);
                    //URL编码
                    str_date = URLEncoder.encode(str_date,"utf-8");
                    System.out.println("编码后:"+str_date);
                    cookie.setValue(str_date);
                    //设置cookie的存活时间
                    cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
                    response.addCookie(cookie);
                    //响应数据
                    //获取Cookie的value,时间
                    String value = cookie.getValue();
                    System.out.println("解码前:"+value);
                    //URL解码:
                    value = URLDecoder.decode(value,"utf-8");
                    System.out.println("解码后:"+value);
                    response.getWriter().write("<h1>欢迎回来,您上次访问时间为:"+value+"</h1>");
                    break;

                }
            }
        }
        if(cookies == null || cookies.length == 0 || flag == false){
            //没有,第一次访问
            //设置Cookie的value
            //获取当前时间的字符串,重新设置Cookie的值,重新发送cookie
            Date date  = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            String str_date = sdf.format(date);
            System.out.println("编码前:"+str_date);
            //URL编码
            str_date = URLEncoder.encode(str_date,"utf-8");
            System.out.println("编码后:"+str_date);

            Cookie cookie = new Cookie("lastTime",str_date);
            //设置cookie的存活时间
            cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
            response.addCookie(cookie);
            response.getWriter().write("<h1>您好,欢迎您首次访问</h1>");
        }
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

5.3 Session:翻译为(主菜)

  • 数据将保存在服务器端的对象中。HttpSession
  1. 获取HttpSession对象:
    HttpSession session = request.getSession();
  2. 使用HttpSession对象:
    Object getAttribute(String name)
    void setAttribute(String name, Object value)
    void removeAttribute(String name)
  • Session依赖于Cookie的。
    在这里插入图片描述
java">package xyz.slienceme.session;
@WebServlet("/sessionDemo1")
public class SessionDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //使用session共享数据
        //1.获取session
        HttpSession session = request.getSession();
        //2.存储数据
        session.setAttribute("msg","hello session");
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

java">package xyz.slienceme.session;
@WebServlet("/sessionDemo2")
public class SessionDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //使用session获取数据
        //1.获取session
        HttpSession session = request.getSession();
        //2.获取数据
        Object msg = session.getAttribute("msg");
        System.out.println(msg);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

注意:

session_782">1. 客户端关闭服务器不关闭,session不是同一个

如果客户端关闭,服务器不关闭,那么两次获取session默认情况不是同一个
但是如果需要相同,则可创建Cookie,键为JSESSIONID,而且设置最大的存活时间日期,让cookie来持久化保存。

java">Cookie c = new Cookie("JSESSIONID",session.getId());
c.setMaxAge(60*60);
response.addCookie(c);
java">package xyz.slienceme.session;
@WebServlet("/sessionDemo3")
public class SessionDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取session
        HttpSession session = request.getSession();
        System.out.println(session);
        //期望客户端关闭后,session也能相同
        Cookie c = new Cookie("JSESSIONID",session.getId());
        c.setMaxAge(60*60);
        response.addCookie(c);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

在这里插入图片描述

session_810">2. 客户端不关闭服务器关闭,session不同一个

如果客户端不关闭,服务器关闭,两次获取的session不是同一个,但是如果要确保数据不丢失损失。
tomcat自动完成以下工作

  • session的钝化:
    • 在服务器正常关闭之前,将session对象序列化到电脑的硬盘上
  • session的活化:
    • 在服务器启动后,将session文件转化为电脑内存中的session对象。
java">package xyz.slienceme.session;
@WebServlet("/sessionDemo4")
public class SessionDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //1.获取session
        HttpSession session = request.getSession();
        System.out.println(session);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

3. 失效时间

session失效时间有:

  1. 当服务器关闭时候
  2. session对象调用invalidate()方法时 。
  3. 而且session默认失效时间 30分钟 我们可以选择性配置修改
<session-config>
        <session-timeout>你想要的时间</session-timeout>
    </session-config>

4. 主要特点

session有什么特点呢?

  1. 注意session 主要用于存储一次会话的多次请求的数据,而且存在服务器端
  2. 注意session可以存储任意类型的数据,或者是任意大小的数据

5. 差异不同

对于sessionCookie的差异与不同:

  1. session数据放在服务器端存储,Cookie数据在客户端存储
  2. session无数据大小的限制,Cookie有数据大小的限制
  3. session数据更安全,Cookie相对而言不安全

案例:验证码

  1. 案例需求:

    1. 访问带有验证码的登录页面login.jsp
    2. 用户输入用户名,密码以及验证码。
      • 如果用户名和密码输入有误,跳转登录页面,提示:用户名或密码错误
      • 如果验证码输入有误,跳转登录页面,提示:验证码错误
      • 如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您
  2. 分析:

java"><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>
    <script>
        window.onload = function(){
            document.getElementById("img").onclick = function(){
                this.src="/c/checkCodeServlet?time="+new Date().getTime();
            }
        }
    </script>
    <style>
        div{
            color: red;
        }
    </style>
</head>
<body>
    <form action="/c/loginServlet" method="post">
        <table>
            <tr>
                <td>用户名</td>
                <td><input type="text" name="username"></td>
            </tr>
            <tr>
                <td>密码</td>
                <td><input type="password" name="password"></td>
            </tr>
            <tr>
                <td>验证码</td>
                <td><input type="text" name="checkCode"></td>
            </tr>
            <tr>
                <td colspan="2"><img id="img" src="/c/checkCodeServlet"></td>
            </tr>
            <tr>
                <td colspan="2"><input type="submit" value="登录"></td>
            </tr>
        </table>
    </form>
    <div><%=request.getAttribute("cc_error") == null ? "" : request.getAttribute("cc_error")%></div>
    <div><%=request.getAttribute("login_error") == null ? "" : request.getAttribute("login_error") %></div>
</body>
</html>
  1. 生成验证码函数
java">package xyz.slienceme.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


        int width = 100;
        int height = 50;

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


        //2.美化图片
        //2.1 填充背景色
        Graphics g = image.getGraphics();//画笔对象
        g.setColor(Color.PINK);//设置画笔颜色
        g.fillRect(0,0,width,height);

        //2.2画边框
        g.setColor(Color.BLUE);
        g.drawRect(0,0,width - 1,height - 1);

        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789";
        //生成随机角标
        Random ran = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= 4; i++) {
            int index = ran.nextInt(str.length());
            //获取字符
            char ch = str.charAt(index);//随机字符
            sb.append(ch);

            //2.3写验证码
            g.drawString(ch+"",width/5*i,height/2);
        }
        String checkCode_session = sb.toString();
        //将验证码存入session
        request.getSession().setAttribute("checkCode_session",checkCode_session);

        //2.4画干扰线
        g.setColor(Color.GREEN);

        //随机生成坐标点

        for (int i = 0; i < 10; i++) {
            int x1 = ran.nextInt(width);
            int x2 = ran.nextInt(width);

            int y1 = ran.nextInt(height);
            int y2 = ran.nextInt(height);
            g.drawLine(x1,y1,x2,y2);
        }


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


    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

  1. 验证信息
java">package xyz.slienceme.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.设置request编码
        request.setCharacterEncoding("utf-8");
        //2.获取参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String checkCode = request.getParameter("checkCode");
        //3.先获取生成的验证码
        HttpSession session = request.getSession();
        String checkCode_session = (String) session.getAttribute("checkCode_session");
        //删除session中存储的验证码
        session.removeAttribute("checkCode_session");
        //3.先判断验证码是否正确
        if(checkCode_session!= null && checkCode_session.equalsIgnoreCase(checkCode)){
            //忽略大小写比较
            //验证码正确
            //判断用户名和密码是否一致
            if("zhangsan".equals(username) && "123".equals(password)){//需要调用UserDao查询数据库
                //登录成功
                //存储信息,用户信息
                session.setAttribute("user",username);
                //重定向到success.jsp
                response.sendRedirect(request.getContextPath()+"/success.jsp");
            }else{
                //登录失败
                //存储提示信息到request
                request.setAttribute("login_error","用户名或密码错误");
                //转发到登录页面
                request.getRequestDispatcher("/login.jsp").forward(request,response);
            }


        }else{
            //验证码不一致
            //存储提示信息到request
            request.setAttribute("cc_error","验证码错误");
            //转发到登录页面
            request.getRequestDispatcher("/login.jsp").forward(request,response);

        }

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

  1. 成功访问
java"><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <h1><%=request.getSession().getAttribute("user")%>,欢迎您</h1>

</body>
</html>

-----------------------------------------------------------------------------

1. JSP

1.1 概念:

  • Java Server Pagesjava服务器端页面
    • 可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码
    • 用于简化书写

1.2 原理

  • JSP本质上就是一个Servlet
    在这里插入图片描述

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

  1. <% 代码 %>:定义的java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。
  2. <%! 代码 %>:定义的java代码,在jsp转换后的java类的成员位置。
  3. <%= 代码 %>:定义的java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。

1.4 JSP的内置对象:

  • jsp页面中不需要获取和创建,可以直接使用的对象
  • jsp一共有9个内置对象(其中三个)
    • request
    • response
    • out:字符输出流对象。可以将数据输出到页面上。和response.getWriter()类似
      • response.getWriter()out.write()的区别:
        • tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。
        • response.getWriter()数据输出永远在out.write()之前
java"><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
      <%
        System.out.println("hello jsp");
        int i = 5;
        String contextPath = request.getContextPath();
        out.print(contextPath);
      %>
      <%!
        int i = 3;
      %>
      <%= "hello" %>
      System.out.println("hello jsp");
      <h1>hi~ jsp!</h1>
      <% response.getWriter().write("response....."); %>
  </body>
</html>

1.5 指令

1.5.1 作用:

  • 用于配置JSP页面,导入资源文件

1.5.2 格式:

  • <%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>

1.5.3 分类:

1. page: 配置JSP页面的

  • contentType:等同于response.setContentType()
    1. 设置响应体的mime类型以及字符集
    2. 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)
  • import:导包
  • errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
  • isErrorPage:标识当前也是是否是错误页面。
    • true:是,可以使用内置对象exception
    • false:否。默认值。不可以使用内置对象exception

2. include : 页面包含的。导入页面的资源文件

  • <%@include file="top.jsp"%>

3. taglib : 导入资源

  • <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    • prefix:前缀,自定义的
java"><%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=gbk" errorPage="500.jsp" pageEncoding="GBK" language="java" buffer="16kb" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>$Title$</title>
</head>
<body>
<%
    List list = new ArrayList();
    int i = 3 / 0;
%>
</body>
</html>

1.6 注释:

  1. html注释:
    <!-- -->:只能注释html代码片段
  2. jsp注释:推荐使用
    <%-- --%>:可以注释所有

1.7 内置对象

  • jsp页面中不需要创建,直接使用的对象
  • 一共有9个:
变量名真实类型作用
pageContextPageContext当前页面共享数据,还可以获取其他八个内置对象
requestHttpServletRequest一次请求访问的多个资源(转发)
sessionHttpSession一次会话的多个请求间
applicationServletContext所有用户间共享数据
responseHttpServletResponse响应对象
pageObject当前页面(Servlet)的对象 this
outJspWriter输出对象,数据输出到页面上
configServletConfigServlet的配置对象
exceptionThrowable异常对象

2. MVC:开发模式

jsp_1187">2.1. jsp演变历史

  1. 早期只有servlet,只能使用response输出标签数据,非常麻烦
  2. 后来又jsp,简化了Servlet的开发,如果过度使用jsp,在jsp中即写大量的java代码,有写html表,造成难于维护,难于分工协作
  3. 再后来,javaweb开发,借鉴mvc开发模式,使得程序的设计更加合理性

2.2 MVC

  • (django利用了该模式 网址):
    在这里插入图片描述
  1. M:Model,模型。JavaBean
    • 完成具体的业务操作,如:查询数据库,封装对象
  2. V:View,视图。JSP
    • 展示数据
  3. C:Controller,控制器。Servlet
    • 获取用户的输入
    • 调用模型
    • 将数据交给视图进行展示
  • 优点:
    1. 耦合性低,方便维护,可以利于分工协作
    2. 重用性高
  • 缺点:
    1. 使得项目架构变得复杂,对开发人员要求高

3. EL表达式

3.1 概念:

  • Expression Language 表达式语言

3.2 作用:

  • 替换和简化jsp页面中java代码的编写

3.3 语法:

  • ${表达式}

3.4 注意:

  • jsp默认支持el表达式的。如果要忽略el表达式
    1. 设置jsppage指令中:isELIgnored="true" 忽略当前jsp页面中所有的el表达式
    2. \${表达式} :忽略当前这个el表达式
java"><%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java"   %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${3 > 4}
    \${3 > 4}
</body>
</html>

3.5 使用:

3.5.1 运算:

1. 运算符:

  1. 算数运算符: + - * /(div) %(mod)
  2. 比较运算符: > < >= <= == !=
  3. 逻辑运算符: &&(and) ||(or) !(not)
  4. 空运算符: empty
  • 功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0
  • ${empty list}:判断字符串、集合、数组对象是否为null或者长度为0
  • ${not empty str}:表示判断字符串、集合、数组对象是否不为null 并且 长度>0
java">
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java"   %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${3 > 4}
    \${3 > 4}
<hr>
    <h3>算数运算符</h3>
    ${3 + 4}<br>
    ${3 / 4}<br>
    ${3 div 4}<br>
    ${3 % 4}<br>
    ${3 mod 4}<br>
    
    <h3>比较运算符</h3>
    ${3 == 4}<br>

    <h3>逻辑运算符</h3>
    ${3 > 4  && 3 < 4}<br>
    ${3 > 4  and 3 < 4}<br>

    <h4>empty运算符</h4>
<%
    String str = "";
    request.setAttribute("str",str);

    List list = new ArrayList();
    request.setAttribute("list",list);
%>
    ${not empty str}
    ${not empty list}
</body>
</html>

2. 获取值

  1. el表达式只能从域对象中获取值
  2. 语法:
    1. ${域名称.键名}:从指定域中获取指定键的值
      域名称:

      1. pageScope --> pageContext
      2. requestScope --> request
      3. sessionScope --> session
      4. applicationScope --> application(ServletContext)
        • 举例:在request域中存储了name=张三
        • 获取:${requestScope.name}
    2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。

java"><%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>el获取域中的数据</title>
</head>
<body>
    <%
        //在域中存储数据
        session.setAttribute("name","李四");
        request.setAttribute("name","张三");
        session.setAttribute("age","23");
        request.setAttribute("str","");
    %>
<h3>el获取值</h3>
${requestScope.name}
${sessionScope.age}
${sessionScope.haha}
${name}
${sessionScope.name}

</body>
</html>

  1. 获取对象、List集合、Map集合的值
    1. 对象:${域名称.键名.属性名}
      本质上会去调用对象的getter方法
    2. List集合:${域名称.键名[索引]}
    3. Map集合:
      • ${域名称.键名.key名称}
      • ${域名称.键名["key名称"]}
java">package xyz.slienceme.domain;
import java.text.SimpleDateFormat;
import java.util.Date;

public class User {

    private String name;
    private int age;
    private Date birthday;

    public User(String name, int age, Date birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }
    public User() {
    }

    /**
     * 逻辑视图
     * @return
     */
    public String getBirStr(){

        if(birthday != null){
            //1.格式化日期对象
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //2.返回字符串即可
            return sdf.format(birthday);

        }else{
            return "";
        }
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

java"><%@ page import="xyz.slienceme.domain.User" %>
<%@ page import="java.util.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>el获取数据</title>
</head>
<body>

    <%
        User user = new User();
        user.setName("张三");
        user.setAge(23);
        user.setBirthday(new Date());


        request.setAttribute("u",user);


        List list = new ArrayList();
        list.add("aaa");
        list.add("bbb");
        list.add(user);

        request.setAttribute("list",list);


        Map map = new HashMap();
        map.put("sname","李四");
        map.put("gender","男");
        map.put("user",user);

        request.setAttribute("map",map);

    %>

<h3>el获取对象中的值</h3>
${requestScope.u}<br>

<%--
    * 通过的是对象的属性来获取
        * setter或getter方法,去掉set或get,在将剩余部分,首字母变为小写。
        * setName --> Name --> name
--%>

    ${requestScope.u.name}<br>
    ${u.age}<br>
    ${u.birthday}<br>
    ${u.birthday.month}<br>

    ${u.birStr}<br>

    <h3>el获取List值</h3>
    ${list}<br>
    ${list[0]}<br>
    ${list[1]}<br>
    ${list[10]}<br>

    ${list[2].name}

    <h3>el获取Map值</h3>
    ${map.gender}<br>
    ${map["gender"]}<br>
    ${map.user.name}

</body>
</html>

java"><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>el隐式对象</title>
</head>
<body>

    ${pageContext.request}<br>
    <h4>jsp页面动态获取虚拟目录</h4>
    ${pageContext.request.contextPath}
<%
%>
</body>
</html>

在这里插入图片描述

3. 隐式对象:

  • el表达式中有11个隐式对象
  • pageContext
    • 获取jsp其他八个内置对象
      • ${pageContext.request.contextPath}:动态获取虚拟目录

4. JSTL

4.1 概念:

  • JavaServer Pages Tag Library JSP标准标签库
    • 是由Apache组织提供的开源的免费的jsp标签<标签>

4.2 作用:

  • 用于简化和替换jsp页面上的java代码

4.3 使用步骤:

  1. 导入jstl相关jar
  2. 引入标签库:taglib指令: <%@ taglib %>
  3. 使用标签

4.4 常用的JSTL标签

  1. if:相当于java代码的if语句
java"><%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
    <title>if标签</title>
</head>
<body>
    <%--
    c:if标签
        1. 属性:
            * test 必须属性,接受boolean表达式
                * 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
                * 一般情况下,test属性值会结合el表达式一起使用

        2. 注意:c:if标签没有else情况,想要else情况,则可以在定义一个c:if标签
        
    --%>
    <c:if test="true">
        <h1>我是真...</h1>
    </c:if>
    <br>
    <%
        //判断request域中的一个list集合是否为空,如果不为null则显示遍历集合
        List list = new ArrayList();
        list.add("aaaa");
        request.setAttribute("list",list);
        request.setAttribute("number",4);
    %>
    <c:if test="${not empty list}">
        遍历集合...
    </c:if>
    <br>
    <c:if test="${number % 2 != 0}">
            ${number}为奇数
    </c:if>
    <c:if test="${number % 2 == 0}">
        ${number}为偶数
    </c:if>
</body>
</html>

在这里插入图片描述

  1. choose:相当于java代码的switch语句
java"><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>choose标签</title>
</head>
<body>
    <%--
        完成数字编号对应星期几案例
            1.域中存储一数字
            2.使用choose标签取出数字         相当于switch声明
            3.使用when标签做数字判断         相当于case
            4.otherwise标签做其他情况的声明  相当于default
    --%>
    <%
        request.setAttribute("number",51);
    %>
    <c:choose>
        <c:when test="${number == 1}">星期一</c:when>
        <c:when test="${number == 2}">星期二</c:when>
        <c:when test="${number == 3}">星期三</c:when>
        <c:when test="${number == 4}">星期四</c:when>
        <c:when test="${number == 5}">星期五</c:when>
        <c:when test="${number == 6}">星期六</c:when>
        <c:when test="${number == 7}">星期天</c:when>
        <c:otherwise>数字输入有误</c:otherwise>
    </c:choose>
</body>
</html>
  1. foreach:相当于java代码的for语句
java"><%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>foreach标签</title>
</head>
<body>

<%--
    foreach:相当于java代码的for语句
        1. 完成重复的操作
            for(int i = 0; i < 10; i ++){

            }
            * 属性:
                begin:开始值
                end:结束值
                var:临时变量
                step:步长
                varStatus:循环状态对象
                    index:容器中元素的索引,从0开始
                    count:循环次数,从1开始
        2. 遍历容器
            List<User> list;
            for(User user : list){
            }
            * 属性:
                items:容器对象
                var:容器中元素的临时变量
                varStatus:循环状态对象
                    index:容器中元素的索引,从0开始
                    count:循环次数,从1开始


--%>
<c:forEach begin="1" end="10" var="i" step="2" varStatus="s">
    ${i} <h3>${s.index}<h3> <h4> ${s.count} </h4><br>

</c:forEach>
    <hr>
    <%
        List list = new ArrayList();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        request.setAttribute("list",list);
    %>
    <c:forEach items="${list}" var="str" varStatus="s">
            ${s.index} ${s.count} ${str}<br>
    </c:forEach>
</body>
</html>

4.5 练习:

  • 需求:在request域中有一个存有User对象的List集合。需要使用jstl+el将list集合数据展示到jsp页面的表格table中
java"><%@ page import="xyz.slienceme.domain.User" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
    <title>test</title>
</head>
<body>
<%
    List list = new ArrayList();
    list.add(new User("张三",23,new Date()));
    list.add(new User("李四",24,new Date()));
    list.add(new User("王五",25,new Date()));
    request.setAttribute("list",list);
%>
<table border="1" width="500" align="center">
    <tr>
        <th>编号</th>
        <th>姓名</th>
        <th>年龄</th>
        <th>生日</th>
    </tr>
    <%--数据行--%>
    <c:forEach items="${list}" var="user" varStatus="s">

        <c:if test="${s.count % 2 != 0}">

            <tr bgcolor="red">
                <td>${s.count}</td>
                <td>${user.name}</td>
                <td>${user.age}</td>
                <td>${user.birStr}</td>
            </tr>
        </c:if>

        <c:if test="${s.count % 2 == 0}">

            <tr  bgcolor="green">
                <td>${s.count}</td>
                <td>${user.name}</td>
                <td>${user.age}</td>
                <td>${user.birStr}</td>
            </tr>
        </c:if>
    </c:forEach>
</table>
</body>
</html>

在这里插入图片描述

5. 三层架构:软件设计架构

  1. 界面层(表示层):用户看的得界面。用户可以通过界面上的组件和服务器进行交互
  2. 业务逻辑层:处理业务逻辑的。
  3. 数据访问层:操作数据存储文件。

案例:用户信息列表展示

1. 需求:用户信息的增删改查操作

2. 设计:

  1. 技术选型:Servlet+JSP+MySQL+JDBCTempleat+Duird+BeanUtilS+tomcat
  2. 数据库设计:
create database day17; -- 创建数据库
		use day17; 			   -- 使用数据库
		create table user(   -- 创建表
			id int primary key auto_increment,
			name varchar(20) not null,
			gender varchar(5),
			age int,
			address varchar(32),
			qq	varchar(20),
			email varchar(50)
		);

3. 开发:

  1. 环境搭建

    1. 创建数据库环境
    2. 创建项目,导入需要的jar包
  2. 编码

4. 测试

5. 部署运维


http://www.niftyadmin.cn/n/1460059.html

相关文章

学习日志day1(2021-07-06)(1、 安装jdk,配置环境变量 2、 学习JavaSE 基本语法)

学习内容&#xff1a;学习JavaSE&#xff08;Day1&#xff09; 1、 安装jdk&#xff0c;配置环境变量 2、 学习JavaSE 基本语法 1、安装jdk&#xff0c;配置环境变量 &#xff08;1&#xff09;Java之父James Gosling&#xff0c;任职经历&#xff1a;IBM → SUN → Google →…

学习日志day2(2021-07-07)(1、 学习运算符 2、 变量类型转换 3、 获取键盘输入的值 4、 学习三种程序运行的结构 )

学习内容&#xff1a;学习JavaSE&#xff08;Day2&#xff09; 1、 学习运算符 2、 变量类型转换 3、 获取键盘输入的值 4、 学习三种程序运行的结构 1、学习运算符 &#xff08;1&#xff09;算术运算符 加 -减 *乘 /除以 %取余 自增1 --自减1 -减一个数的值 *乘一个数的值 …

Python 图像 一样大小_Python小应用之批量打水印

&#xfeff;之前写菲律宾游记&#xff0c;想给自己的照片批量打上水印&#xff0c;首先想到的就是用Python实现给图片加文字&#xff0c;然后写个循环。做过图像识别的&#xff0c;应该知道OpenCV&#xff0c;其中cv2.putText()函数&#xff0c;就可以实现在图片上加文字&…

离散数学 ->(个人学习记录笔记)

第一章 命题逻辑 1.1 命题及表示方法 1.1.1 基本知识 命题 能表达判断的语句 并具有确定真值的陈述句 真值 一个命题的值&#xff0c;该值只有两种 真&#xff08;True&#xff09;&#xff0c;用 T 表示 假&#xff08;False&#xff09;&#xff0c;用 F 表示 悖论 …

模拟电路笔记

第一章 1.1 半导体基础知识 常用的模拟电路&#xff1a; 放大电路运算电路信号发生电路直流电源 1.1.1 本征半导体 具有纯净的晶体结构的半导体称为本征半导体。 常用半导体材料 硅&#xff08;Si&#xff09;锗&#xff08;Ge&#xff09;四价元素 本征半导体中的两种载流…

学习日志day3(2021-07-08)(1、 学习数组)

学习内容&#xff1a;学习JavaSE&#xff08;Day3&#xff09; 1、 学习数组 1、学习数组 &#xff08;1&#xff09;数组也是一种数据类型&#xff0c;是一种引用数据类型&#xff0c;引用数据类型都是带有属性的&#xff0c;如nums.length就是数组的属性&#xff0c;代表数…

weblogic多次连接后tcp服务堵塞_web 服务器有哪些

<1>什么是web服务器"网络服务"&#xff08;Web Service&#xff09;的本质&#xff0c;就是通过网络调用其他网站的资源。Web Service架构和云如果一个软件的主要部分采用了"网络服务"&#xff0c;即它把存储或计算环节"外包"给其他网站了…

叉积 微分 恒等式_向量恒等式

这次的内容相当平凡。最近学磁流体力学&#xff0c;发现对向量恒等式还是不熟悉&#xff0c;以前只是记一下然而今天上课的时候&#xff0c;看到这个等式傻了&#xff1a;不能直接代原来的等式&#xff0c;问题当然来源于 这个算符&#xff0c;我们需要修改一下之前的&#xff…