JSP初入门
- <% JAVA 代码 %>:scriptlet,可以直接运行 Java 代码。
- <%@ page import=“全限定包名,全限定包名” %>:page指令,导包指令,导入不止一个包需要使用逗号分隔。
- <%= JAVA 代码 %>:直接将java代码执行结果打印到页面中。
上面第一个<% %>包裹的是 scriptlet,第二个是多了一个 @ 的是指令,第三个多个 = 的是表达式。
注意:
表达式是打印语句,隐式的调用了 out.print() 方法,表达式中的值会自动加入到 out.print() 的括号中成为打印的值。所有表达式不需要添加结尾分号,否则是无法编译。还有表达式必须是有返回值,否则会报错。
<% count = 0; %>
JSP 中可以在 scriptlet 可以直接声明变量,上面代码中声明了一个 count 变了,但是注意,这样声明的变量是局部变量,每次服务器运行这个 JSP 时,这个 count 就会初始化。
<%! int count = 0; %>
上面代码,在第一个百分号后面添加了一个感叹号,这种 JSP 元素标签,被称为声明。被这种声明所标记的内容都会增加到类中,而且置于服务方法之外。这便意味着我们可以在 JSP 中声明静态变量和方法,还可以声明实例变量和方法。
容器如何处理 JSP
对于普通的 JSP,容器在初始化时,会将其转换成一个特殊的 HttpServlet 子类,使用成为容器中的一个普通的 Servlet对象,步骤如下:
- 查看指令,得到转换时可能需要的信息。
- 创建一个 HttpServlet 子类。
- 如果一个 page 指令有 import 属性,它会在类文件的最上面写入 import 属性。
- 如果有声明,容器将这些声明写到类文件中,通常放在类声明下面,并在服务方法签名。
- 建立服务方法。服务方法的具体方法名是 _jspServlet()。所生成的 servlet 会覆盖 servlet 父类的 service() 方法,_jspService() 就由覆盖的 service() 方法调用,要接收 HttpServletRequest 和 HttpServletRequest 参数。建立中国方法时,容器会声明并初始化所有的隐式对象。
- 将普通的 Html、scriptlet 和表达式放到服务方法中,完成格式化,并写至 PrintWriter 响应输出。
各种指令
- <%@ page import="" session=""%>:定义页面特有的属性,如字符编码、页面响应的内容类型,以及这个页面是否要有隐式的会话对象。page 指令可以使用至多 13 个不同的属性。
- <%@ taglib tagdir="/WEB-INF/tags/cool" prefix=“cool”%>:定义 jsp 可以使用的标记库。
- <%@ include file=“wickedHeader.html”%>:定义在转换时增加到当前页面的文本和代码。这样可以建立可以重用的块,这些可以重用的块能增加到各个页面上。
page 的指令:
- import:定义 java 的 improt 语句,所定义的 import 语句会增加到生成 servlet 类中。
- isThreadSafe:定义生成的 servlet 是否需要实现 SingleThreadModel,默认值是 true,不通常不设置为 false。
- contentType:定义 jsp 响应的 MIME 类型(和可选的字符编码)。
- isELIgnored:定义转换这个页面时是否忽略 EL 表达式。
- isErrorPage:定义当前页面是否是另一个 jsp 的错误页面。默认值是 false,但是如果这个属性值为 true,页面就能访问隐式的 exception 对象。属性为 false ,自然就不能访问错误对象了。
- errorPage:定义一个自由的 URL ,如果有未捕获到的 Throwable,就会发送到这个资源。如果这里指定了一个 jsp,该 jsp 的 page 指令中就会有 isErrorPage=“true” 属性。
- language:定义 scriptlet、表达式和声明中使用的脚步语言。可取值只有一个,就是“java”。
- extends:jsp会变成一个 servlet 类,这属性定义了此类会以哪个类作为超类。
- session:定义页面是否有一个隐式的 session 对象。默认值为“true”。
- buffer:定义隐式 out 对象(JspWriter的引用)如何处理缓存。
- autoFlush:定义缓存的输出是否自动刷新输出,默认值为“true”。
- info:定义放到转换后页面的串,这样就可以使用所生成 servlet 继承的 getServletInfo() 方法来得到这些信息。
- pageEncoding:定义 Jsp 的字符编码。默认为“ISO-8859-1”。
EL表达式
Emeil:${getServletContext.getInitParameter("Emeil")}
上面的就是 EL 表达式,上面的代码运行后与 <%=getServletContext.getInitParameter(“Emeil”) %> 一致。
JSP 禁用脚步元素(scriptlet、Java表达式或者声明)
在 web.xml中设置:
<web-app>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scription-invalid>
true
</scription-invalid>
</jsp-property-group>
</jsp-config>
</web-app>
JSP 禁用 EL
在 web.xml中设置:
<web-app>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>
true
</el-ignored>
</jsp-property-group>
</jsp-config>
</web-app>
在 JSP 中设置:
<%@ page isELIgnored="true"%>
动作
JSP 页面里,模型中返回的是一个普通的 JavaBean 对象,如果要拿这个对象中 name 属性,使用脚本的方式是:
<html>
<body>
<% person p = (person) request.getAttribute("person");%>
Person is:<%= p.getName%>
</body>
</html>
使用标准动作的方式是:
<html>
<body>
<jsp:useBean id="person" class="包名.Person" scope="request"/>
Person is:<jsp:getProperty name="person" property="name"/>
</body>
</html>
上面标准动作的含义:
- jsp:useBean:标识标准动作
- id:声明 bean 对象的标识符。名字与 servlet 中 request.setAttribute(“person”,p); 中设置的 key 一致。
- class:声明 bean 对象的类类型,全限定类名。
- scope:标识这个对象的属性作用域
- jsp:getProperty:标识标准动作。
- name:标识具体的bean 对象。与 useBean 中标记的 id 值匹配。
- property:标识属性中的标识符,对象的属性
注意:
jsp:useBean 这个标记,会在标识的属性作用域下寻找对应的对象。如果找不到,它会找这个标识类,自己创建一个类实例,并把这个实例对象赋值给 id 对象,如何设置指定的作用域。
jsp:getProperty 标准动作是获取普通的 JavaBean 的属性值。既然可以获取值,那么也可以给对象设置值:
<jsp:setProperty name="person" property="name" value="Fred"/>
value 属性便可以给该实例对象的属性赋值。
还有一种设置方式:
<jsp:useBean id="person" class="包名.Person" scope="request">
<jsp:setProperty name="person" property="name" value="Fred"/>
</jsp:useBean>
将设置值的标签定义在 jsp:useBean 的体中,这种方式在定义时,会给新建立的实例属性赋值。如果可以作用域中可以找到设置的实例,这个标签内容不会执行。但是如果作用域中未找到设置的实例,useBean 开始重新建立实例时,这段便会执行,相对于给属性值赋一个默认的值。
jsp:include 标准动作,用于将另一个页面插入到当前位置:
<jsp:include page="Header.jsp"/>
上面的代码会将名字为 header.jsp 的文件的响应插入到当前页面的放置了上方代码的位置中。
jsp:forward 标准动作,将这个 jsp 页面的请求转发到另一个页面。
<jsp:forward page="Header.jsp"/>
将请求转发给 header.jsp 页面。