【Java Web编程 三】JSP基本概念和语法

简介: 【Java Web编程 三】JSP基本概念和语法

上文中提到,Tomcat会处理JSP和Servlet两种类型的文件,那么我们先来看看这两种类型文件是什么,有什么作用,然后再从Tomcat的架构角度去看请求是怎么被处理的,本篇文章重点探讨JSP的整体运行机制。

JSP概念简介

前文我们说过有静态和动态两种网站模式,其实我们大多数的网站都是动态网站,所以不能依赖单纯的Html去构建。这个时候我们有两种方式去解决这个问题:

  1. 把html代码和样式嵌入到Java代码中,然后将Java文件解析运行,这种方式下我们需要分析的是html代码,将html代码打印出来
  2. 把Java代码嵌入到html代码和样式中,然后将该文件动态解析为Java文件运行,这种方式下我们需要分析的是Java代码,将Java代码运行。

依据实际情况来看,因为html样式代码数量远大于Java代码,我们的修改动作也较为频繁,而我们希望更方便的调整html样式而不需要面对大量的print打印语句。

所以我们选择第二种方式,由此也引出了JSP的概念:Java Server Page 简称 JSP,是由 Sun 公司倡导建立的一种动态网页技术标准,用于开发动态网页,JSP就是将传统Java代码嵌入到Html页面代码中,由Web服务器进行编译执行,生成最终的静态Html返回客户端

JSP执行流程

浏览器无法直接运行JSP文件,只有将包含JSP文件的Web项目部署到Web服务器上,才能看到JSP的显示效果,当客户端浏览器向服务器发出请求访问一个JSP页面后,服务器根据该请求加载相应的JSP 页面,并对该页面进行转换、编译和执行。

具体的执行过程如下:

  1. 浏览器发送一个 HTTP 请求给服务器。
  2. Web 服务器识别出这是一个对 JSP 网页的请求,并且将该请求传递给 JSP 引擎。通过使用 URL或者 .jsp 文件来完成。
  3. JSP 引擎从磁盘中载入 JSP 文件,然后将它们转化为 Servlet。这种转化只是简单地将所有模板文本改用 println() 语句,并且将所有的 JSP 元素转化成 Java 代码。
  4. JSP 引擎将 Servlet 编译成可执行类,并且将原始请求传递给 Servlet 引擎。
  5. Web 服务器的某组件将会调用 Servlet 引擎,然后载入并执行 Servlet 类。在执行过程中,Servlet 产生 HTML 格式的输出并将其内嵌于 HTTP response 中上交给 Web 服务器。
  6. Web 服务器以静态 HTML 网页的形式将 HTTP response 返回到浏览器中。
  7. 最终,Web 浏览器处理 HTTP response 中动态产生的HTML网页,就好像在处理静态网页一样

总体而言,引擎会帮我们将JSP编译为Servlet,然后执行

JSP组成元素

JSP文件中包括两类代码:JSP元素和Template(模版):

  • JSP元素:指的就是<%...... %>内的代码,这部分代码是JSP引擎直接处理的部分,这部分必须符合Java语法
  • Template(模版):指的就是<%...... %>外的代码,例如代码中HTML的内容,这些数据JSP引擎不作处理,直接返回给客户端的浏览器

所以解析处理的时候其实只需要处理JSP元素。

JSP生命周期

JSP生命周期就是从创建到销毁的整个过程,类似于servlet生命周期,区别在于JSP生命周期还包括将JSP文件编译成servlet:

  1. 编译阶段:servlet容器编译servlet源文件,生成servlet类。当浏览器请求JSP页面时,JSP引擎会首先去检查是否需要编译这个文件。如果这个文件没有被编译过,或者在上次编译后被更改过,则编译这个JSP文件。分为三个步骤:解析JSP文件;将JSP文件转为servlet;编译servlet
  2. 初始化阶段:加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法jspInit
  3. 执行阶段:调用与JSP对应的servlet实例的服务方法_jspService
  4. 销毁阶段:调用与JSP对应的servlet实例的销毁方法jspDestroy,然后销毁servlet实例

整个流程图如下:

JSP语法标识

JSP的语法分为三类:指令标识、脚本标识注释标识动作标识。这里我们以一个JSP页面进行举例,贯穿接下来的练习代码

index.jsp文件

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*" %>
<%@ include file="top.jsp" %>
<!DOCTYPE html>
<html>
<head>
    <title>JSP - Hello World</title>
    <%!
        int number = 0;// 声明全局变量
        int count() {
            number++;//number 自增
            return number;
        }%>
</head>
<h1><%= "Hello World!" %>
</h1>
<br/>
<body>
<%
    String print = "我是脚本语句内容";
    List<String> strList = new ArrayList<>();
    strList.add("脚本语句1");
    strList.add("脚本语句2");
    strList.add("脚本语句3");
//  strList.add("脚本语句4");  //这是一个Java注释,用来注释Java代码,查看源码时不可见
%>
<a href="hello-servlet">我的第一个JavaWeb项目</a> <!-- 这是一个html注释,可见<%= new Date().getTime() %> -->
<br/>
<%--这是一个JSP注释,查看源码时不可见--%>
声明语句示例:这是第 <%=count()%> 次访问该页面
<br/>
表达式语句示例: <%="我是一个表达式语句"%>
<br/>
脚本语句示例: <%=print%>, 打印列表 <%=strList%>
<jsp:forward page="result.jsp"></jsp:forward>
跳转语句之后,代码不会被执行:<%="我是一个跳转后的表达式语句"%>
</body>
</html>

top.jsp文件

<%--
  Created by IntelliJ IDEA.
  User: tianmaolin
  Date: 2021/7/13
  Time: 8:15 下午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*" %>
<html>
<head>
    <title>我是include的top.jsp页面</title>
</head>
<body>
<%
  String printTop="top打印";
%>
<a href="hello-servlet">我是top的打印,<%=printTop%></a>
</body>
</html>

result.jsp文件

<%--
  Created by IntelliJ IDEA.
  User: tianmaolin
  Date: 2021/7/14
  Time: 11:32 上午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>跳转的结果页面</title>
</head>
<body>
<a>我是跳转后的结果页面</a>
</body>
</html>

test.jsp文件

按照语法基础,我们实践三种语法流程:判断逻辑,循环逻辑:

<%--
  Created by IntelliJ IDEA.
  User: tianmaolin
  Date: 2021/7/14
  Time: 12:30 下午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.*,java.io.*" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%! int day = 3; %>
if语句输出练习:
<br/>
<% if (day == 1 || day == 7) { %>
<p>今天是周末</p>
<% } else { %>
<p>今天不是周末</p>
<% } %>
<br/>
for语句输出练习;
<br/>
<%for ( int fontSize = 1; fontSize <= 3; fontSize++){ %>
<span style="color: green; ">
    循环第 <%=fontSize%> 遍<br/>
</span><br/>
<%}%>
</body>
</html>

指令标识

指令标识主要用于设定在整个 JSP 页面范围内都有效的相关设置信息,它是被服务器解释并执行的,不会产生任何内容输出到网页中,格式如下:

<%@ 指令名 属性 1=“属性值 1” 属性 2=“属性值 2”...%>
  • 指令名:用于指定指令名称,在 JSP 中包含 page、include 和 taglib 3 个指令。
  • 属性:用于指定属性名称,不同的指令包含不同的属性。在一个指令中,可以设置多个属性,属性之间用逗号或空格隔开。
  • 属性值:用户指定属性值

上述文件中<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> 就是一个page指令。

指令标识包含:page指令、include指令以及taglib指令。

page指令

Page指令为容器提供当前页面的使用说明。一个JSP页面可以包含多个page指令,page的标准语法如下:

<%@ page attribute="value" %>

page指令的常用属性如下:

例如我们想要访问list相关的方法,就需要引入java的util类:

<%@ page language="java" import="java.util.*,java.io.*" pageEncoding="UTF-8"%>

include指令

JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是该JSP文件的一部分,会被同时编译执行。Include指令的语法格式如下:

<%@ include file="文件相对 url 地址" %>

include 指令中的文件名实际上是一个相对的 URL 地址,例如:

注意:在应用 include 指令包含文件时,为使整个页面的层次结果不发生冲突,应将被包含页面中的 元素和 元素删除,因为包含该页面的文件中已经指定了这些标记

Taglib指令

在 JSP 文件中,可以通过 taglib 指令声明该页面中所使用的标签库,同时引用标签库,并指定标签前缀,在页面中引用标签库后,就可以通过前缀引用标签库中的标签

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

标签库的使用后续会提到。

脚本标识

脚本标识是JSP中最主要的元素,相当于JSP中需要编译的那一部分内容,也是JSP语法中的核心内容,包含声明、表达式以及脚本段

声明

声明标识用于在 JSP 页面中定义全局的变量或方法,通常使用该标识定义整个 JSP 页面需要引用的变量或方法,在JSP文件中,必须先声明这些变量和方法然后才能使用它们,相当于Java里的成员变量和成员方法定义。语法规则如下:

<%! 声明变量或方法代码 %>

一个全局的统计访问次数的例子如下:

<%!
        int number = 0;// 声明全局变量
        int count() {  //声明全局方法
            number++;//number 自增
            return number;
        }%>
  这是第 <%=count()%> 次访问该页面

可以打印出来第几次访问页面

脚本段

Scriptlet(代码片段)脚本程序,是在 JSP 页面中嵌入的 Java 代码或脚本代码,代码片段将在页面请求的处理期间被执行,通过 Java 代码可以定义变量或流程控制语句等,相当于Java里main方法的代码逻辑,语法规则如下:

<% 表达式或者变量名 %>

脚本段语句示例:

<%
    String print = "我是脚本语句内容";
    List<String> strList = new ArrayList<>();
    strList.add("脚本语句1");
    strList.add("脚本语句2");
    strList.add("脚本语句3");
%>
脚本语句示例: <%=print%>, 打印列表 <%=strList%>

可以直接打印脚本段内的内容。

表达式

JSP 表达式用于向页面中输出信息,类似于System.out.println()括号中的内容,相当于Java里main方法里的System.out.println()语句,只不过是输出回客户端,而非服务端本地打印,语法规则如下:

<%= 表达式或者变量名 %>

以上我们无论是声明还是脚本段的输出其实都用到了表达式:

<br/>
声明语句示例:这是第 <%=count()%> 次访问该页面
<br/>
表达式语句示例: <%="我是一个表达式语句"%>
<br/>
脚本语句示例: <%=print%>, 打印列表 <%=strList%>

注释标识

注释用于对某些代码做功能性的说明,从而增加程序的可读性。JSP 程序中可以包含 3 种不同类型的注释:

JSP注释

JSP注释主要有两个作用:为代码作注释以及将某段代码注释掉。主要是给JSP页面提供注释,JSP注释在客户端浏览器无法查看到,注释内容不会被发送至浏览器甚至不会被编译,其语法规则如下:

<%-- JSP标准注释 --%>

例如我们可以这么编写:

<%--表达式展示的JSP注释--%>
声明语句示例:这是第 <%=count()%> 次访问该页面
<br/>
表达式语句示例: <%="我是一个表达式语句"%>
<br/>
脚本语句示例: <%=print%>, 打印列表 <%=strList%>
</body>

Java注释

Java注释指的是java代码,和Java代码的注释格式是一致的,同样的Java注释在客户端浏览器无法查看到,注释内容不会被发送至浏览器甚至不会被编译,语法规则如下:

<%
       //Java单行注释
       /*
           Java多行注释
       */
%>

例如我们可以这么编写:

<%
    String print = "我是脚本语句内容";
    List<String> strList = new ArrayList<>();
    strList.add("脚本语句1");
    strList.add("脚本语句2");
    strList.add("脚本语句3");
//  strList.add("脚本语句4");  //这是一个Java注释,用来注释Java代码
%>

HTML注释

HTML注释主要给JSP页面的Template元素提供注释,HTML网页注释在客户端浏览器可以看到,语法规则如下:

<!-- HTML网页注释 -->

这类在查看源码时可见,其中的脚本语句也是可执行的,示例如下:

<!-- 这是一个html注释,可见<%= new Date().getTime() %> -->

点击查看源码我们可以看到注释:

动作标识

JSP行为标签使用XML语法结构来控制servlet引擎。它能够动态插入一个文件,重用JavaBean组件,引导用户去另一个页面,为Java插件产生相关的HTML等等。行为标签只有一种语法格式,它严格遵守XML标准。其语法格式如下:

<jsp:action_name attribute="value" />

包含很多种可以作用的动作标识:

举例说明如下,执行到跳转动作后会跳转到结果页面:

<jsp:forward page="result.jsp"></jsp:forward>
跳转语句之后,代码不会被执行:<%="我是一个跳转后的表达式语句"%>

总结一下

这篇Blog我们大致了解了JSP的基本概念,为什么要用JSP,以及JSP的生命周期、执行流程和组成元素,但是最最重要的还是JSP的基本语法:指令、注释、脚本、动作,这几个各有用处,指令管理页面的配置和属性,脚本管理JSP元素的代码和逻辑,动作可以简化指令和脚本,用标签的形式去体现,让整个页面Java代码更少看起来更加的配置化,注释则用于对文件进行解释。其中脚本可谓核心,我们希望脚本的内容越少越好,这样JSP的视图而非逻辑作用发挥的就越好,所以后续我们还会学习一些高级语法:JSTL标签和EL表达式,这两配合起来可以大量简化写法

相关文章
|
2月前
|
安全 Java API
Java Web 在线商城项目最新技术实操指南帮助开发者高效完成商城项目开发
本项目基于Spring Boot 3.2与Vue 3构建现代化在线商城,涵盖技术选型、核心功能实现、安全控制与容器化部署,助开发者掌握最新Java Web全栈开发实践。
330 1
|
2月前
|
存储 前端开发 Java
【JAVA】Java 项目实战之 Java Web 在线商城项目开发实战指南
本文介绍基于Java Web的在线商城技术方案与实现,涵盖三层架构设计、MySQL数据库建模及核心功能开发。通过Spring MVC + MyBatis + Thymeleaf实现商品展示、购物车等模块,提供完整代码示例,助力掌握Java Web项目实战技能。(238字)
282 0
|
1月前
|
Java 编译器 Go
【Java】(5)方法的概念、方法的调用、方法重载、构造方法的创建
Java方法是语句的集合,它们在一起执行一个功能。方法是解决一类问题的步骤的有序组合方法包含于类或对象中方法在程序中被创建,在其他地方被引用方法的优点使程序变得更简短而清晰。有利于程序维护。可以提高程序开发的效率。提高了代码的重用性。方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。这种就属于驼峰写法下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。
168 5
|
3月前
|
JavaScript Java 微服务
现代化 Java Web 在线商城项目技术方案与实战开发流程及核心功能实现详解
本项目基于Spring Boot 3与Vue 3构建现代化在线商城系统,采用微服务架构,整合Spring Cloud、Redis、MySQL等技术,涵盖用户认证、商品管理、购物车功能,并支持Docker容器化部署与Kubernetes编排。提供完整CI/CD流程,助力高效开发与扩展。
448 65
|
3月前
|
前端开发 Java 数据库
Java 项目实战从入门到精通 :Java Web 在线商城项目开发指南
本文介绍了一个基于Java Web的在线商城项目,涵盖技术方案与应用实例。项目采用Spring、Spring MVC和MyBatis框架,结合MySQL数据库,实现商品展示、购物车、用户注册登录等核心功能。通过Spring Boot快速搭建项目结构,使用JPA进行数据持久化,并通过Thymeleaf模板展示页面。项目结构清晰,适合Java Web初学者学习与拓展。
274 1
|
4月前
|
存储 缓存 NoSQL
java 集合入门基础理论的核心概念与实用长尾知识
本文介绍了Java集合框架的基础理论知识,包括单列集合(List、Set、Queue)和双列集合(Map)的特点及常用实现类(如ArrayList、HashSet、HashMap等)。详细讲解了集合的遍历方式(迭代器、增强for循环、Lambda表达式)和典型应用场景(如数据去重、键值存储等)。通过具体代码示例,帮助初学者理解集合框架的核心概念和实际应用,为Java编程中的数据存储与管理提供基础指导。
127 0
|
4月前
|
缓存 NoSQL Java
Java Web 从入门到精通之苍穹外卖项目实战技巧
本项目为JavaWeb综合实战案例——苍穹外卖系统,涵盖Spring Boot 3、Spring Cloud Alibaba、Vue 3等主流技术栈,涉及用户认证、订单处理、Redis缓存、分布式事务、系统监控及Docker部署等核心功能,助你掌握企业级项目开发全流程。
490 0
|
4月前
|
安全 JavaScript Java
java Web 项目完整案例实操指南包含从搭建到部署的详细步骤及热门长尾关键词解析的实操指南
本项目为一个完整的JavaWeb应用案例,采用Spring Boot 3、Vue 3、MySQL、Redis等最新技术栈,涵盖前后端分离架构设计、RESTful API开发、JWT安全认证、Docker容器化部署等内容,适合掌握企业级Web项目全流程开发与部署。
275 0
|
5月前
|
存储 安全 Java
2025 年最新 40 个 Java 基础核心知识点全面梳理一文掌握 Java 基础关键概念
本文系统梳理了Java编程的40个核心知识点,涵盖基础语法、面向对象、集合框架、异常处理、多线程、IO流、反射机制等关键领域。重点包括:JVM运行原理、基本数据类型、封装/继承/多态三大特性、集合类对比(ArrayList vs LinkedList、HashMap vs TreeMap)、异常分类及处理方式、线程创建与同步机制、IO流体系结构以及反射的应用场景。这些基础知识是Java开发的根基,掌握后能为后续框架学习和项目开发奠定坚实基础。文中还提供了代码资源获取方式,方便读者进一步实践学习。
1430 2
|
5月前
|
分布式计算 Java 大数据
Java 语言基础概念与常识之主要特点解析
Java是一种广泛应用于企业级开发、移动应用(如Android)、大数据处理及云计算等领域的编程语言。其核心特点包括跨平台性(一次编写,到处运行)、面向对象设计、自动垃圾回收、多线程支持和高性能表现。Java通过JVM实现跨平台,具备强大的健壮性和安全性,同时拥有丰富的标准库与活跃的开发者社区。本文深入解析Java的技术优势及其在电商系统、大数据处理和云计算中的实际应用,并提供相关面试资料供学习参考。
142 0