JAVAweb开发 —— JSP语法

 

前言

一个jsp包含了若干个语法,本章将了解一些基础的语法并学会如何在jsp中使用语法


2.1、JSP页面的基本结构

    在传统的HTML页面文件中加入JAVA程序片和JSP标记就构成了一个JSP页面。一个JSP页面可由五种元素组合而成:

  •         普通的HTML标记和JavaScript标记

  •         JSP标记,如指令标记、动作标记

  •         变量和方法的声明

  •         JAVA程序片

  •         JAVA表达式

    当Tomcat服务器上的一个JSP页面被第一次请求执行时,Tomcat服务器上的一个 JSP页面转译成一个JAVA文件,再将这个JAVA文件编译生成字节码文件,然后通过字节码文件响应用户的请求。当多个用户请求一个JSP页面时,Tomcat服务器为每个用户启动一个线程,该线程负责执行常驻内存的字节码文件来响应用户的请求。这些线程由Tomcat服务器来管理,将CPU的使用权在各个线程之间快速切换,以保证每个线程都有机会执行字节码文件。这个字节码文件的任务就是:

  • 把JSP页面中普通的HTML标记和JavaScript标记交给用户端浏览器执行显示。
  • JSP标记、方法的定义、JAVA程序片由服务器负责处理和执行,将需要显示的结果发送给用户端浏览器。
  • JAVA表达式由服务器负责计算,并将结果转化为字符串,然后交给用户端浏览器负责显示。

2.2   声明变量和定义方法 

   1.声明变量   

   不同于JAVA,在JSP中定义变量和方法需要在标记符号<%! - - - %>內进行。<%! - - - %>标记符号的内容应放在JSP页面指令之后,<HTML>之前,也可以放在<HTML>和</HTML>之间。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body bgcolor="white">
<%!
    int i = 0;
%>
<%
    i++;
%>
<p style="font-family: 宋体;font-size: 22px">
你是第<%=i%>个访问的用户
</p>
</body>
</html>

13cebf476db344da9b05f0fa0ba0f41c.png    图中所声明的变量i在page上进行刷新时不会消失,相当于成员变量。

    2.定义方法

   可以在<%! - - - %>标记符号之间定义方法,并在JAVA程序片中调用该方法。方法内声明的变量只能在该方法內有效,当方法被调用时,方法内声明的变量被分配内存,方法被调用完毕即可释放这些变量所占的内存。

   可以在<%! - - - %>标记符号之间定义类,可以在JAVA程序片中使用该类创建对象。如下图定义的两个方法和Circle类,计算出了圆的面积

<html>
<body bgcolor="white">
<p style="font-family: 宋体;font-size: 22px;color: black">
<%!
    double multi(double x,double y){
        return x*y;
    }
    double div(double x,double y){
        return x/y;
    }
    class Circle{
        double r;
        double getArea(){
            return 3.14*r*r;
        }
    }
%>>
    <%
        double x = 8;
        double y = 10;
        out.print(multi(x,y));
        out.print(div(x,y));
        String s = String.format("%10.3f",div(y,x));
        out.print(s);
        Circle circle = new Circle();
        circle.r = 3.6;
        out.print(circle.getArea());
    %>
</p>
</body>
</html>

2.3   JAVA程序片

   一个JSP页面中可以有许多程序片,这些程序片被Tomcat服务器按顺序执行。在程序片中声明的变量称作JSP页面的局部变量。局部变量的有效范围与其生命的位置有关,即全局变量在JSP页面后继的所有程序片以及表达式部份内都有效。Tomcat服务器将JSP页面转译成JAVA文件时,将各个程序片的这些变量作为类中某个方法的变量,即局部变量。

   JAVA程序片可以写在<HTML>之前,也可以写在<HTML>和</HTML>之间或者之后。当多个用户请求一个JSP页面时,Tomcat服务器为每个用户启动一个线程,该线程负责执行字节码文件响应用户的请求。

  如果一个用户在执行JAVA程序片时调用JSP页面额方法操作成员变量,可能不希望其他用户也调用该方法操作成员变量,以免对其产生不利的影响,那么就应该将操作成员变量的方法用synchronized关键字修饰。当一个线程在执行JAVA程序片期间调用该方法时,其他线程在其JAVA程序片中调用这个synchronized方法时就必须等待,直到正在调用该方法的线程调用执行完该方法。

   一个JSP页面中的JAVA程序片会按其在页面中的顺序被执行,而且某个JAVA程序片中生命的局部变量在其后继的所有JAVA程序篇以及表达式部分内都有效。利用JAVA程序片中的这个性质,有时候可以讲一个JAVA程序片分割成几个JAVA程序片,然后再这些JAVA程序片之间在插入其他标记元素。在程序片中插入HTML中的标记对于灵活显示数据是非常重要的。通常的格式是:

HTML中的标记
<%
    JAVA程序片
%>
HTML中的标记
<%
    JAVA程序片
%>
HTML中的标记

2.4   JAVA表达式

   可以在<%= - - - %>之间插入一个可求值的表达式(注意:%和=之间不能有空格)。表达式的值由服务器负责计算,并将计算结果用字符串的形式发送到用户端显示。

   JAVA表达式可以写在<HTML>之前,也可以写在<HTML>和</HTML>之间或者之后。在JSP页面中,表达式的值被表示成一个字符串的形式,即Tomcat服务器将表达式的结果转换成字符串,然后发送给用户的浏览器。因此,在编写JSP页面时,要把JAVA表达式按普通文本来使用。例如:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body bgcolor="white">
<%
    int x = 12,y = 9;
%>
<p style="font-family: 宋体;font-size: 22px;color: black">
计算表达式x+y+x%y,即<%=x%>+<%=y%>+<%=x%>%<%=y%>的值
    <%=x+y+x%y%>
    <br>
    计算表达式x>y<%=x%>><%=y%>的值:
    <%=x>y%>
    <br>
    计算表达式sin(<%=Math.PI%>/2)的值:
    <%=Math.sin(Math.PI/2)%>
    <br>
    <%
    if (x-y>=0)
    %>
    如果<%=x%>大于<%=y%>,计算<%=x%>-<%=y%>即
    <%=x-y%>的平方根:
    <%=Math.sqrt(x-y)%>
</p>
</body>
</html>

2.5   JSP中的注释

   灵活使用注释可以增强JSP页面的可读性,使JSp页面易于维护。JSP页面中的注释可分为两种

   (1)HTML注释:在标记符号<! - - - >之间加入注释内容:

<! - 注释内容 - - >

   JSP引擎把HTML注释交给用户,因此用户通过浏览器查看JSP页面的源文件时,能够看到HTML注释。   

(2)JSP注释:在标记符号<% - -   - - %>之间加入注释内容:

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

   Tomcat服务器忽略了JSP注释,即在编译JSP页面时忽略了JSP注释。

<!--这是HTML注释-->

<%--这是JSP注释--%>

2.6    JSP指令标记

  • 2.6.1   page指令标记

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

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

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

...

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

也可以用一个page指令同时指定多个属性的值,如:

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

例如,我们经常会在JSP页面首端编写的两个指令:

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

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

也可以合并成一个page指令,如:

<%@page contentType = "text/html" pageEncoding = "utf-8" %>

   page指令的作用对整个JSP页面有效,与其书写的位置无关。习惯上把page指令写在JSP页面的最前面。

   page指令标记可以为contentType、import、language、session、buffer、autoFlushis、ThreadSafe、pageEncoding、inform等属性指令值。以下将分别讲述这些属性的设置与作用。(1)contentType属性

   Tomcat服务器负责解释执行JSP页面,并将某些信息发送到用户的浏览器,以便用户浏览这些信息。Tomcat服务器同时负责通知用户的浏览器使用怎样的方法来处理所接收到的信息。这就要求JSP页面必须设置响应的MIME(Multipurpose Internet Mail Extention)类型,即设置contentType属性的值。contentType属性值确定JSP页面响应的MIME类型。(注:如果想深入了解MIME类型,可以在流行的搜索引擎中搜索MIME关键字)

   如果我们希望用户的浏览器启用HTML解析器来执行所接收到的信息(即所谓的网页形式),就可以如下设置contentType属性的值:

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

   如果希望用户的浏览器启用本地的MS-Word应用程序来解析执行收到的信息,就可以如下设置contentType属性的值:

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

   如果不使用page指令为contentType指定一个值,那么contentType属性的默认值是“text/html”。JSP页面使用page指令只能为contentType指定一个值,不允许两次使用page指令给contentType属性指定不同的属性值,下面的语法是错误的:

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

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

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

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

(2)pageEncoding属性

   pageEncoding属性的默认值是UTF-8.需要注意的是,和contentType的附加属性charset的值的意义不同,pageEncoding属性值是定义JSP页面使用的编码,即是告诉Tomcat服务器的解析器用怎样的编码解析JSP页面中的字符,比如当JSP页面指定的编码是UTF-8时:

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

   保存JSP页面应当将“编码”选择为“UTF-8”,原因是,Tomcat服务器根据JSP页面产生成JAVA文件时,Tomcat服务器的解析器是按照UTF-8编码来解析JSP页面中的字符数据(JSP页面本质上是一个XML文档)产生对应JAVA文件。如果保存JSP页面时,不小心将“编码”选择为其他编码,那么Tomcat服务器的解析器在产生对应的JAVA文件中的某些字符串就有可能出现乱码现象。

   另外,JSP页面使用page指令只能为pageEncoding指定一个值,不允许两次使用page指令给pageEncoding属性指定不同或相同的属性值。

(3)language属性

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

   为language属性指定值的格式是:

<%@page language = "java" %>

language属性的默认值是"java",即如果在JSP页面中没有使用page指令指定该属性的值,那么JSP页面默认有如上的page指令。

(4)import属性

   该属性的作用是为了JSp页面引入JAVA运行环境提供的包中的类,这样就可以在JSP页面的程序片部分、变量及方法定义部分以及表达式部分使用包中的类。可以为该属性指定多个值,该属性的值可以是某包中的所有类或一个具有的类,例如:

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

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

"java.lang.*" "javax.servlet.*" "javax.servlet.jsp.*" "javax.servlet.http.*"

当为import指定多个属性值时,比如:

<%@page import = "java.io.*"

<%@page import = "java.util.*"

(5)session属性

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

(6)buffer属性

   内置输出流对象out负责将服务器的某些信息或运行结果发送到用户端显示。buffer属性用来指定out设置的缓冲区的大小或不使用缓冲区。例如:

<%@page buffer = "24kb" %>

buffer属性的默认值是8kb。buffer属性可以取值“none”,即设置out不使用缓冲区。

(7)autoFlush属性

   autoFlush属性指定out的缓冲区被填满时,缓冲区是否自动更新。

   autoFlush可以取值true或false,属性的默认值是true。当autoFlush属性取值是false时,如果out的缓冲区填满,就会出现缓存溢出异常。当buffer的值是“none”时,autoFlush的值就不能设置成false。

(8)isThreadSafe属性

   isThreadSafe属性采用布尔值true或false,表示JSP页面在多线程环境中是否安全。默认值是true。

isThreadSafe的语法为:

<%@ page isThreadSafe =“true”%>

设置为true时,相同的JSP页面可以支持多个客户端。这是什么意思?为了更好地理解,我通过Servlet解释,因为JSP文件在内部转换为Servlet。当客户端请求JSP文件时,容器会加载JSP文件,将其转换为Servlet,然后编译然后执行。对于多个客户端的请求,容器也会创建相同Servlet的多个对象。对于每个Servlet对象,都会创建一个单独的service()方法。也就是说,每个客户端都有一个单独的service()方法。因此,Servlet和JSP是隐式线程安全的。

   若isThreadSafe =“true”,在多个客户端请求时为同一个JSP文件创建多个对象。每个客户端都有一个单独的_jspService()方法(只加载了一个JSP文件)。

   当isThreadSafe =“false”,允许容器为请求相同JSP的每个客户端创建一个Servlet对象。多个客户端将拥有容器创建的多个Servlet对象,以支持所有客户端。

这是使用SingleThreadModel接口在Servlet中实现的。

(9)info属性

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

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

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

getServletInfo( );

   获取info属性的属性值。(注:当JSP页面被转译成JAVA文件时,转译成的类是Servlet的一个子类,所以在JSP页面中可以使用Servlet类的方法:getServletInfo( ) )


  • 2.6.2   include指令标记

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

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

   include指令标记的作用是在JSP页面出现该指令的位置处,静态嵌入一个文件,该文件的编码必须和当前JSP页面一致。被嵌入的文件必须是可以访问或可以使用的。如果该文件和当前JSP页面在同一Web服务目录中,那么“文件的URL”就是文件的名字,如果该文件在JSP页面所在的Web服务目录的一个子目录中,比如fileDir子目录中,那么文件的URL就是”fileDir/文件的名字“。所谓静态嵌入,就是当前JSP页面和嵌入的文件合并成一个新的JSP页面,然后Tomcat服务器再将这个新的JSP页面转译成JAVA文件。因此嵌入文件后,必须保证新合并成的JSP页面符合JSP语法规则,即能够成为一个JSP页面文件。比如,被嵌入的文件是一个JSP页面,该JSP页面使用page指令为contentType属性设置了值:

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

   那么,合并后的JSP页面就两次使用page指令为contentType属性设置了不同的属性值,导致出现语法错误。因为JSP页面中的page指令只能为contentType指定一个值。

<%@page contentType ="text/html "%>
<%@page pageEncoding ="utf-8 "%>
<%@include file = "myfile/ok.txt" %>
<html><center><body background = "image/beida.jpg">
<bgsound src = "sound/beida.mp3" loop = 1>
<h1>这里是北京大学</h1>
</body></html>
<%@page contentType ="text/html "%>
<%@page pageEncoding ="utf-8 "%>
<%@include file = "myfile/ok.txt" %>
<html><center><body background = "image/beida.jpg">
<bgsound src = "sound/beida.mp3" loop = 1>
<h1>这里是清华大学</h1>
</body></html>
<%@page contentType ="text/html "%>
<center>
<A herf = "example2_10_a.jsp">北京大学</A>
<A herf = "example2_10_b.jsp">清华大学</A>
</body></html>

2.7   JSP动作标记

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

  • 2.7.1   include动作标记

   include动作标记语法格式为:

  <jsp : include page = "文件的URL"/>

  <jsp : include page = "文件的URL"/>

   param子标记

  </jsp:include>

(注:当include动作标记不需要param子标记时,必须使用第一种形式)

   include动作标记告诉JSP页面动态包含一个文件,即JSP页面运行时才将文件加入。与静态嵌入文件的include指令标记不同,当Tomcat服务器根绝JSP页面产生成JAVA文件时,不把JSP页面中动作指令include所包含的文件与原JSP页面合并为一个新的JSP页面,而是告诉JAVA解释器,这个文件在JSP运行时才包含进来。

   尽管include动作标记和include指令标记的作用都是处理所需要的文件,但是处理方式和处理事件是不同的。include指令标记是在编译阶段就处理所需要的文件,被处理的文件在逻辑和语法上依赖于当前的JSP页面,其优点是页面的执行速度快;而include动作标记实在JSP页面运行时才处理文件,被处理的文件在逻辑和语法上独立于当前JSP页面,其优点是可以使用param子标记更灵活的处理所需要的文件,缺点是执行速度相对慢一些。(注:书写include动作标记<jsp:include page.../>时要注意:“jsp”“:”“include”三者之间不要有空格)   

  • 2.7.2   param动作标记

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

   param动作标记语法格式是:

<jsp:param name = "参数" value = "参数的值"/>

当该标记与jsp:include动作标记一起使用时,可以将poaram标记中参数的值传递到include动作标记要加载的文件中去,被加载的JSP文件可以使用Tomcat服务器提供的request内置对象获取include动作标记的param子标记中name给出的参数的值。因此include动作标记通过使用param子标记来处理加载的文件,比include指令标记更为灵活。

e74535b8603141f1a126fd7f53b3cab0.png

  • 2.7.3   forward动作标记

   forward动作标记的语法格式是:

<jsp:forward page = "要专项的页面"/>

<jsp:forward page = "要专项的页面"/>

   param子标记

</jsp:forward>

   该指令的作用是:从该指令处停止当前页面的执行,而转向执行page属性指定的JSP页面。需要注意的是,当forward动作标记不需要param子标记时,必须使用第一种形式。

   forward标记可以使用param动作标记作为子标记,而转向的页面传送信息。forward动作标记指定的要转向的JSP文件可以使用Tomcat服务器提供的request内置对象获取param子标记中name指定的属性值。

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

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>forward Action Signal</title>
</head>
<body>
<h1> Create a random number from 1 to 10:
    <% double i = (int)(Math.random()*10)+1;
    if(i<5){
        %>
    <jsp:forward page="example2_12_a.jsp">
    <jsp:param name="number" value = "<%=i%>"/>
    </jsp:forward>
<% }
    else
    { %>
    <jsp:forward page="example2_12_b.jsp">
    <jsp:param name = "number" value = "<%=i%>"/>
    </jsp:forward>
    <%
        }%>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Sign A</title>
</head>
<body bgcolor="#dc143c">
<p style="font-family: 'Lucida Sans Unicode';font-size: medium">
    <%
        String s = request.getParameter("number");
        out.print("The random number is : "+s);
    %>
    <br>
    <img style="font-size: small" src="image/CXK.png" width="150" height="400"/>
</p>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Sign B</title>
</head>
<body bgcolor="#00ffff">
<p style="font-family: 'Lucida Sans Unicode';font-size: medium">
  <%
    String s = request.getParameter("number");
    out.print("The random number is : "+s);
  %>
  <br>
  <img style="font-size: small" src="image/xianbei.png"/>
</p>
</body>
</html>

   输出结果如下图:

f85b5126faa049eda7c6e014614d6dd3.png

 295ca639888f4de0a93e823e181c8129.png

   经过刷新可以更新随机数的结果来调用相应的img文件。


  • 2.7.4   useBean动作标记

   useBean标记用来创建并使用一个JavaBean,是非常重要的一个动作标记。JavaBean负责存储数据,JSP页面显示JavaBean中的数据,而servlet负责管理JavaBean中的数据。

   <jsp:useBean id="bean的名称" class="bean的权限定类名"

<jsp:usebean id = "bean的名字" class = "创建bean的类" scope = "bean的有效范围"/>

   或

<jsp:usebean id = "bean的名字" class = "创建bean的类" scope = "bean的有效范围"/>

</jsp:usebean>

例如: 

<jsp:usebean id = "circle" class = "tom.jiafei.Cirlce" scope = "page"/>

需要注意,其中的“创建bean的类”腰带有包名,例如:

class = "tom.jiafei.Circle"

    scope="page/request/session/context" />。这个标记首先会在是定的作用域中查找对象,如果存在,就直接拿来。如果不存在,就重新创建一个对象。这里面的scope是这个Bean的作用域。           page表示只在本页面有效,request表示这个bean是request属性,session表示这个bean是session属性context。
   <jsp:setProperty name="bean的名称" property="属性名称" value="属性值" />就是向bean设置属性。当表单的名称和bean的属性名称相同时可以简写成这样:<jsp:setProperty name="bean的名称" property="*"  />这会大大降低代码的编写量。
   <jsp:getProperty name="bean的名称" property="属性名称">这个标记是把bean的属性打印出来。具体代码如下图:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<style>
    #textStyle{
        font-family: 宋体;font-size: 36px;color: black;
    }
</style>
<html>
<head>
    <title>example5_1</title>
</head>
<body bgcolor="white">
<p id="textStyle">
    <jsp:useBean id="circle" class="tom.jiafei.Circle" scope="page"/>
    <%--通过useBean标记,获得名字是circle的page bean--%>
    圆的初始半径是:<%=circle.getRadius()%>
    <%
    double newRadius = 100;
    circle.setRadius(newRadius);  //修改半径
    %>
    <br>修改半径为:<%=newRadius%><br>
    <b>圆的半径是:<%=circle.getRadius()%>
        <br><b>圆的周长是:<%=circle.circleLength()%>
            <br><b>圆的面积是:<%=circle.circleArea()%>
</p>
</body>
</html>
package tom.jiafei;
public class Circle {
    double radius;
    public Circle(){
        radius = 1;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }
    public double circleArea(){
        return Math.PI*radius*radius;
    }
    public double circleLength(){
        return 2.0*Math.PI*radius;
    }
}

   (注:为了让Tomcat服务器能找到字节码文件,class文件应保存在特定的目录中)


总结

JSP语法是Web设计中的基础,本章难点在于JAVA程序片与JSP动作标记

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值