现在的位置: 首页 > 综合 > 正文

JSP基本语法

2018年01月25日 ⁄ 综合 ⁄ 共 9473字 ⁄ 字号 评论关闭
一、两种注释,<!--comment--!>会输出浏览器里,可以加表达式进行值的计算和<%--comment--%>,不会输出到浏览器里。
二、指令元素,用来给编译器解释jsp用的。
page指令:<%@ page 属性1="" 属性2="" ....%> 。
<%@ page %>指令可以放到页面的任何位置,作用于整个JSP页面,同样包括静态的包含文件,比如<%@ include %>。但是<% @ page %>指令不能作用于动态的包含文件,比如      <jsp:include>
1、language,表示编译该jsp页面所使用的语言,属性默认为java,也只能是java;
2、import,表示引入该jsp页面的类,和java语言中的import指令一样作用,可以该属性可以有多个值,用逗号分开,或者分别写在不用的import里。
<%@ page import="java.io.*,java.util.*,javax.servlet.*" %>
或者<%@ page import = "java.io.*" %>
<%@ page import="java.util.*" %>
3.contentType,表示该jsp页面生成的html页面的字符编码格式,和页面相应的MIME类型,因此contentType包含两部分,type和charset,type用来指定MIME,charset用来指定字符编码的格式。< %@ page contentType=" text/html; charset=UTF-8" %>
4.session,表示该页面是否使用session对象,一个常见的误解是以为session在有客户端访问时就被创建,然而事实是直到某server端程序调用HttpServletRequest.getSession(true)这样的语句时才被创建,注意如果JSP没有显示的使用 <%@page session="false"%> 关闭session,则JSP文件在编译成Servlet时将会自动加上这样一条语句HttpSession
session = HttpServletRequest.getSession(true);这也是JSP中隐含的session对象的来历。由于session会消耗内 存资源,因此,如果不打算使用session,应该在所有的JSP中关闭它。
对于那些无需跟踪会话状态的页面,关闭自动创建的会话可以节省一些资源。使用如下page指令:<%@ page session="false"%>
5. buffer属性用来指定输出流JSPWriter的缓冲区大小,指定到客户端的输出流的缓冲模式,指定到客户端的输出流的缓冲模式。
buffer的取值可以为none、8KB或者指定大小的KB值。如果为none,则不缓冲,如果是用户指定大小,则采用不小于该值的缓冲区进行缓存,用户自行设置时,至少应该为8KB。buffer的默认值与服务器有关,大多数服务器上其默认的值通常为8KB,其他的服务器上也不会少于8KB。
6、autoflash,注意不是autoflush。表示缓冲区已满,是否刷新缓冲区。默认为true,我们不应该修改这个值。因为如果为false,缓冲区满了之后,会出现异常。
7、isThreadSafe用来指定当前jsp页面的Servlet是否支持多线程的访问,默认为true。
8、info,通过一个字符串来定义当前页面的相关信息,通常为针对该jsp页面的一些附加性的说明性文字,info的值,可以通过servlet.getServletInfo()的方法获得。
9、errorPage指定该页面如果发生异常,需要跳转的页面。通常errorPage 的默认值是忽略的,但是一旦指定了errorPage的值,那么该jsp发生异常之后,都将跳转到该页面,而在web.xml文件中定义的任何错误处理页面都不会被调用。
10、isErrorPage 与 errorPage对应,用来指定该jsp页面是否是其他jsp页面的错误处理页面。默认为false,不能使用九大内置对象中的Exception对象。
11、extends用来指定该jsp页面转换成的servlet,继承哪个父类,属性值必须是完整的限定类名,并且必须是javax.servlet.jsp.HttpJspPage的子类。通常不建议使用该属性,jsp会自动提供转换后的servlet的父类,默认的父类是HttpJspBase类。
12、pageEncoding,说明了该jsp页面的编码格式,服务器按照这个编码来读取jsp。
13、isELignore 如果设定为真,那么JSP中的表达式被当成字符串处理。
include指令
include指令用来在使用该指令的地方静态的引用其他文件的内容,把引用文件的代码和当前jsp页面的代码组合在一起,组成一个新的源代码文件。
<%@ include file="引用文件的路径" %>
通常路径都为相对路径,无须指定端口、协议、域名等内容,这有利于文件的可移植性。
include指令在页面恰当的位置使用,而不仅仅是放到开头。
taglib
taglib 指令通过定义一个标记库和自定义标签的前缀,来允许用户使用自定义标签。对于自定义标签的定义,必须放在使用自定义标签的前面,以保证在编译时先知道这个自定义标签的存在。
<%@ taglib uri="taglibURI" prefix="tagprefix"
其中uri为标签的描述符,即如何找到标签描述的文件和标签库。
prefix为使用该标签用到的前缀名。uri属性会根据自定义标签的前缀名对自定义标签进行唯一的命名操作。注意:prefix有些保留字,不能使用。包括:jsp、jspx、java、javax、servlet、sun和sunw。
在jsp2.0版本规范中,添加了jstl标签库。
三、脚本元素
脚本元素包括声明、表达式和脚本程序。
1、表达式元素:表示的是一个正在脚本语言中被定义的表达式,在运行后自动转换为字符串,然后插入到这个表达式在jsp文件中的位置。
<%= expression %>
有时候表达式也能作为其他jsp元素的属性值。一个表达式可以很复杂,它可能由一个或多个表达式组成,这些表达式的顺序是从左到右进行计算的。
2、脚本程序scriptlet
虽然表达式能够在页面中嵌入java代码,但是如果要通过表达式嵌入大量的java代码进行编程,既麻烦又不合理,而scriptlet能够包含一段完整有效的程序片段。
<% code fragment %>
一个scriptlet能够包含多个java语句,包括方法、变量等内容。scriptlet提供的功能如下:
a、声明要用到的变量或方法。
b、编写JSP表达式
c、使用任何隐藏的对象和任何用<jsp:userBean>声明过的对象。
d、编写java程序语句
由于scriptlet中包含的是java程序片段,所以其他任何文本、html标记、jsp元素都必须在scriptlet之外。
3、声明
<%! declaration; [declaration;] + ... %>
<%! 
Date date = new Date();
Date getDate(){
     System.out.println("xxxxxxxxxxx");
     return date();
}
%>
now, time is <%= getDate() %>!
多次访问页面,时间不变。
这样我能就能在scriptlet和表达式中使用这些变量和方法了。可以一次声明多个变量和方法。只要以“;”结尾就可以了。
声明和scriptlet的区别是,声明里的变量只会初始化一次,而scriptlet里的变量执行赋值,从jsp转换成的servlet看,声明将 变量 作为servlet 的成员变量,在初始化的时候被赋值,而scriptlet将变量作为serlvet的方法的局部变量,多次赋值。
一个声明仅仅在一个jsp页面中有效,如果有多个页面都需要用到同样的声明,可以将他们写成一个单独的jsp文件,然后用<%@ include %>或<jsp:include>元素包含进来,实现代码的复用。
四、动作元素
jsp动作元素页面请求的处理阶段才起作用。
jsp动作元素包括自定义动作元素和标准动作元素,jsp在其规范中定义了很多标准动作元素,这些动作元素均以“jsp”作为前缀。
jsp动作元素的两种通用格式如下:
a、<前缀:标签名 属性1="value" 属性2="value" .../>
b、<前缀:标签名 属性1="value" 属性2="value" ...>
     </前缀:标签名>

1、param动作
<jsp:param>动作是用来追加参数的标记,提供了以"key"-"value"的方式向其他页面传递参数的功能。通常与<jsp:include>和<jsp:forward>等动作标签一起进行使用,向需要包含的动态页面或将要转向的页面提供参数信息。
<jsp:param name="parameterName" value="parameterValue">
value的数据类型可以为多种基本数据类型,但是request.getParameter()方法只能返回String类型的值。
<jsp:forward page="getParam.jsp">
     <jsp:param name="paramName" value="<%=str%>" />
</jsp:forward>
getParam.jsp里:
<% String param = request.getParameter("paramName");%>
2、include动作 
<jsp:include page="filepath" flush="true">
page表示引用的文件的路径,一般使用相对路径,flush必须为true,默认也为true。
<jsp:include>动作通常与<jsp:param>动作一起使用,但是只有当<jsp:include>引入的是动态文件时,才需要通过<jsp:param>动作传递参数。
<@include>和<jsp:include>的区别:参见<%@include%>和<jsp:include>的区别
另外在两种用法中file和page属性都被解释为一个相对的URI.如果它以斜杠开头,那么它就是一个环境相关的路径.将根据赋给应用程序的URI的前缀进行解释,如果它不是以斜杠开头,那么就是页面相关的路径,就根据引入这个文件的页面所在的路径进行解释
3、forward动作
<jsp:forward page="filepath" />
其中page属性用来定义将要跳转的页面的相对路径,和include 的相对路径用法一致。
forward动作可以和param动作一起使用。
<jsp:forward page="filepath">
<jsp:param name="paramName" value="paramValue" />
</jsp:forward>
4、useBean动作
useBean动作用来在jsp页面中创建并使用一个JavaBean,同时制定它的名字和作用范围,保证JavaBean在标签制定的范围内可用。
<jsp:useBean>动作常用的两种方式如下:
第一种方式:
<jsp:useBean id="ID" scope="scopeValue" 其他可选属性/>
第二种方式:
<jsp:useBean id="ID" scope="scopeValue" 可选属性>
<jsp:setProperty name="beanName" property="propertyName"/>
<jsp:setProperty name="beanName" property="propertyName" value="propertyValue"/>
<jsp:setProperty
name="beanName" property="propertyName" param="paramName"/>

</jsp:useBean>
第二种方式使用了<jsp:setProperty>动作,用于设置JavaBean的属性值。
scope的默认值为page,其他可选取值为request、session、application。
在scope范围内通过bean的id属性来获取,比如:
<jsp:useBean>动作中,其他的可选属性有以下四种方式:
A: class="className"
B: class="className" type="typeName"
C: beanName="beanName" type="typeName"
D: type="typeName"
首先说明一点,必选属性只有两点,id和scope,但是只有这两点会报jsp.error.usebean.missingType错误。
下面说明几个可选属性的意义:
在这之前说明一下,useBean的方式都是先从scope中根据id去取对象,如果没有对象再进行处理。
其中:A方式是:从scope中取不到id,就自己通过JavaBean的构造方法来new一个对象,放到scope里。
A方式要求:class是表示使用的JavaBean的路径和类名,该JavaBean不能是抽象类或接口,而且必须有公有的、无参的构造函数。
<jsp:useBean id="user" class="com.jeaw.entity.User" scope="request">
示例代码:
com.jeaw.entity.User user = null;
      synchronized (request) {
        user = (com.jeaw.entity.User) _jspx_page_context.getAttribute("user", PageContext.REQUEST_SCOPE);
        if (user == null){
          user = new com.jeaw.entity.User();
          _jspx_page_context.setAttribute("user", user, PageContext.REQUEST_SCOPE);
        }
      }
A方式可以认为有个默认的type,即为class。
B方式也是使用class的构造方法来new一个对象,而type用来指定声明变量的类型。
<jsp:useBean id="user" class="com.jeaw.entity.User" type="Object" scope="request">
示例代码:
Object user = null;
      synchronized (request) {
        user = (Object) _jspx_page_context.getAttribute("user", PageContext.REQUEST_SCOPE);
        if (user == null){
          user = new com.jeaw.entity.User();
          _jspx_page_context.setAttribute("user", user, PageContext.REQUEST_SCOPE);
        }
      }
C方式是:从scope中取不到id,就通过instantiate方式,实例化一个JavaBean对象。该方式要求必须有type。type的作用是指定实例化对象的类型。
使用java.beans.Beans.instantiate方法实例化beanName属性指定的类或序列化模板对应的Bean对象,赋予JavaBean对象type属性指定的数据类型。Beans.instantiate方法会检查beanName属性指定的名称是类名称还是序列化模板的名称。假如该JavaBean对象已被序列化,则Beans.instantiate使用类加载器读取序列化的内容,更多信息可参考JavaBeans.
<jsp:useBean id="user1" beanName="com.jeaw.entity.User" type="Object" scope="request"/>
示例代码:
Object user1 = null;
      synchronized (request) {
        user1 = (Object) _jspx_page_context.getAttribute("user1", PageContext.REQUEST_SCOPE);
        if (user1 == null){
          try {
            user1 = (Object) java.beans.Beans.instantiate(this.getClass().getClassLoader(), "com.jeaw.entity.User");
          } catch (ClassNotFoundException exc) {
            throw new InstantiationException(exc.getMessage());
          } catch (Exception exc) {
            throw new ServletException("Cannot create bean of class " + "com.jeaw.entity.User", exc);
          }
          _jspx_page_context.setAttribute("user1", user1, PageContext.REQUEST_SCOPE);
        }
      }
D方式是:直接从scope中根据id去取对象,如果没找到直接报错。
<jsp:useBean id="role" type="com.jeaw.entity.Role"
scope="request"/>
示例代码:
com.jeaw.entity.Role role = null;
      synchronized (request) {
        role = (com.jeaw.entity.Role) _jspx_page_context.getAttribute("role", PageContext.REQUEST_SCOPE);
        if (role == null){
          throw new java.lang.InstantiationException("bean role not found within scope");
        }
      }

稍微总结一下:<jsp:useBean>总会先从scope中去取对象,如果不存在有三种处理:第一种A/B通过类的构造方法实例化对象(需要指定class),第二种通过instantiate方式实例化对象(需要指定beanName和type),第三种方式直接报错(需要指定type)。第一种方式和第二种方式互斥,class和beanName不能同时存在。type用来指定声明变量的类型,在A/B方式中,type可有可无,在C方式中type必须指定,D方式只有一个type。
5、setProperty动作
<jsp:setProperty name="beanName" propertyDetails/>
setProperty动作用来设置beanName的简单属性和索引属性,与<jsp:useBean>动作一起使用。实际上<jsp:setProperty>动作是通过调用JavaBean中相应的set方法为一个或多个属性进行赋值。
其中name属性为必选属性,用来表示使用的JavaBean的名称,其值与<jsp:useBean>动作中的id属性值相同。
propertyDetails有一下4种方式:
A:property="*"
B:property="propertyName" value="propertyValue"
C:property="propertyName" param="paramName"
D:property="propertyName"
其中,
A:property="*"是最便捷的设置JavaBean属性的方式,当然,这要求从request中获取的参数名和JavaBean中的属性一一对应。
当使用property="propertyName"时,则根据request对象的一个参数来为JavaBean中的一个指定属稍微性进行赋值操作。由于表单中传过来的数据类型都是String 类型的,Jsp内在机制会把这些参数转化成Bean属性对应的类型。(各种类型的参数的测试未做?
B:使用value值来给propertyName赋值
C:使用request的参数paramName来给propertyName赋值
D:使用request中和propertyName同名的参数来给propertyName赋值

稍微总结一下:A方式是给所有的属性赋值。B/C/D给一个属性赋值,如果参数名和属性名同名,用D,不同名,用C,用具体的值,用B。
另外,需要注意一点的是,<jsp:useBean>和<jsp:setProperty>配合使用有两种方式:
<jsp:useBean>
<jsp:setProperty/>
</jsp:useBean>
或者
<jsp:useBean/>
<jsp:setProperty/>
二者区别在于<jsp:setProperty>是否位于<jsp:useBean>里面,如果在里面,那么,如果bean已经存在了,那么<jsp:setProperty>不会被执行。所以,如果想要<jsp:setProperty>总是执行,那么就不能把<jsp:setProperty>放到<jsp:useBean>里面。
6、getProperty动作
<jsp:getProperty name="beanName" property="propertyName"/>
<jsp:getProperty/>动作与<jsp:setProperty/>动作相对应,用来获取一个JavaBean的各属性值。在使用<jsp:getProperty/>动作之前,要求必须使用<jsp:useBean/>动作创建一个JavaBean的对象。这里的限制是必须的,即使把<jsp:useBean/>动作翻译成的代码用scriptlet替代,然后使用<jsp:getProperty/>动作,还是会报错。

Name was not previously introduced as per JSP.5.3
当JavaBean中的属性为基本数据类型时,<jsp:getProperty/>动作会将其转化为String类型的值。如果JavaBean中的属性为类类型,那么<jsp:getProperty/>动作将调用其toString()方法。在<jsp:getProperty/>动作将JavaBean中的属性转换为String值之后,再将其发送至输出流,交由客户端浏览器进行显示。
7、plugin动作
plugin动作用来在jsp页面加载Java小程序,并在客户端浏览器产生特殊标签,例如<object>和<embed>标签。
当Jsp页面被编译并将结果返回给客户端浏览器时,<jsp:plugin>动作将根据客户端浏览器的版本,被替换成<object>或<embed>标签。
。。。。。暂时不考虑这个动作,以及接下来的fallback动作。

抱歉!评论已关闭.