草庐IT

JSP的页面结构学习笔记

Syhang 2023-03-28 原文

JSP页面的基本结构

在传统的html页面文件中加入Java程序片和JSP标记就构成了一个JSP页面,一个JSP页面可由5种元素构成:

  • 普通的HTML标记和JavaScript标记
  • JSP标记,如指令标记、动作标记
  • 变量和方法的声明
  • Java程序片
  • Java表达式

执行过程

当Tomcat服务器上的一个JSP页面被第一次请求执行时,Tomcat服务器首先将JSP页面文件转译成一个Java文件,再将这个Java文件编译生成字节码文件,然后通过执行字节码文件响应用户的请求。

字节码文件的任务:

  • 将JSP页面中的HTML标记和JavaScript标记交给用户端浏览器执行显示
  • JSP标记、方法的定义、Java程序片由服务器处理和执行,将需要显示的结果发给用户端浏览器

声明变量和定义方法

<%!%>标记符号之间声明变量和定义方法。

书写位置

<%!%>标记符号习惯上放在JSP页面指令之后,<HTML>之前,也就是放在JSP页面的前面。但是<%!%>标记符号在整个JSP页面都有效,与书写位置无关,因此也可以写在<HTML>和</HTML>之间。

特性

<%!%>标记符号之间声明的变量作为类的成员变量被每个用户线程共享,因此任何一个用户对JSP页面成员变量的操作都会影响其他用户。

Java程序片

可以在<%%>之间插入Java程序片,一个JSP页面可以有多个Java程序片,这些程序片将被Tomcat按顺序执行,程序片中定义的变量为JSP页面的局部变量。

书写位置

可以写在<HTML>之前,也可以写在<HTML>之间,也可以写在<HTML>之后。

特性

  • 操作成员变量:任何一个线程对JSP页面成员变量操作的结果,都会影响其他线程
  • 操作局部变量:Java程序片运行在不同的线程中,局部变量互不影响,程序片执行完毕即释放局部变量
  • synchronized修饰:当一个线程在执行Java程序片期间调用synchronized方法时,其他线程在调用这个synchronized方法就必须等待。(比如当操作成员变量的时候不希望其他用户同时操作成员变量,例如计数器)
  • Java程序片可以分割成几个程序片,然后再这些程序片之间插入其他标记元素

eg.

...
<%
	int number = 7 + (int)(Math.random()*13);
	if(number <= 13){
%>
	<center><h2>显示小学生图片</h2>
<%  }
    else{
%>
    <center><h2>显示中学生图片</h2>
<%  }
%>
...

Java表达式

可以在<%=%>之间插入一个可求值的表达式

注意:不可插入语句

表达式的值由服务器负责计算,并将计算结果用字符串的形式发送到客户端显示。

书写位置

可以写在<HTML>之前,也可以写在<HTML>之间,也可以写在<HTML>之后。

使用举例

<%= x>y %>
<%= Math.sqrt(x-y) %>

JSP中的注释

注释可以增强JSP页面的可读性,使之更易于维护。

JSP页面中的注释分为两种:

HTML注释

<!---->中加入注释内容

<!-- 注释内容 -->

JSP注释

在标记符号<%--%>之间加入注释内容

<%-- 注释内容 --%>

Tomcat服务器会在编译时忽略JSP注释。

另注

如果你想要在java代码片中添加注释,那么需要按照java注释来写

JSP指令标记

page指令标记

page属性用来定义整个JSP页面的一些属性和这些属性的值,属性值用单引号或双引号括起来。可以使用多个page指令分别为每个属性指定值:

<%@ page 属性1 = "属性1的值" %>
<%@ page 属性2 = "属性2的值" %>
<%@ page 属性n = "属性n的值" %>

也可以用一个page属性指定多个属性的值:

<%@ page 属性1 = "属性1的值" 属性2 = "属性2的值"

eg.

<% @ page contentType="text/html" pageEncoding = "utf-8" %>
书写位置

对整个JSP界面都有效,与书写位置无关,但习惯上写在最前面。

contentType属性

Tomcat服务器要通知用户的浏览器用怎样的方式来处理接收到的信息,这就要求JSP页面必须设置响应的MIME类型,即设置contentType的值。

如果我们希望用户的浏览器启动HTML解析器来解析执行所接收到的信息,那么可以按照如下方式(如果不指定,也是此默认值):

<% @ page contentType = "text/html" %>

如果希望用户的浏览器启动本地的MS-Word应用程序来解析执行所接收到的信息,那么可以按照如下方式:

<% @ page contentType = "application/msword" %>

但是注意,JSP不允许两次使用page指令给contentType属性指定不同的属性值,例如以下做法是错误的:

<% @ page contentType = "text/html" %>
<% @ page contentType = "application/msword" %>

用page指令为contentType指定一个值的同时,也可以为contentType的附加属性charset制定一个值(默认是iso-8859-1),例如:

<% @ page contentType = "text/html;charset=gb2312" %>

charset的值是通知用户浏览器用怎样的编码解析收到的字符。

当JSP页面用page指定了JSP的页面本身的编码,例如:

<% @ page pageEncoding="UTF-8" %>

此时,charset编码与JSP页面编码保持一致,为utf-8,因此一般不需要再指定charset的值,使其和JSP页面编码保持一致即可。

pageEncoding属性

pageEncoding属性的默认值是UTF-8。

需要注意的是,与contentType的附加属性charset的值意义不同,pageEncoding属性值是定义JSP页面使用的编码,是告诉Tomcat服务的解析器用怎样的编码解析JSP页面中的字符。

保存JSP页面应当将编码选择为UTF-8,因为Tomcat服务器是根据UTF=8编码来解析JSP页面中的字符数据的。

JSP页面使用page指令只能为pageEncoding指定一个值不允许两处使用page指令给pageEncoding指定相同或不同的值。

language属性

language属性定义JSP页面使用的脚本语言,该属性的值目前只能取java

<% @ page language = "java" %>

如果不写,那么JSP也有默认上述指令。

import属性

该属性的作用是为JSP引入java运行环境所提供的包中的类。

可以为该属性指定多个值,该属性的值可以是某包中的所有类或者一个具体的类。

<% @ page import = "java.io.*","java.time.LocalDate" %>

JSP页面默认import属性已经有如下的值:

"java.lang.*"
"javax.servlet.*"
"javax.servlet.jsp.*"
"javax.servlet.http.*"
session属性

session属性设置是否需要使用内置的session对象,属性值可以是true或者false,默认值是true。

buffer属性

buffer属性用来指定out设置的缓冲区大小或者不使用缓冲区。

<% @ page buffer = "24kb" %>
autoFlush属性

autoFlush属性指定out的缓冲区被填满时,缓冲区是否自动刷新。属性值可以是true或者false,默认值是true。

当buffer的值是none时,autoFlush的值就不能设置成false。

isThreadSafe属性

isThereadSafe属性用来设置访问JSP页面是否是线程安全的。属性值可以是true或者false,默认值是true。

当值为true时,JSP页面可以同时响应多个用户的请求,当值为false时,JSP页面同一时刻只能响应一个用户的请求,其他用户须排队等待。

info属性

info属性是一个字符串,其目的是为JSP页面准备一个常用但可能要经常修改的字符串,如:

<% page info = "we are students" %>

可以在JSP页面中使用方法:

getServletInfo()

include指令标记

如果需要在JSP页面内某处整体嵌入一个文件,就可以考虑使用include指令标记:

<% @ include file = "文件的Url" %>

include指令标记的作用是在JSP页面出现该指令的位置处,静态嵌入一个文件。

  • 该文件的编码必须与当前JSP页面一致。
  • 该文件必须是可以访问或者可以使用的。

静态嵌入是指当前JSP页面与嵌入的文件合并成一个新的JSP页面,然后Tomcat服务器再将这个新的JSP页面转译成Java文件。因此,嵌入文件后,必须保证新合并成的JSP页面符合JSP语法规则,即能够成为一个新的JSP页面文件。

eg.被嵌入文件是一个JSP文件,该JSP页面使用了page指令为contentType设置了值:

<% @ page contentType = "application/msword" %>

那么,合并后的JSP就两次使用page指令为contentType属性设置了不同的属性值,导致语法错误。

注意:允许被嵌入文件使用page指令指定contentType属性的值,但指定的值必须与被嵌入页面JSP中指定的值相同

JSP动作标记

动作标记是一种特殊的标记,它影响JSP运行时的功能。

include动作标记

语法格式
<jsp:include page="文件的URL"/>

<jsp:include page="文件的URL">
param子标记
</jsp:include>

需要注意的是,当include动作标记不需要param子标记时,必须使用第一种形式。

include动作标记告诉JSP页面动态包含一个文件,即JSP页面运行时才将文件加入。

include指令标记:静态包含,先合并再编译。

include动作标记:动态包含,生成Java文件时不合并,当JSP运行(Java文件的字节码文件被加载执行)时才被包含进来。如果包含的是文本文件就直接发到用户端,如果是JSP文件就先由Tomcat执行再将结果发到用户端。

对比
处理时间 执行速度 灵活性
include指令标记 编译阶段处理 被处理的文件逻辑和语法依赖当前JSP页面
include动作标记 JSP页面运行时处理 被处理的文件逻辑和语法独立于当前JSP页面,可以使用param子标记

param动作标记

param标记以名字-值对的形式为其他标记提供附加信息,不能独立使用,必须作为jsp:includejsp:forward标记的子标记来使用。

语法格式
<jsp:param name="参数" value="参数的值" />

当标记与jsp:include动作标记一起使用时,可以将param标记中的参数的值传到include动作标记要加载的文件中去。被加载的JSP文件可以用Tomcat服务器所提供的的request内置对象获取参数的值。

eg.

<!-- exam1.jsp  -->
<jsp:include page = "exam2.jsp">
    <jsp:param name="msg" value="Hello,world!"/>
</jsp:include>

<% -- exam2.jsp -- %>
request.getParameter("msg");

forward动作标记

语法格式
<jsp:forward page = "要转向的页面" />

<jsp:forward page = "要转向的页面">
    param子标记
</jsp:forward>

该指令的作用是,从该指令处停止当前页面的执行,而转向执行page属性指定的JSP页面。

注意:当没有param子标记时必须采用第一种形式

forward标记可以使用param动作标记作为子标记向转向的页面传送信息,接收方法同include也是利用request.getParameter()获取。

需要注意的是,当前页面使用forward动作标记转向后,尽管看到的效果是转向后的页面效果,但是浏览器地址栏显示的依然是转向前的JSP页面的URL地址。因此,如果刷新浏览器的显示,将再次执行当前浏览器地址栏中显示的JSP页面。

比如,当前页面是生成一个0-1随机数,如果随机数的值为1那么则转向a.jsp,否则转向b.jsp。那么你在刷新这个页面的时候,地址栏显示都是此页面的url,但是显示效果可能有时是a.jsp页面,有时是b.jsp页面。

useBean

useBean标记用来创建并使用一个JavaBean,是非常重要的一个动作标记。

Sun公司倡导JavaBean负责存储数据,JSP页面显示JavaBean中的数据,servlet负责管理JavaBean中的数据。

有关JSP的页面结构学习笔记的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  3. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  4. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  5. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  6. ruby-on-rails - 一般建议和推荐的文件夹结构 - Sinatra - 2

    您将如何构建一个简单的Sinatra应用程序?我正在制作,我希望该应用具有以下功能:“应用程序”更像是一个包含所有信息的管理仪表板。然后另一个应用程序将通过REST访问信息。我还没有创建仪表板,只是从数据库中获取东西session和身份验证(尚未实现)您可以上传图片,其他应用可以显示这些图片我已经使用RSpec创建了一个测试文件通过Prawn生成报告目前的设置是这样的:app.rbtest_app.rb因为我实际上只有应用程序和测试文件。到目前为止,我已经将Datamapper用于ORM,将SQLite用于数据库。这是我的第一个Ruby/Sinatra项目,所以欢迎任何和所有建议-我应

  7. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  8. ruby - 在 ASP 页面上 Mechanize 中断 - 2

    require'mechanize'agent=Mechanize.newlogin=agent.get('http://www.schoolnet.ch/DE/HomeDE.htm')agent.clicklogin.link_withtext:/Login/然后我得到Mechanize::UnsupportedSchemeError。 最佳答案 Mechanize不支持javascript但您可以将搜索字段添加到表单并为其分配搜索词并使用mechanize提交表单form=page.forms.firstform.add_fie

  9. ruby - 如何在 ruby​​ 中复制目录结构,不包括某些文件扩展名 - 2

    我想编写一个ruby​​脚本来递归复制目录结构,但排除某些文件类型。因此,给定以下目录结构:folder1folder2file1.txtfile2.txtfile3.csfile4.htmlfolder2folder3file4.dll我想复制这个结构,但不包含.txt和.cs文件。因此,生成的目录结构应如下所示:folder1folder2file4.htmlfolder2folder3file4.dll 最佳答案 您可以使用查找模块。这是一个代码片段:require"find"ignored_extensions=[".cs"

  10. ruby-on-rails - prawnto 显示新页面时不会中断的表格 - 2

    我有可变数量的表格和可变数量的行,我想让它们一个接一个地显示,但如果表格不适合当前页面,请将其放在下一页,然后继续。我已将表格放入事务中,以便我可以回滚然后打印它(如果高度适合当前页面),但我如何获得表格高度?我现在有这段代码pdf.transactiondopdf.table@data,:font_size=>12,:border_style=>:grid,:horizontal_padding=>10,:vertical_padding=>3,:border_width=>2,:position=>:left,:row_colors=>["FFFFFF","DDDDDD"]pdf.

随机推荐