Head First JSP---随笔五

11 篇文章 0 订阅
11 篇文章 0 订阅

作为JSP

JSP变成Servlet。这个servlet不用你来创建。容器会查看你的JSP,把它转换成Java源代码,在编译成完整的Java servlet类。


JSP技术模型

6.1 识别或描述以下元素,或为以下元素编写JSP代码:

  1. 模板文本
  2. 脚本元素(注释、指令、声明、scriptlet和表达式)
  3. 标准动作和制定动作
  4. 表达式语言元素

6.2 编写使用以下指令的JSP代码:

  1. page(带有属性import、session、contentType和isELIgnored)
  2. include
  3. taglib

6.3 编写使用了正确语法的JSP文档(基于XML的文档)

6.4 描述页面生命周期的作用和事件序列:

  1. JSP页面转换
  2. JSP页面编译
  3. 加载类
  4. 创建实例
  5. 调用jspInit方法
  6. 调用_jspService方法
  7. 调用_jspDestroy方法

6.5 给定一个设计目标,使用适当地隐式对象编写JSP代码:

  1. request
  2. response
  3. out
  4. session
  5. config
  6. application
  7. page
  8. pageContext
  9. exception

6.6 配置部署描述文件来声明一个或多个标记库,禁用计算(表达式)语言,以及禁用脚本语言

6.7 给定一个特定的设计目标,要求将一个JSP片段包含在另一个页面中,编写JSP代码使用最合适的包含机制(include指令或jsp:include标准动作)


JSP变成一个servlet

这里写图片描述

这一章将解决下面几个问题:

  1. JSP文件中的各个部分最后会放在servlet源代码中的说明位置?
  2. 能访问JSP页面的“servlet性”吗?例如,JSP中有ServletConfig或ServletContext的概念吗?
  3. JSP中可以放哪些类型的元素?
  4. JSP中的不同元素有什么语法?
  5. JSP的生命周期是怎样的?能介入到JSP生命周期中吗?
  6. JSP中的不同元素在最后的servlet中如何交互?

建立一个JSP显示被访问了多少次

开发环境:
开发环境
BasicCounter.jsp文件代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
The page count is:
<% 
    //JSP不认识Counter类,所以需要foo.Counter
    out.println(foo.Counter.getCount());
%>
</body>
</html>

Counter.java文件代码:

package foo;

public class Counter {
    private static int count = 0;
    public static synchronized int getCount() {
        count++;
        return count;
    }
}

XML文件代码:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">

    <welcome-file-list>
        <welcome-file>/BasicCounter.jsp</welcome-file>
    </welcome-file-list>

</web-app>

实验结果:
实验结果


使用page指令导入包

我们发现写foo有点麻烦。所以,使用page指令导入包。将JSP文件代码更改为:

<%@ page import="foo.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
The page count is:
<% 
    out.println(Counter.getCount());
%>
</body>
</html>

实验结果:
JSP2的实验结果

指令有3种:

  1. page
  2. include
  3. taglib

page允许你导入包。导入多个包<%@ page import="foo.*,java.util.*" %>

记住:<%@ page import = ? %>中的page是指令,import是page的属性,?是属性的值


表达式

我们在JSP代码里面使用了out.println(),我们应该尽量的避免这样的做法。所以可以更改JSP代码:

<%@ page import="foo.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
The page count is:
<%= Counter.getCount() %>
</body>
</html>

实验结果:
实验结果JSP3

我们已经看到3种不同类型的JSP元素:

  1. Scriptlet:<% %>
  2. 指令:<%@ %>
  3. 表达式:<%= %>

容器看到<%= Counter.getCount()%>就会把它转换为out.print(Counter.getCount());

如果看到的是<%= Counter.getCount();%>,注意最后一个分号,容器会转换成out.print(Counter.getCount(););这种样子,明显会报错

要记住:不要在表达式的最后加分号(还有要注意的地方就是,表达式不能输出一个void的类型,想想如果调用一个返回值为void的方法,就会报错)。


一个炸弹

修改JSP文件代码如下:

<%@ page import="foo.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
//定义一个变量是count,JSP是一个servlet
<% int count = 0; %>
The page count is:
//count+1
<%= ++count %>
</body>
</html>

我们认为JSP是一个servlet,用scriptlet声明一个变量,然后去使用它。结果刚刚开始的时候还不错,如下:
炸弹
第二次访问:
第二次
发现怎么和结果1等同呢?

于是我们查看jsp最后会变成一个什么样的servlet代码。如下:

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.4
 * Generated at: 2018-08-02 12:04:37 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
//与servlet的差别
import javax.servlet.jsp.*;
//导入的包
import foo.*;

//继承也不一样
public final class BasicCounter_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.HashSet<>();
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("foo");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = null;
  }

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  //初始化
  public void _jspInit() {
  }
  //销毁
  public void _jspDestroy() {
  }
  //service方法
  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

    final java.lang.String _jspx_method = request.getMethod();
    if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
      return;
    }

    //下面是隐式对象
    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html");
      pageContext = _jspxFactory.getPageContext(this, request, response,
                null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\r\n");
      out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");

      //我们写的代码,定义一个变量
      int count = 0; 

      out.write("\r\n");
      out.write("The page count is:\r\n");

      //我们写的代码,然count+1
      out.print( ++count );

      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

由上面代码的注释就知道了,原来我们定义的count是局部变量。因此我们知道了我们的原因。


另一个JSP元素

我们想要声明一个全局变量。

将JSP代码修改为(<%! %>设置全局变量):

<%@ page import="foo.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
//设置全局变量
<%! int count = 0; %>
The page count is:
<%= ++count %>
</body>
</html>

我们在看看JSP.java文件的代码:

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.4
 * Generated at: 2018-08-02 12:20:55 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import foo.*;

public final class BasicCounter_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {
  //count变成了全局变量
 int count = 0; 

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.HashSet<>();
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("foo");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = null;
  }

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  public void _jspInit() {
  }

  public void _jspDestroy() {
  }

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

    final java.lang.String _jspx_method = request.getMethod();
    if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
      return;
    }

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html");
      pageContext = _jspxFactory.getPageContext(this, request, response,
                null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\r\n");
      out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("\r\n");
      out.write("The page count is:\r\n");
      out.print( ++count );
      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

正如上面代码所看见的,count变成了全局变量。实验效果很好,会一直累计访问次数。


方法声明

修改JSP文件代码:

<%@ page import="foo.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
//JSP中定义方法
<%! int doubleCount(){
    count = count*2;
    return count;
} %>
<%! int count = 0; %>
The page count is:
<%= ++count %>
</body>
</html>

JSP.java文件在int count的上方增加了下面这样的一段代码:

//方法定义
int doubleCount(){
    count = count*2;
    return count;
}
//全局变量
int count = 0;

于是乎,我们好像知道了JSP就是一个servlet。


容器如何处理JSP

  1. 查看指令,得到转换时可能需要的信息。(比如导包)
  2. 创建一个HttpServlet子类,所生成的servlet会拓展:org.apache.jasper.runtime.HttpJspBase
  3. 如果有声明,容器会将这些声明写到类文件中,通常放在类声明下面,并在服务方法前面。(正如我们所看到的Tomcat声明了好多静态变量和好多方法)
  4. 建立服务方法。服务方法的具体方法名是_jspService()。这个方法由servlet超类被覆盖的service()方法调用,要接收HttpServletRequest和HttpServletResponse参数在建立这个方法时,容器会声明并初始化所有隐式对象
  5. 将普通的HTML(称为模板文本)、scriptlet和表达式放到服务方法中,完成格式化,并写至PrintWriter响应输出。

隐式对象

API隐式对象
JspWriterout
HttpServletRequestrequest
HttpServletResponseresponse
HttpSessionsession
ServletContextapplication
ServletConfigconfig
Throwableexception
PageContextpageContext
Objectpage

我们这里说说第4个作用域:pageContext(页面级作用域)

其中PageContext封装了其他隐式对象,所以如果向某些辅助对象提供一个PageContext引用,这些辅助对象就可以使用这个PageContext引用得到其他隐式对象的引用以及所有作用域的属性。

再说说exception,只有指定“错误页面”才能用到这个隐式对象


练习

开发环境:
开发环境
hobby.html代码:

<%@ page import="java.util.*" %>
<html>
<body>
    The friends who share your hobby of
    <%= request.getParameter("hobby") %>
    are:<br>
    <% ArrayList al = (ArrayList)request.getAttribute("names");%>
    <% Iterator it = al.iterator(); %>
    <% while(it.hasNext()){         %>
    <%= it.next() %>    
    <br>
    <% } %>
</body>
</html>

Hobby.java这个servlet代码:

package foo;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Hobby extends HttpServlet{
    private static final long serialVersionUID = 1L;

    @Override
    protected void doPost(HttpServletRequest request
            , HttpServletResponse response) 
                    throws ServletException, IOException {
        response.setContentType("html/text");

        ArrayList<String> al = new ArrayList<String>();
        al.add("Fred");
        al.add("Pradeep");
        al.add("Philippe");
        request.setAttribute("names", al);
        request.getRequestDispatcher("/BasicCounter.jsp").forward(request, response);
    }
}

BasicCounter.jsp代码:

<%@ page import="java.util.*" %>
<html>
<body>
    The friends who share your hobby of
    <%= request.getParameter("hobby") %>
    are:<br>
    <% ArrayList al = (ArrayList)request.getAttribute("names");%>
    <% Iterator it = al.iterator(); %>
    <% while(it.hasNext()){         %>
    <%= it.next() %>    
    <br>
    <% } %>
</body>
</html>

XML代码:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">

    <servlet>
        <servlet-name>hobby</servlet-name>
        <servlet-class>foo.Hobby</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>hobby</servlet-name>
        <url-pattern>/HobbyPage.do</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>/hobby.html</welcome-file>
    </welcome-file-list>

</web-app>

实验结果:
提交前
点击提交后:
提交后的结果


所生成servlet的API

JSP的UML图:
JSP的UML
3个关键方法:

  1. jspInit(),这个方法由init()方法调用。可以覆盖这个方法。
  2. jspDestroy(),这个方法由servlet的destroy()方法调用。可以覆盖这个方法。
  3. _jspService(),这个方法由servlet的service()方法调用,这说明,对于每个请求,它会在一个单独的线程中运行。容器将Request和Response对象传递给这个方法。不能覆盖这个方法。

JSP生命周期

  1. 部署.jsp文件,此时不做任何事情
  2. 客户请求.jsp文件,将.jsp文件转换成一个servlet.java文件
  3. 容器尝试这把这个.java文件被编译为.class文件
  4. 容器加载servlet类
  5. 容器实例化servlet并调用jspInit()方法
  6. 容器创建一个新线程来处理这个请求,通过调用_jspService()方法
  7. 调用jspDestroy()方法销毁servlet实例

这里指出:Web应用包含JSP,部署这个应用时,在JSP生命周期中,整个转换和编译步骤只发生一次


初始化JSP

我们想着既然JSP也是servlet,那么我们能不能能不能像初始化Servlet一样初始化JSP呢?该怎么做呢?

开发环境:
开发环境
配置servlet初始化参数(DD)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">

    <servlet>
        <servlet-name>MyTestInit</servlet-name>
        <jsp-file>/TestInit.jsp</jsp-file>
        <init-param>
            <param-name>email</param-name>
            <param-value>ikickedbutt@wickedlysmart.com</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>MyTestInit</servlet-name>
        <!-- 注意这里的url名字,映射而已 -->
        <url-pattern>/TestInit.do</url-pattern>
    </servlet-mapping>

</web-app>

覆盖jspInit()

<html>
<body>
    <%! 
        public void jspInit(){
            ServletConfig sConfig = getServletConfig();
            String emailAddr = sConfig.getInitParameter("email");
            ServletContext ctx = getServletContext();
            ctx.setAttribute("mail", emailAddr);
        }
    %>
    <%= config.getInitParameter("email") %>
    <%= application.getAttribute("mail") %>
</body>
</html>

实验结果如下:
实验结果


JSP中的属性

-servlet中JSP中(隐式对象)
应用getServletContext()application
请求requestrequest
会话request.getSession()session
页面不适用pageContext

通常我们不需要关系页面作用域,除非我们在开发定制标记

PageContext的UML图:
UML图


使用pageContext的实例

设置一个页面作用域属性

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

获取一个页面作用域属性

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

使用pageContext设置一个会话作用域属性

<%
    Float two = new Float(22.4);
    pageContext.setAttribute("foo",two,PageContext.SESSION_SCOPE);
%>

使用pageContext获得一个会话作用域属性(等价于session.getAttribute(“foo”))

<%= pageContext.getAttribute("foo",PageContext.SESSION_SCOPE)%>

使用pageContext获得一个应用作用域属性(等价于application.getAttribute(“mail”))

<%= pageContext.getAttribute("mail",PageContext.APPLICATION_SCOPE)%>

使用pageContext,即使不知道作用域也可以查找一个属性(查找顺序:先从请求作用域查找,再查找会话作用域,最后查找应用作用域。先找到哪一个就算“赢”)

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

JSP的3个指令

指令格式说明
page指令<%@ page import=”foo.*” session=”false”%>定义页面特定的属性,如字符编码、页面响应的内容类型,已经这个页面是否要有隐式对象。page指令可以使用至多13个不同属性(如import属性)
taglib指令<%@ taglib tagdir=”/WEB-INF/tags/cool” prefix=”cool”%>定义JSP可以使用标记库
include指令<%@ include file=”wickedHeader.html”%>定义在转换时增加到当前页面的文本和代码。从而允许你建立可重用的块,这些可重用的块能增加到各个页面上,而不必在每个JSP中重复写所有这些代码


page指令的属性

属性说明
import导包
isThreadSafe定义生成的servlet是否需要实现SingleThreadModel(最好不要这样做)
contentType定义JSP响应的MIME内容
isELIgnored定义转换(.jsp到.java)这个页面时是否忽略EL表达式
errorPage定义一个资源的URL,如果有未捕获到的Throwable,就会发送到这个资源。如果这个属性指定了一个JSP,该JSP的page指令中就会有isErrorPage=”true”属性
language定义scriptlet、表达式和声明中使用的脚本语言(现在就只有一个值,就是”java”)
extendsJSP会变成一个servlet类,这个属性则定义了这个类的超类(一般不会使用这个属性)
session定义页面是否有一个隐式的session对象。默认值为”true”
buffer定义隐式out对象如何处理缓存
autoFlush定义缓存的输出是否自动刷新输出。默认值为”true”
info定义放到转换后页面中的串,这样就能使用所生成servlet继承的getServletInfo()方法来得到这个信息
pageEncoding定义JSP的字符编码。默认为”ISO-8859-1”

EL

HTML开发员不懂Java,所以不能再JSP里面写这种Java代码。

于是,EL出现了,它的出现完美的解决下面2个问题:

  1. 不应该要求Web页面设计人员必须懂Java
  2. JSP中的Java代码很难修改和维护

EL小试牛刀

EL表达式:${applicationScope.mail}等价于<%= application.getAttribute("mail")%>


禁用scriptlet

在DD中配置:

<web-app ...>
    <jsp-config>
        <jsp-property-group>
            //作用于所有的.jsp文件
            <url-pattern>*.jsp</url-pattern>
            //只要配置上这个就行了,记住true是禁用scriptlet
            <scripting-invalid>true</scripting-invalid>
        </jsp-property-group>
    </jsp-config>
</web-app>

禁用EL表达式

两种方式:

(1)在DD中配置:

<web-app ...>
    <jsp-config>
        <jsp-property-group>
            //作用于所有的.jsp文件
            <url-pattern>*.jsp</url-pattern>
            <el-ignored>true</el-ignored>
        </jsp-property-group>
    </jsp-config>
</web-app>

(2)在JSP中用page指令(注意前面还有一个is):

<%@ page isELIgnored="true"%>

初见JSP的“动作”

标准动作:<jsp:include page="wickedFooter.jsp">
其他动作:<c:set var="rate" value="32">

看看动作的语法,把它与其他类型JSP元素的语法做个比较。我们回答下面问题:

(1)动作元素与scriptlet有什么区别?
本质上没有区别,只是代码形式改变了。

(2)看到一个动作时,怎么才能认出来?
不知道= =


本章完

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值