• JSP基础知识


    一、概述

            JSP(全称:Java Server Pages):Java服务端页面,是一种动态的网页技术,既可以定义HTML、JS、CSS等静态内容,也可以定义Java代码的动态内容,也就是JSP=HTML+Java,如下就是JSP代码

    1. <head>
    2. <title>Titletitle>
    3. head>
    4. <body>
    5. <h1>JSP,Hello Worldh1>
    6. <%
    7. System.out.println("hello,jsp~");
    8. %>
    9. body>

    JSP作用:简化开发,避免了在Servlet中直接输出HTML标签

    二、案例

    如下是jsp代码

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    2. <html>
    3. <head>
    4. <title>Titletitle>
    5. head>
    6. <body>
    7. <h1>hello jsph1>
    8. <%
    9. System.out.println("hello jsp~");
    10. %>
    11. body>
    12. html>

     

     

     三、JSP原理

            JSP本质上是一个Servlet,

     

    1. 浏览器第一次访问 hello.jsp 页面
    2. tomcat 会将 hello.jsp 转换为名为 hello_jsp.java 的一个 Servlet
    3. tomcat 再将转换的 servlet 编译成字节码文件 hello_jsp.class
    4. tomcat 会执行该字节码文件,向外提供服务

    四、JSP脚本

            JSP脚本用于在 JSP页面内定义 Java代码。在之前的入门案例中我们就在 JSP 页面定义的 Java 代码就是 JSP 脚本。

    4.1 JSP脚本分类

    JSP 脚本有如下三个分类:

    • <%...%>:内容会直接放到_jspService()方法之中
    • <%=…%>:内容会放到out.print()中,作为out.print()的参数
    • <%!…%>:内容会放到_jspService()方法之外,被类直接包含

    在hello.jsp中书写

    1. <%
    2. System.out.println("hello jsp~");
    3. int i=3;
    4. System.out.println(i);
    5. %>

     

    1. <%
    2. System.out.println("hello jsp~");
    3. int i=3;
    4. System.out.println(i);
    5. %>
    6. <%=i%>

     

    网页输出的hello jsp是HTML输出的 

    4.2 案例

    使用JSP动态输出某品牌信息,

    1. List brands = new ArrayList();
    2. brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
    3. brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
    4. brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));
    1. <%@ page import="pojo.Brand" %>
    2. <%@ page import="java.util.ArrayList" %>
    3. <%@ page import="java.util.List" %>
    4. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    5. <%
    6. // 查询数据库
    7. List<Brand> brands = new ArrayList<Brand>();
    8. brands.add(new Brand(1, "三只松鼠", "三只松鼠", 100, "三只松鼠,好吃不上火", 1));
    9. brands.add(new Brand(2, "优衣库", "优衣库", 200, "优衣库,服适人生", 0));
    10. brands.add(new Brand(3, "小米", "小米科技有限公司", 1000, "为发烧而生", 1));
    11. %>
    12. html>
    13. <html lang="en">
    14. <head>
    15. <meta charset="UTF-8">
    16. <title>Titletitle>
    17. head>
    18. <body>
    19. <input type="button" value="新增"><br>
    20. <hr>
    21. <table border="1" cellspacing="0" width="800">
    22. <tr>
    23. <th>序号th>
    24. <th>品牌名称th>
    25. <th>企业名称th>
    26. <th>排序th>
    27. <th>品牌介绍th>
    28. <th>状态th>
    29. <th>操作th>
    30. tr>
    31. <%
    32. for (int i = 0; i < brands.size(); i++) {
    33. //获取集合中的 每一个 Brand 对象
    34. Brand brand = brands.get(i);
    35. %>
    36. <tr align="center">
    37. <td><%=brand.getId()%>
    38. td>
    39. <td><%=brand.getBrandName()%>
    40. td>
    41. <td><%=brand.getCompanyName()%>
    42. td>
    43. <td><%=brand.getOrdered()%>
    44. td>
    45. <td><%=brand.getDescription()%>
    46. td>
    47. <td><%=brand.getStatus() == 1 ? "启用" : "禁用"%>
    48. td>
    49. <td><a href="#">修改a> <a href="#">删除a>td>
    50. tr>
    51. <%
    52. }
    53. %>
    54. table>
    55. body>
    56. html>

    4.3 JSP缺点

    由于JSP页面内既可以定义HTML标签又可以定义Java代码,造成以下问题:

    • 书写麻烦:特别是复杂的页面
    • 既要写 HTML 标签,还要写 Java 代码
    • 阅读麻烦
    • 上面案例的代码,相信你后期再看这段代码时还需要花费很长的时间去梳理
    • 复杂度高:运行需要依赖于各种环境,JRE,JSP容器,JavaEE…
    • 占内存和磁盘:JSP会自动生成.java和.class文件占磁盘,运行的是.class文件占内存
    • 调试困难:出错后,需要找到自动生成的.java文件进行调试
    • 不利于团队协作:前端人员不会 Java,后端人员不精 HTML
    • 如果页面布局发生变化,前端工程师对静态页面进行修改,然后再交给后端工程师,由后端工程师再将该页面改为 JSP 页面

    由于以上问题,JSP已经不再常用,更多的是用HTML+Ajax替代。技术发展过程如下:

     

    1. 第一阶段:使用 servlet 即实现逻辑代码编写,也对页面进行拼接。这种模式我们之前也接触过
    2. 第二阶段:随着技术的发展,出现了 JSP ,人们发现 JSP 使用起来比 Servlet 方便很多,但是还是要在 JSP 中嵌套 Java 代码,也不利于后期的维护
    3. 第三阶段:使用 Servlet 进行逻辑代码开发,而使用 JSP 进行数据展示
    4. 第四阶段:使用 servlet 进行后端逻辑代码开发,而使用 HTML 进行数据展示。而这里面就存在问题,HTML 是静态页面,怎么进行动态数据展示呢?这就是 ajax 的作用了。

    我们可以使用EL表达式和JSTL标签库替换JSP中等Java代码

    五、EL表达式

     5.1 概述

    • EL(全称Expression Language )表达式语言,用于简化 JSP 页面内的 Java 代码。
    • EL 表达式的主要作用是 获取数据。其实就是从域对象中获取数据,然后将数据展示在页面上。
    • 而 EL 表达式的语法也比较简单,${expression} 。例如:${brands} 就是获取域中存储的 key 为 brands 的数据。

    5.2 代码演示

    定义servlet,在servlet中封装一些数据到request域对象中并转发到el-demo.jsp页面

    1. @WebServlet("/demo1")
    2. public class ServletDemo1 extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    5. //1. 准备数据
    6. List brands = new ArrayList();
    7. brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
    8. brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
    9. brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));
    10. //2. 存储到request域中
    11. request.setAttribute("brands",brands);
    12. //3. 转发到 el-demo.jsp
    13. request.getRequestDispatcher("/el-demo.jsp").forward(request,response);
    14. }
    15. @Override
    16. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    17. this.doGet(request, response);
    18. }
    19. }

    (注意:此处需要使用转发,因为转发才可以使用request对象作为域对象进行数据共享)

    在el-demo.jsp中通过EL表达式获取数据

    1. <%@page isELIgnored="false"%>
    2. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    3. <html>
    4. <head>
    5. <title>Titletitle>
    6. head>
    7. <body>
    8. ${brands}
    9. body>
    10. html>

    5.3 域对象

    JavaWeb中有四大域对象,分别是:

    • page:当前页面有效
    • request:当前请求有效
    • session:当前会话有效
    • application:当前应用有效

    el 表达式获取数据,会依次从这4个域中寻找,直到找到为止。而这四个域对象的作用范围如下图所示

     例如: ${brands},el 表达式获取数据,会先从page域对象中获取数据,如果没有再到 requet 域对象中获取数据,如果再没有再到 session 域对象中获取,如果还没有才会到 application 中获取数据。(由于page范围太小以及application范围太大,用的比较少)

    六、JSTL标签

    6.1 概述

    JSP标准标签库(Jsp Standarded Tag Library) ,使用标签取代JSP页面上的Java代码。如下代码就是JSTL标签

    1. <c:if test="${flag == 1}">
    2. c:if>
    3. <c:if test="${flag == 2}">
    4. c:if>

    JSTL提供了很多标签,两个最常用的标签, 标签和 标签。

    6.2 if标签

    相当于if判断

    • 属性:test,用于定义条件表达式 

    代码演示:

     定义一个servlet,在该servlet中向request域对象中添加键是status,值为1的数据

    1. @WebServlet("/demo2")
    2. public class ServletDemo2 extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    5. request.setAttribute("status",1);
    6. request.getRequestDispatcher("/jstl-if.jsp").forward(request,response);
    7. }
    8. @Override
    9. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    10. this.doGet(request, response);
    11. }
    12. }

    定义jstl-if.jsp页面,在该页面使用标签(注意在page标签中添加 isELIgnored="false",否则识别不了EL表达式)

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
    2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    3. <html>
    4. <head>
    5. <title>Titletitle>
    6. head>
    7. <body>
    8. <c:if test="${status==1}">
    9. 启用
    10. c:if>
    11. <c:if test="${status==0}">
    12. 禁用
    13. c:if>
    14. body>
    15. html>

    在该页面也要引入JSTL核心标签库, <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

    6.3 forEach标签

    : 相当于for循环。 java中有增强for循环和普通for循环,JSTL 中的 也有两种用法

    6.3.1 用法一

    类似与Java中的增强for循环。涉及到的中的属性如下

    • items:被遍历的容器
    • var:遍历产生的临时变量
    • varStatus:遍历状态对象

    如下代码,是从域对象中获取名为 brands 数据,该数据是一个集合;遍历遍历,并给该集合中的每一个元素起名为 brand,是 Brand对象。在循环里面使用 EL表达式获取每一个Brand对象的属性值  

    1. <c:forEach items="${brands}" var="brand">
    2. <tr align="center">
    3. <td>${brand.id}td>
    4. <td>${brand.brandName}td>
    5. <td>${brand.companyName}td>
    6. <td>${brand.description}td>
    7. tr>
    8. c:forEach>

    6.3.2 用法二

    类似于Java中普通的for循环。涉及到的属性如下

    • begin:开始数
    • end:结束数
    • step:补偿

    实例如下:从0循环到10,变量名是i,每次自增1

    1. <c:forEach begin="0" end="10" step="1" var="i">
    2. ${i}
    3. c:forEach>

    七、MVC模式和三层架构

    MVC 模式和三层架构是一些理论的知识,将来我们使用了它们进行代码开发会让我们代码维护性和扩展性更好。

    7.1 MVC模式

    MVC是一种分层开发的模式,其中

    • M是指Model,业务模型,处理业务。
    • V是指View,视图,界面展示
    • C是指Controller,控制器,处理请求,调用模型和视图

     

     控制器(serlvlet)用来接收浏览器发送过来的请求,控制器调用模型(JavaBean)来获取数据,比如从数据库查询数据;控制器获取到数据后再交由视图(JSP)进行数据展示。

    好处:

    • 职责单一,互不影响。每个角色做它自己的事,各司其职。
    • 有利于分工协作。
    • 有利于组件重用

    7.2 三层架构

    三层架构是将项目分为三个层面,分别是表现层、业务逻辑层、数据访问层 

     

    • 数据访问层:对数据库的CRUD基本操作
    • 业务逻辑层:对业务逻辑进行封装,组合数据访问层层中基本功能,形成复杂的业务逻辑功能。例如 注册业务功能 ,我们会先调用 数据访问层selectByName() 方法判断该用户名是否存在,如果不存在再调用 数据访问层insert() 方法进行数据的添加操作
    • 表现层:接收请求,封装数据,调用业务逻辑层,响应数据

    而整个流程是,浏览器发送请求,表现层的Servlet接收请求并调用业务逻辑层的方法进行业务逻辑处理,而业务逻辑层方法调用数据访问层方法进行数据的操作,依次返回到serlvet,然后servlet将数据交由 JSP 进行展示。

    7.3 MVC和三层架构

    两者有什么区别和联系?

     

            如上图上半部分是 MVC 模式,上图下半部分是三层架构。 MVC 模式 中的 C(控制器)和 V(视图)就是 三层架构 中的表现层,而 MVC 模式 中的 M(模型)就是 三层架构 中的 业务逻辑层 和 数据访问层。

            可以将 MVC 模式 理解成是一个大的概念,而 三层架构 是对 MVC 模式 实现架构的思想。 那么我们以后按照要求将不同层的代码写在不同的包下,每一层里功能职责做到单一,将来如果将表现层的技术换掉,而业务逻辑层和数据访问层的代码不需要发生变化。

  • 相关阅读:
    C++的对像生存期
    kruskal重构树
    LeetCode 2385.感染二叉树需要的总时间:两次搜索(深搜 + 广搜)
    新掌门蔡崇信,能否“再救”阿里?
    Linux学习笔记
    GCC特性——内建函数
    5分钟了解Redis的内部实现快速列表(quicklist)
    【PyTorch深度学习项目实战100例】—— 利用pytorch长短期记忆网络LSTM实现股票预测分析 | 第5例
    网络安全深入学习第七课——热门框架漏洞(RCE— Fastjson反序列化漏洞)
    如何利用博途PLC PID_Compact 进行PID闭环仿真(一阶对象传递函数)
  • 原文地址:https://blog.csdn.net/weixin_66813230/article/details/126380494