JSP速通

JSP速通

文章导入

  • JSP现在是不是已经被淘汰了我们还有必要学习吗

    JSP现在算是已经被淘汰了,但我们还是有必要学习。

    JSP算是一门老技术了,如今很多企业都极少用它了,可能在一些国企中还能见到吧🌝,那么我们还有必要学习JSP吗?我的答案是肯定的,一是,毕竟以前JSP很火,很多企业都用了JSP,这就导致企业可能还有遗留或者还在使用JSP,我们懂JSP能够进一步提高竞争力;其次,学习旧技术不一定是为了去使用它,我们在学习过程中,能偶丰富我们的眼界,提高我们的学习能力,了解新技术相对旧技术有哪些改进、哪些相同点、不同点,从而更有利于我们对新技术的掌握和理解。

  • 是什么导致JSP的没落

    主要原因还得是前后端分离,其次就是主流的spring框架不支持JSP。

    在Web2.0时代,当时都是前后端一体化,一个程序员既要干后端又要干前端(简称全干工程师😆),而JSP能够将Java代码和HTML代码混着写,非常符合当时的趋势,所以就大火。然而现在,随着技术的发展、时代的进步,很多互联网公司都为追求高效率,开始盛行前后端分离,所以说前后端分离是JSP。

    前后端分离主要有以下几个好处:

    • 提高工作效率。前端和后端的逻辑思维、需求都有很大区别,专门的人干专门的事
    • 减小服务器的压力。很多请求处理都交给了前端来做
    • 降低维护成本。对前端代码和后端代码进行了解耦,调试前端代码无需后端人员的参与
    • 提升用户体验。实现页面的按需加载,无需一开始加载首页便加载网站的所有的资源,服务器也不再需要解析前端页面,在页面交互及用户体验上有所提升
  • 谁取代了JSP

    JSP的大部分功能都被thymeleaf 取代了。

    JSP存在的意义就是解决网页能动态获取来自服务器的响应数据,而thymeleaf也能。同时在当今Java界叱咤风云的Springboot框架统治下,对于JSP更加更加学上加霜,首先Springboot不支持JSP,它很好地继承了thymeleaf模板引擎,让thymeleaf在使用了Springboot的Web项目下显得更加如鱼得水,其次就是Sun公司(已被Oracle公司收购)停止了对JSP的更新,连亲爹都放弃它了🤣。

总的来说JSP的没落是技术的更新换代,是行业趋势所致,是时代的更迭。

1、JSP概述

  • 什么是JSP

      JSP是一种动态网页技术,能够将Java代码和特定变动内容嵌入到静态的页面中,实现以静态页面为模板,动态生成其中的部分内容。JSP主要作用是为了简化Servlet的工作而出现的替代品,,本质仍然是Servlet!因为Servlet输出HTML非常繁琐,JSP就是替代Servlet输出HTML的。

      JSPJavaServer Pages)是由Sun Microsystems公司主导创建的一种动态网页技术标准。JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTMLXML或其他格式文档的Web网页,然后返回给请求者。JSP技术以Java语言作为脚本语言,为用户的HTTP请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求。

  • JSP的组成静态标签 + JSP脚本 + 动态标签

    • 静态标签主要是html标签

    • JSP脚本主要是Java代码

    • 动态标签主要是JSTL标签

  • JSP的优缺点

    • 优点
      • 跨平台。由于JSP是基于Java的,所以它们也有Java语言的最大优点——平台无关性,“一次编写,随处运行“
      • 动态交互。实现静态HTML页面中数据的动态变化
      • 生态较好。有很多优秀且免费的JSP开发工具可供使用
      • 简化Servlet的开发。将原本Servlet客户端程序输出HTML内容的工作给包揽了,简化了Servlet的开发
    • 缺点
      • 占用内存。JSP会自动生成.java.class文件占用磁盘大量内存
      • 增加项目的复杂性。前端后端混合在一起,书写麻烦、代码阅读性不高、维护难度大。同时需要依赖于各种环境,比如:JSP容器(Tomcat)、JRE、Servlet相关jar包……搭建环境要费时间且不易
      • 开发效率低。前后端未分离,分工不明确,开发效率较低
      • 增大后端服务器压力。后端服务器既要处理前端数据,又要处理后端数据
      • 调试困难。 首先被转换为.java文件(Servlet),然后将.java文件编译为.class文件. 这样,出错信息实际上指向的是转换后的那个.java文件(Servlet),而不是JSP本身(调试有难度)

看着这一堆缺点,也难怪JSP会被淘汰😆,但不可否认它以前也是一代霸王

2、JSP初体验

创建JSP文件
编写JSP代码
部署项目
测试
导入项目依赖
  • Step1:导入项目依赖

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <!--===============项目信息===================-->
        <!--Maven版本信息-->
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.hhxy</groupId>
        <artifactId>day9_jsp</artifactId>
        <version>1.0-SNAPSHOT</version>
        <!--项目打包方式-->
        <packaging>war</packaging>
        <!--项目所依赖的JDK版本-->
        <properties>
            <maven.compiler.source>16</maven.compiler.source>
            <maven.compiler.target>16</maven.compiler.target>
        </properties>
        <!--=============================================-->
    
        <!--===============导入项目依赖==================-->
        <!--导入Servlet依赖-->
        <dependencies>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <!--导入JSP依赖-->
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>2.2</version>
                <!--排除Tomcat中原有的JSPjar包-->
                <scope>provided</scope>
            </dependency>
    
        </dependencies>
    
        <!--导入项目所依赖的插件-->
        <build>
            <plugins>
                <!--导入Tomcat7-maven插件-->
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <port>8080</port><!--设置端口号-->
                        <!--                    <path>/</path>设置虚拟目录-->
                    </configuration>
                </plugin>
            </plugins>
        </build>
        <!--============================================-->
    </project>
    
  • Step2:创建JSP文件

    image-20220807102202295

  • Step3:编写JSP代码

    hello.jsp

    <%--
      Created by IntelliJ IDEA.
      User: ghp
      Date: 2022/1/7
      Time: 10:22
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>JSP初体验</title>
    </head>
    <body>
        <%--这是html代码--%>
        <h1>Hello,JSP!</h1>
        <%
            /*这是Java代码*/
            System.out.println("这是我的第一个JSP程序");
        %>
    </body>
    </html>
    
  • Step4:启动Tomcat,同时将JSP项目部署到Tomcat上

    备注:所需插件:Tomcat7+MavenHelper

    image-20220807103047038

  • Step5:测试

    image-20220807103219858

3、JSP运行原理

image-20220807175631474

备注

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

可以在E:\项目\Project_JavaWeb\day9_jsp\target\tomcat\work\Tomcat\localhost\day9_jsp\org\apache\jsp目录下看到转换后的 servlet

image-20220807175902763

可以通过查看hello_jsp.java,发现它是继承HttpJspBase类的:

image-20220807181010545

而后我们可以去查看Tomcat的源码,发现HttpJspBase类是继承HttpServlet类的,这也充分说明了JSP本质就是一个Servlet,在tomcat源码\apache-tomcat-8.5.68-src\java\org\apache\jasper\runtime\HtpJspBase.java中查看(Tomcat源码可以去官网下载)

image-20220807180716546


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

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

image-20210818114008998

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

4、JSP脚本

JSP脚本也叫Java脚本,其实就是Java代码片段,指用<%%>括起来的JSP页面中的Java脚本;所有能在java程序中执行的代码,都可以通过jsp脚本执行。

JSP脚本分为三种<%...%><%=…%><%!...%>

  • <%...%>:编写Java语句。内容会直接放到_jspService()方法之中
  • <%=…%>:编写Java表达式。内容会放到out.print()中,作为out.print()的参数,然后会直接输出到页面上
  • <%!…%>:编写Java定义类成员。内容会放到_jspService()方法之外,被类直接包含

示例

hello.jsp

<%--
  Created by IntelliJ IDEA.
  User: ghp
  Date: 2022/8/7
  Time: 10:22
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSP初体验</title>
</head>
<body>
    <%--这是html代码--%>
    <h1>Hello,JSP!</h1>
    <%
        /*这是Java代码*/
        System.out.println("这是我的第一个JSP程序");
        int i=1;
    %>
    <%=i%>
<%!
    void show(){}
    String name = "zhangsan";
%>
</body>
</html>

测试结果和执行流程

image-20220807192125715

备注:html标签中的内容和<%=>一样,也是需要加载到Tomcat中,然后通过_jspService成员方法中的out.print()方法直接输出到网页上,加载后,也可以再hello_jsp.java中查看:

image-20220807193405062

5、EL表达式

EL(Expression Language )表达式语言,用于简化 JSP 页面内的 Java 代码,主要功能用于从域对象中获取数据。它的灵感来自XPath表达式语言。主要作用就是简化<%=expression%>代码

详细学习:JSP表达式语言|菜鸟教程

后面再详细学习吧,先了解一下,掌握EL表达式的常用方式

5.1 基本语法

语法

${expression};//获取域对象expression中的数据
相当于替换了原来JSP中的:<%=expression%>

eg

	  <%
        Person pperson = new Person();
        person.setName("zhangsan");
        person.setPhones(new String[]{"123","456","789"});//给Person对象中的数组进行赋值
        //设置List集合
        List<String> cities = new ArrayList<String>();
        cities.add("北京");
        cities.add("上海");
        cities.add("深圳");
        person.setCities(cities);
		//设置map集合
		Map<String,Object> map = new HashMap<>();
        map.put("key1","value1");
        map.put("key2","value2");
        map.put("key3","value3");
        person.setMap(map);
		pageContext.setAttribute("p", person);//将Person对象传递进Page域对象中
		%>
<%--EL表达式中对象名.属性名不找属性的值,而是找名字对应的getXxx方法,没有此方法会报错--%>
    输出Person对象的值:${p}   <%--需要重写p对象的toString方法,不然输出的是对象的 全类名+@哈希码--%>
    输出Person的name属性:${p.name} <%--p对象中即使没有name属性也不会报错,但是必须有getName的方法,否则会报错--%>
    输出Person的arr数组地址值:${p.phones} 
    输出Person的arr数组属性值:${p.phones[2]} 
    输出Person的list集合中的元素值:${p.cities} 
    输出PersonList集合中个别元素值:${p.cities[2]} 
    输出PersonMap集合: ${p.map} 
    输出PersonMap集合中某个key的值: ${p.map.key1} 

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

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

image-20220807204516545

EL表达式会从这些域对象中依次由内到外进行查找,直到找到为止

5.2 示例

一般EL表达式需要和JSTL标签结合使用

image-20220807210211965

Servlet:

package com.hhxy.jsp;

import com.hhxy.pojo.Brand;

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.io.IOException;
import java.util.ArrayList;
import java.util.List;

@WebServlet("/JspDemo1")
public class JspDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("doPost方法别调用了");
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("doGet方法被调用了");
        //1. 准备数据
        List<Brand> brands = new ArrayList<>();
        brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
        brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
        brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));

        //2. 存储到request域中
        request.setAttribute("lists",brands);

        //3. 请求转发到JSP中
        request.getRequestDispatcher("/brand.jsp").forward(request,response);
    }
}

JSP:

  • 使用EL表达式:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="com.hhxy.pojo.Brand" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ 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>
    <%--========================核心代码============================--%>
    <c:forEach items="${lists}" var="brand">
        <%--El表达式中对象的遍历需要搭配JSTL标签使用--%>
        <tr align="center">
            <td>${brand.id}</td>
            <td>${brand.brandName}</td>
            <td>${brand.companyName}</td>
            <td>${brand.ordered}</td>
            <td>${brand.description}</td>
            <td>${brand.status == 1 ? "启用":"禁用"}</td>
            <td><a href="#">修改</a> <a href="#">删除</a></td>
        </tr>
    </c:forEach>
<%--
   使用不同for循环的方式进行遍历
    <c:forEach begin="0" end="${lists.size()-1}" step="1" var="i">
        <tr align="center">
            <td>${lists[i].id}</td>
            <td>${lists[i].brandName}</td>
            <td>${lists[i].companyName}</td>
            <td>${lists[i].ordered}</td>
            <td>${lists[i].description}</td>
            <td>${lists[i].status == 1 ? "启用":"禁用"}</td>
            <td><a href="#">修改</a> <a href="#">删除</a></td>
        </tr>
    </c:forEach>
--%>
    <%--==========================================================--%>
</table>
</body>
</html>
  • 不使用EL表示式:
<%@ page import="com.hhxy.pojo.Brand" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ 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>
    <%--========================核心代码============================--%>
    <%
        List<Brand> lists = (List<Brand>) request.getAttribute("lists");
        for (int i = 0; i < lists.size(); i++) {
            Brand brand = lists.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>

直接运行Servlet,效果是一样的

image-20220808094406481

推荐阅读:

EL表达式

6、JSTL标签

JSTL(Java server pages standarded tag library,即JSP标准标签库)是由JCP(Java community Proces)所制定的标准规范,它主要提供给Java Web开发人员一个标准通用的标签库,并由Apache的Jakarta小组来维护。开发人员可以利用这些标签取代JSP页面上的Java代码,从而提高程序的可读性,降低程序的维护难度。

image-20220807215957243

6.1 JSTL所需环境

JSTL所需依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!--===============项目信息===================-->
    <!--Maven版本信息-->
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.hhxy</groupId>
    <artifactId>day9_jsp</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--项目打包方式-->
    <packaging>war</packaging>
    <!--项目所依赖的JDK版本-->
    <properties>
        <maven.compiler.source>16</maven.compiler.source>
        <maven.compiler.target>16</maven.compiler.target>
    </properties>
    <!--=============================================-->

    <!--===============导入项目依赖==================-->
    <!--导入Servlet依赖-->
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!--导入JSP依赖-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <!--排除Tomcat中原有的JSPjar包-->
            <scope>provided</scope>
        </dependency>
        <!--导入JSTL依赖-->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
    </dependencies>
    
    <!--导入项目所依赖的插件-->
    <build>
        <plugins>
            <!--导入Tomcat7-maven插件-->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <port>8080</port><!--设置端口号-->
                    <!--                    <path>/</path>设置虚拟目录-->
                </configuration>
            </plugin>
        </plugins>
    </build>
    <!--============================================-->
</project>

在JSP页面中引入JSTL标签库:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 

6.2 JSTL常见标签

  • <c:if test=""></c:if>:和Java中的if条件判断是一样的,test属性中放判断表达式
  • <c:forEach items="" var="" varStatus="i"></c:forEach>:作用等价于Java中的foreach语句
    • items:表示遍历的容器(可以是数组也可以是集合)
    • var:表示每一次产生的临时对象或者值
    • varStatus:该属性中的i表示第几次遍历,从0开始
  • <c:forEach begin="" end="" step="1" var="i"></c:forEach>:作用等价于Java中的普通for循环
    • begin:起始条件
    • end:终止条件
    • step:表示遍历的步长,1表示一个一个遍历,类似于for循环中的i++,2表示隔一个遍历一个,类似于for循环中的 i+=2
    • var:该属性中的i表示第几次遍历,从0开始

相关示例代码请参看前面

心有所感:

看到这些标签让我想起了MyBatis的动态SQL😃熟悉的配方,知识真的是越学越有趣,越学越容易触类旁通,然而当懂的多了的时候,反而感觉有点迷茫了,可能这是在逐渐了解知识的海洋的深而远所产生恐惧感吧(●’◡’●)

学习的路途中要时常回顾,时常总结……

要学的东西真™多啊┭┮﹏┭┮


参考文章

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知识汲取者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值