09_作为 JSP

每篇一句:观察的本质是:不赞美,不责难,甚至也不惋惜,但求了解认识而已。  ——《看见》

JSP 概述

看一下维基百科的定义:

JSP(全称JavaServer Pages)是由Sun Microsystems公司主导创建的一种动态网页技术标准。JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTML、XML或其他格式文档的Web网页,然后返回给请求者。

JSP 最终会变成一个完整的 servlet 在 Web 应用中运行。首先,容器拿到在 JSP 中写的代码,把这些代码转换为一个 servlet 类源文件 ( .java ),然后在把这个源文件编译为 Java servlet 类。然后和 servlet 运行一样了。

在 JSP 中可以使用 scriptlet 放入常规的 Java 代码。所谓 scriptlet 就是 放在 <% ··· %> 标记中的 Java 代码。例如:

<% out.println(foo.Counter.getCount()); %>

在 JSP 中使用 Java,要么导入包,要么在代码中使用完全限定名。

指令

指令有 3 种:page. include. taglib。

page 指令

定义页面特定的属性,如字符编码,页面响应的内容类型,以及这个页面是否有隐式的会话对象

导入单个包


<%@ page import="foo.*" %>
<html><body>
The page count is:
<%
    
    out.println(Counter.getCount());
%>
body>html>

导入多个包

使用逗号来分隔多个包。

<%@ page import="foo.*, java.util.*" %>

page 指令的属性

属性 作用
import 定义 Java,所定义的 import 语句会增加到生成的 servlet 类中
isThreadSafe 定义生成的 servlet 是否需要实现 SingleThreadModel。默认值为 “true”,表示不需要实现 SingleThreadModel
contentType 定义 JSP 响应的 MIME 内容
isELIgnored 定义转换这个页面时是否忽略 EL 表达式
isErrorPage 定义当期页面是否是另一个 JSP 的错误页面。默认是 “false”
errorPage 定义一个资源的 URL,如果有未捕获的 Throwable,就会发送到这个资源

taglib 指令

定义 JSP 可以使用的标记库

<%@ taglib tagdir="/WEB-INF/tags/cool" prefix="cool" %>

include 指令

定义在转换时增加到当前页面的文本和代码,以建立可重用的块

<%@ include file="wickedHeader.html" %>

表达式

表达式元素会自动打印放在标记之间的内容

<%= Counter.getCount() %>

表达式会成为 out.print() 的参数。也就是说,容器拿到 <%=%> 之间的所有内容,把它作为参数传递给打印语句,打印到隐式响应 PrinWriter out。如上式会转换为

out.println(Counter.getCount());

注意:不要把一个返回类型为 void 的方法用作表达式

声明

JSP 转换为 servlet 代码时,所有 scriptlet 和表达式代码都放在服务方法中。所以 scriptlet 中声明的变量都是局部变量

声明的 JSP 元素

<@! int count = 0; %>

JSP 声明用于声明所生成 servlet 类的成员,包括变量和方法。而 <%!%> 标记之间的 所有内容都会增加到类中,且置于服务方法之外

例如,这个 JSP

<html><body>
<%! int doubleCount(){
        count = count * 2;
        return count;
    }
%>
<%! int count = 0; %>
The page count is now:
<%= doubleCount() %>
body>html>

会转换为这个 servlet

public class basicCounter_jsp extends SomeSepecialHttpServlet{
    int doubleCount(){
        count = count * 2;
        return count;
    }
    int count = 0; 
    public void _jspService(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException{
            PrintWriter out = response.getWriter();
            response.setContentType("text/html");
            response.write("");
            response.write("The page count is now:");
            response.print( doubleCount() );
            response.write("");
        }
}

隐式对象

容器把 JSP 转换为 servlet 时,服务方法最前面会有一些隐式对象声明和赋值。所有的隐式对象都会映射到 Servlet/JSP 中的某个东西。

API 隐式对象
JspWriter out
HttpServletRequest request
HttpServletResponse response
HttpSession session
ServletContext application
Throwable exception
PageContext pageContext
Object page

其中 PageContext 封装了其他隐式对象,可以使用提供的 PageContext 的引用得到其他隐式对象的引用以及所有作用域的属性

注释

在 JSP 中可以有两种不同的注释:

容器把它直接传递给客户,在客户端,浏览器会把它解释为注释

  • <%-- JSP 注释 -->

JSP 注释会在转换页面时将其去掉

生成 Servlet 的 API

容器根据 JSP 生成的类会实现 HttpJspPage 接口。其中三个关键方法:
- jspInit()

这个方法由 init() 方法调用,可以覆盖

  • jspDestroy()

这个方法由 servlet 的 destroy() 方法调用,也可以覆盖

  • _jspService()

这个方法由 servlet 的 service() 方法调用,不过不能覆盖

JSP 的生命周期

JSP 完整的生命周期如下:

  1. 首先容器会读取应用的 web.xml,但对 .jsp 文件不做任何处理
  2. 当用户点击链接请求这个 .jsp 时,容器将 .jsp 转换为一个 servlet 类的 .java 源代码
  3. 然后把这个 servlet .java 源文件编译为一个 .class 文件
  4. 容器会加载新的 servlet 类
  5. 容器实例化 servlet,并调用 servlet 的 jspInit() 方法,成为一个 servlet
  6. 容器创建一个新线程来处理这个客户的请求,servlet 的 _jspService() 方法会运行

在整个生命周期中,转换和编译步骤只发生了一次。一旦servlet 得到加载和初始化,请求时只会创建或分配一个线程来运行服务方法

初始化 JSP

配置 servlet 初始化参数

与为 servlet 配置初始化参数基本一样,只是在 标记中增加一个 元素

<web-app ···>
    <servlet>
        <servlet-name>MyTestInitservlet-name>
        <jsp-file>/TestInit.jspjsp-file>
        <init-param>
            <param-name>emailparam-name>
            <param-value>[email protected]param-value>
        init-param>
    servlet>
    <servlet-mapping>
        <servlet-name>MyTestInitservlet-name>
        <url-pattern>/TestInit.jspurl-pattern>
    servlet-mapping>
web-app>

覆盖 jspInit() 方法

jspInit() 方法由 servlet 的 init() 方法调用,在 JSP 页面成为 servlet 的最开始,容器会调用它。所以在 jspInit() 方法中调用 getServletConfig() 和 getServletContext()。

<%!
    public void jspInit(){
        ServletConfig sConfig = getServletConfig();
        String emailAddr = sConfig.getInitParameter("email");
        ServletContext ctx = getServletContext();
        ctx.setAttribute("email", emailAddr);
    }
%>

JSP 中的属性

一般使用隐式对象来得到和设置对应 JSP 中 4 个属性作用域的属性,即标准的 servlet 请求,会话,应用(上下文) 和 页面作用域

servlet JSP(使用隐式对象)
应用 getServletContext().setAttribute("foo", barObj); application.setAttribute("foo", barObj);
请求 request.setAttribute("foo", barObj); request.setAttribute("foo", barObj);
会话 request.getSession.setAttribute("foo", barObj); session.setAttribute("foo", barObj);
页面 不适用 pageContext.setAttribute("foo", barObj);

使用 PageContext 可以得到任意作用域的属性

09_作为 JSP_第1张图片
示例

1.设置和获取页面作用域属性

<% Float one = new Float(42.5); %>
<% pageContext.setAttribute("foo", one); %>
<%= pageContext.getAttribute("foo") %>

2.使用 pageContext 设置和获取会话作用域属性

<% Float two = new Float(42.5); %>
<% pageContext.setAttribute("foo", two, PageContext.SESSION_SCOPE); %>
<%= pageContext.getAttribute("foo", PageContext.SESSION_SCOPE); %>
等价于
<%= session.getAttribute("foo", PageContext.SESSION_SCOPE); %>

3.使用 PageContext 获得一个应用作用域属性

<%= pageContext.getAttribute("email", PageContext.APPLICATION_SCOPE) %>
等价于
<%= application.getAttribute("email") %>

4.使用 pageContext,不知道作用域也可以查找一个属性

<%= pageContext.findAttribute("foo") %>

查找时,首先在页面上下文中查找,如果页面作用域中没有这样的 “foo” 属性,会在其他作用域查找,即先在请求作用域查找,再查找会话作用域,最后查找应用作用域

EL

EL 代表 “表达式语言” ,它的用途是提供一种简单的方法来调用 Java 代码,但是代码放在别的地方。它的表达式形式是:(后面会详细介绍)

${something}

例如:

Please contact: ${applicationScope.email}

禁用脚本元素

在 DD 中放一个 标记,可以让 JSP 禁用脚本元素


<web-app ···>
    ···
    <jsp-config>
        <jsp-property-group>
            <url-pattern>*.jspurl-pattern>
            <scripting-invalid>truescripting-invalid>
        jsp-property-group>
    jsp-config>
<web-app>

忽略 EL

当你想把 EL 作为不处理的文本对待时,可以禁用 EL。可以通过 page 指令,或通过一个 DD 元素指定

在 DD 元素中放置 :

<web-app>
    ···
    <jsp-config>
        <jsp-property-group>
            <url-pattern>&.jsp</url-pattern>
            <el-ignored>true</el-ignored>
        </jsp-property-group>
    </jsp-config>
</web-app>

通过 page 指令

<%@ page isElIgnored="true" %>

JSP 元素:动作

标准动作:

<jsp:include page="wickedFooter.jsp" />

其他动作:

set var="rate" value="32" />

写在最后

如果有任何问题,欢迎交流学习。

你可能感兴趣的:(JavaWeb,JSP,JavaWeb)