【JavaWeb】快速通关JSP(二)

简介: 【JavaWeb】快速通关JSP(二)

3、JSP 原理


我们之前说 JSP 就是一个页面,那么在 JSP 中写 html 标签,我们能理解,但是为什么还可以写 Java 代码呢?


因为 ==JSP 本质上就是一个 Servlet。==接下来我们聊聊访问jsp时的流程


f31dbeda0835665f9ce73962d82acf77_image-20210818111039350.png


浏览器第一次访问 hello.jsp 页面

tomcat 会将 hello.jsp 转换为名为 hello_jsp.java 的一个 Servlet

tomcat 再将转换的 servlet 编译成字节码文件 hello_jsp.class

tomcat 会执行该字节码文件,向外提供服务

我们可以到项目所在磁盘目录下找 target\tomcat\work\Tomcat\localhost\jsp-demo\org\apache\jsp 目录,而这个目录下就能看到转换后的 servlet


7e19fa0087a9f9dbc3af6f60eb16be0b_image-20210818112613589.png


打开 hello_jsp.java 文件,来查看里面的代码


6dbbdb65a9bb00f815d9392ea6b6ecf2_image-20210818112724462.png


由上面的类的继承关系可以看到继承了名为 HttpJspBase 这个类,那我们查看该类的继承关系


1b40c513260effe37c173b22a6919573_image-20210818113118802.png


可以看到该类继承了 HttpServlet ;那么 hello_jsp 这个类就间接的继承了 HttpServlet ,也就说明 hello_jsp 是一个 servlet。


继续阅读 hello_jsp 类的代码,可以看到有一个名为 _jspService() 的方法,该方法就是每次访问 jsp 时自动执行的方法,和 servlet 中的 service 方法一样 。


而在 _jspService() 方法中可以看到往浏览器写标签的代码:


ab2ffc7d40a7e0fb2086fdeae347fec3_image-20210818114008998.png


以前我们自己写 servlet 时,这部分代码是由我们自己来写,现在有了 jsp 后,由tomcat完成这部分功能。


4、JSP 脚本


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


4.1 JSP 脚本分类


JSP 脚本有如下三个分类:


<%...%>:内容会直接放到_jspService()方法之中

<%=…%>:内容会放到out.print()中,作为out.print()的参数

<%!…%>:内容会放到_jspService()方法之外,被类直接包含

代码演示:


在 hello.jsp 中书写


<%
    System.out.println("hello,jsp~");
    int i = 3;
%>


通过浏览器访问 hello.jsp 后,查看转换的 hello_jsp.java 文件,i 变量定义在了 _jspService() 方法中


bbf277f66319ba23c534a0da0fb6d054_image-20210818123820571.png


在 hello.jsp 中书写


<%="hello"%>
<%=i%>


通过浏览器访问 hello.jsp 后,查看转换的 hello_jsp.java 文件,该脚本的内容被放在了 out.print() 中,作为参数


d196754e5e56e3ec23fbb8ef2fc34fba_image-20210818123946272.png


在 hello.jsp 中书写


<%!
    void  show(){}
  String name = "zhangsan";
%>


通过浏览器访问 hello.jsp 后,查看转换的 hello_jsp.java 文件,该脚本的内容被放在了成员位置



4.2 案例


4.2.1 需求


使用JSP脚本展示品牌数据


17ebd9f979366b37a07542ebc09d8339_image-20210818125203390.png


说明:


brand.html 静态页面


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="button" value="新增"><br>
<hr>
<table border="1" cellspacing="0" width="800">
    <tr>
        <th>序号</th>
        <th>品牌名称</th>
        <th>企业名称</th>
        <th>排序</th>
        <th>品牌介绍</th>
        <th>状态</th>
        <th>操作</th>
    </tr>
    <tr align="center">
        <td>1</td>
        <td>三只松鼠</td>
        <td>三只松鼠</td>
        <td>100</td>
        <td>三只松鼠,好吃不上火</td>
        <td>启用</td>
        <td><a href="#">修改</a> <a href="#">删除</a></td>
    </tr>
    <tr align="center">
        <td>2</td>
        <td>优衣库</td>
        <td>优衣库</td>
        <td>10</td>
        <td>优衣库,服适人生</td>
        <td>禁用</td>
        <td><a href="#">修改</a> <a href="#">删除</a></td>
    </tr>
    <tr align="center">
        <td>3</td>
        <td>小米</td>
        <td>小米科技有限公司</td>
        <td>1000</td>
        <td>为发烧而生</td>
        <td>启用</td>
        <td><a href="#">修改</a> <a href="#">删除</a></td>
    </tr>
</table>
</body>
</html>



在该案例中数据不从数据库中查询,而是在 JSP 页面上写死


4.2.2 实现


Brand.java


/**
 * 品牌实体类
 */
public class Brand {
    // id 主键
    private Integer id;
    // 品牌名称
    private String brandName;
    // 企业名称
    private String companyName;
    // 排序字段
    private Integer ordered;
    // 描述信息
    private String description;
    // 状态:0:禁用  1:启用
    private Integer status;
    public Brand() {
    }
    public Brand(Integer id, String brandName, String companyName, String description) {
        this.id = id;
        this.brandName = brandName;
        this.companyName = companyName;
        this.description = description;
    }
    public Brand(Integer id, String brandName, String companyName, Integer ordered, String description, Integer status) {
        this.id = id;
        this.brandName = brandName;
        this.companyName = companyName;
        this.ordered = ordered;
        this.description = description;
        this.status = status;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getBrandName() {
        return brandName;
    }
    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }
    public String getCompanyName() {
        return companyName;
    }
    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }
    public Integer getOrdered() {
        return ordered;
    }
    public void setOrdered(Integer ordered) {
        this.ordered = ordered;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public Integer getStatus() {
        return status;
    }
    public void setStatus(Integer status) {
        this.status = status;
    }
    @Override
    public String toString() {
        return "Brand{" +
                "id=" + id +
                ", brandName='" + brandName + '\'' +
                ", companyName='" + companyName + '\'' +
                ", ordered=" + ordered +
                ", description='" + description + '\'' +
                ", status=" + status +
                '}';
    }
}



将 Brand.java 文件放置到项目的 com.itheima.pojo 包下


在项目的 webapp 中创建 brand.jsp ,并将 brand.html页面中的内容拷贝过来。brand.jsp 内容如下


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="button" value="新增"><br>
<hr>
    <table border="1" cellspacing="0" width="800">
        <tr>
            <th>序号</th>
            <th>品牌名称</th>
            <th>企业名称</th>
            <th>排序</th>
            <th>品牌介绍</th>
            <th>状态</th>
            <th>操作</th>
        </tr>
        <tr align="center">
            <td>1</td>
            <td>三只松鼠</td>
            <td>三只松鼠</td>
            <td>100</td>
            <td>三只松鼠,好吃不上火</td>
            <td>启用</td>
            <td><a href="#">修改</a> <a href="#">删除</a></td>
        </tr>
        <tr align="center">
            <td>2</td>
            <td>优衣库</td>
            <td>优衣库</td>
            <td>10</td>
            <td>优衣库,服适人生</td>
            <td>禁用</td>
            <td><a href="#">修改</a> <a href="#">删除</a></td>
        </tr>
        <tr align="center">
            <td>3</td>
            <td>小米</td>
            <td>小米科技有限公司</td>
            <td>1000</td>
            <td>为发烧而生</td>
            <td>启用</td>
            <td><a href="#">修改</a> <a href="#">删除</a></td>
        </tr>
    </table>
</body>
</html>



现在页面中的数据都是假数据。


在 brand.jsp 中准备一些数据


<%
    // 查询数据库
    List<Brand> brands = new ArrayList<Brand>();
    brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
    brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
    brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));
%>


==注意:==这里的类是需要导包的


将 brand.jsp 页面中的 table 标签中的数据改为动态的


<table border="1" cellspacing="0" width="800">
    <tr>
        <th>序号</th>
        <th>品牌名称</th>
        <th>企业名称</th>
        <th>排序</th>
        <th>品牌介绍</th>
        <th>状态</th>
        <th>操作</th>
    </tr>
    <%
     for (int i = 0; i < brands.size(); i++) {
         //获取集合中的 每一个 Brand 对象
         Brand brand = brands.get(i);
     }
    %>
    <tr align="center">
        <td>1</td>
        <td>三只松鼠</td>
        <td>三只松鼠</td>
        <td>100</td>
        <td>三只松鼠,好吃不上火</td>
        <td>启用</td>
        <td><a href="#">修改</a> <a href="#">删除</a></td>
    </tr>
</table>



上面的for循环需要将 tr 标签包裹起来,这样才能实现循环的效果,代码改进为


<table border="1" cellspacing="0" width="800">
    <tr>
        <th>序号</th>
        <th>品牌名称</th>
        <th>企业名称</th>
        <th>排序</th>
        <th>品牌介绍</th>
        <th>状态</th>
        <th>操作</th>
    </tr>
    <%
     for (int i = 0; i < brands.size(); i++) {
         //获取集合中的 每一个 Brand 对象
         Brand brand = brands.get(i);
    %>
      <tr align="center">
            <td>1</td>
            <td>三只松鼠</td>
            <td>三只松鼠</td>
            <td>100</td>
            <td>三只松鼠,好吃不上火</td>
            <td>启用</td>
            <td><a href="#">修改</a> <a href="#">删除</a></td>
        </tr>
    <%
     }
    %>
</table>



注意:<%%> 里面写的是 Java 代码,而外边写的是 HTML 标签


上面代码中的 td 标签中的数据都需要是动态的,所以还需要改进


<table border="1" cellspacing="0" width="800">
    <tr>
        <th>序号</th>
        <th>品牌名称</th>
        <th>企业名称</th>
        <th>排序</th>
        <th>品牌介绍</th>
        <th>状态</th>
        <th>操作</th>
    </tr>
    <%
     for (int i = 0; i < brands.size(); i++) {
         //获取集合中的 每一个 Brand 对象
         Brand brand = brands.get(i);
    %>
      <tr align="center">
            <td><%=brand.getId()%></td>
            <td><%=brand.getBrandName()%></td>
            <td><%=brand.getCompanyName()%></td>
            <td><%=brand.getOrdered()%></td>
            <td><%=brand.getDescription()%></td>
            <td><%=brand.getStatus() == 1 ? "启用":"禁用"%></td>
            <td><a href="#">修改</a> <a href="#">删除</a></td>
        </tr>
    <%
     }
    %>
</table>



4.2.3 成品代码


<%@ page import="com.itheima.pojo.Brand" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    // 查询数据库
    List<Brand> brands = new ArrayList<Brand>();
    brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
    brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
    brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));
%>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="button" value="新增"><br>
<hr>
<table border="1" cellspacing="0" width="800">
    <tr>
        <th>序号</th>
        <th>品牌名称</th>
        <th>企业名称</th>
        <th>排序</th>
        <th>品牌介绍</th>
        <th>状态</th>
        <th>操作</th>
    </tr>
    <%
        for (int i = 0; i < brands.size(); i++) {
            Brand brand = brands.get(i);
    %>
    <tr align="center">
        <td><%=brand.getId()%></td>
        <td><%=brand.getBrandName()%></td>
        <td><%=brand.getCompanyName()%></td>
        <td><%=brand.getOrdered()%></td>
        <td><%=brand.getDescription()%></td>
  <td><%=brand.getStatus() == 1 ? "启用":"禁用"%></td>
        <td><a href="#">修改</a> <a href="#">删除</a></td>
    </tr>
    <%
        }
    %>
</table>
</body>
</html>



4.2.4 测试


在浏览器地址栏输入 http://localhost:8080/jsp-demo/brand.jsp ,页面展示效果如下


9fb27237463309c34d2ff1b8aecb45dc_image-20210818145450748.png


4.3 JSP 缺点


通过上面的案例,我们可以看到 JSP 的很多缺点。


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


书写麻烦:特别是复杂的页面


既要写 HTML 标签,还要写 Java 代码


阅读麻烦


上面案例的代码,相信你后期再看这段代码时还需要花费很长的时间去梳理


复杂度高:运行需要依赖于各种环境,JRE,JSP容器,JavaEE…


占内存和磁盘:JSP会自动生成.java和.class文件占磁盘,运行的是.class文件占内存


调试困难:出错后,需要找到自动生成的.java文件进行调试


不利于团队协作:前端人员不会 Java,后端人员不精 HTML


如果页面布局发生变化,前端工程师对静态页面进行修改,然后再交给后端工程师,由后端工程师再将该页面改为 JSP 页面


由于上述的问题, ==JSP 已逐渐退出历史舞台,==以后开发更多的是使用 HTML + Ajax 来替代。Ajax 是我们后续会重点学习的技术。有个这个技术后,前端工程师负责前端页面开发,而后端工程师只负责前端代码开发。下来对技术的发展进行简单的说明


6c3bbd7d059800ba5f5b5524fb3a9942_image-20210818150346332.png


第一阶段:使用 servlet 即实现逻辑代码编写,也对页面进行拼接。这种模式我们之前也接触过


第二阶段:随着技术的发展,出现了 JSP ,人们发现 JSP 使用起来比 Servlet 方便很多,但是还是要在 JSP 中嵌套 Java 代码,也不利于后期的维护


第三阶段:使用 Servlet 进行逻辑代码开发,而使用 JSP 进行数据展示


9d3dda56e6657a8a4ae8fcf446a0d350_image-20210818151232955.png


第四阶段:使用 servlet 进行后端逻辑代码开发,而使用 HTML 进行数据展示。而这里面就存在问题,HTML 是静态页面,怎么进行动态数据展示呢?这就是 ajax 的作用了。


接下来我们来学习第三阶段,使用 EL表达式 和 JSTL 标签库替换 JSP 中的 Java 代码。

相关文章
|
1月前
|
存储 前端开发 Java
JavaWeb基础6——Request,Response,JSP&MVC
Request继承体系、获取请求头行体的方法、IDEA使用模板创建Servlet、请求参数中文乱码解决、请求转发、Respones重定向、Response响应字节字符数据、JSP、EL 表达式、JSTL标签、MVC模式和三层架构
JavaWeb基础6——Request,Response,JSP&MVC
|
4月前
|
SQL druid Java
javaweb案例实训之基于jsp和servlet的用户管理开发[增删改查及登录注销]
javaweb案例实训之基于jsp和servlet的用户管理开发[增删改查及登录注销]
32 0
|
4月前
|
SQL 数据可视化 数据库
基于jsp+servlet的javaweb实现最基本的用户注册登陆注销功能
基于jsp+servlet的javaweb实现最基本的用户注册登陆注销功能
22 0
|
5月前
|
前端开发 JavaScript Java
Jsp在Javaweb中扮演什么角色?
Jsp在Javaweb中扮演什么角色?
49 1
|
5月前
|
SQL 缓存 Oracle
JavaWeb之JSP(下)
这篇文档是关于Java Web中JSP(Java Server Pages)技术的主要内容包括:JSP的常用命令使用,EL表达式的概念,和使用,JSTL表达式的概念和使用方式的总结.
|
5月前
|
开发框架 前端开发 Java
JavaWeb之JSP(上)
这篇文档是关于Java Web中JSP(Java Server Pages)技术的介绍。作者首先说明了内容来源于个人在CSDN的原创文章,并遵循CC 4.0 BY-SA版权协议。文档主要内容包括:JSP的基本概念,它是一种动态网页技术,用于将页面逻辑与设计分离,便于开发快速、跨平台的Web应用。接着,讨论了JSP出现的原因,即为了改进servlet展示信息的不便。文档还详细介绍了如何在JSP中嵌入Java代码,包括声明、表达式和程序代码标签的使用,以及page指令的示例。
|
5月前
|
存储 前端开发 Java
JavaWeb:servlet+jsp+mybatis商品管理增删改查
商品管理通常包括增加(添加)、删除、修改和查询商品信息
165 1
JavaWeb:servlet+jsp+mybatis商品管理增删改查
|
5月前
|
XML 安全 Java
JavaWeb有机果蔬商城系统有机蔬菜水果商城系统(分前后台javaWeb+jsp+jstl+css+js+mysql)
JavaWeb有机果蔬商城系统有机蔬菜水果商城系统(分前后台javaWeb+jsp+jstl+css+js+mysql)
|
5月前
|
安全 Java
javaweb实训第四天下午——员工管理系统-JSP&Servlet&JDBC综合练习-CRUD
1.课程介绍 Servlet细节; (掌握) 员工信息相关的CRUD; (掌握) 部门信息相关的CRUD; (掌握) 2.Servlet细节 2.1.多种匹配方式
89 0
|
5月前
|
测试技术 数据库 数据安全/隐私保护
JavaWeb+JSP+SQL server学生学籍管理系统设计与实现(源代码+论文+开题报告+外文翻译+答辩PPT)
JavaWeb+JSP+SQL server学生学籍管理系统设计与实现(源代码+论文+开题报告+外文翻译+答辩PPT)
195 0