zoukankan      html  css  js  c++  java
  • JavaWeb JSP

    1. JSP指令元素

    1.1. page指令

    page指令是JSP页面中最常用的指令,用来声明JSP页面的属性等信息。一个page指令允许定义多个属性;也可以一个page指令定义一个属性,定义多个page指令。

    <!-- 一个page指令,设置多个属性 -->
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!-- 一个page指令,设置一个属性.配置多个page指令 -->
    <%@ page import="java.util.*"%>
    <%@ page pageEncoding="UTF-8"%>

    但是需要注意的是:

    • page指令设置的属性只能出现一次,除import属性以外。
    • 属性名称区分大小写。

    page指令允许的属性如下:

    属性名称

    取值范围

    描述

    language

    java

    指明该JSP文件采用的语言。

    extends

    任何类的全名

    指明该JSP文件继承于哪个类。JSPServlet,因此当指明继承普通类时需要实现Servletinit()destroy()等方法。

    import

    任何包名、类名

    引入该JSP中用到的类、包等。import是唯一可以声明多次的page指令属性。一个import属性可以引用多个类,中间用英文逗号隔开。

    JSP中下面四个包里的类可以直接使用:java.lang.*javax.servlet.*javax.servlet.jsp.*javax.servlet.http.*

    session

    truefalse

    指明该JSP内是否内置Session对象。如果为true,则内置Session对象,可直接使用。否则不内置Session对象。默认为true

    autoFlush

    truefalse

    是否运行缓存。如果为true,则使用out.println()等方法输出的字符串并不是立刻到达服务器端的,而是暂时存在缓存里,缓存满或者程序执行完毕或者执行out.flush()操作时才到客户端。默认为true

    buffer

    none、数字+KB

    指定缓存大小,当autoFlush设为true时有效,默认值为8KB

    isThreadSafe

    truefalse

    指定是否线程安全。如果为true,则运行多个线程同时运行该JSP程序,否则只运行一个线程运行,其余线程等待。默认为false

    isErrorPage

    truefalse

    指定该页面是否为错误处理页面。如果为true,则该JSP内置Exception对象,可直接使用,否则没有。默认为false

    errorPage

    某个JSP页面的相对路径

    指明一个错误显示页面,如果该JSP程序抛出一个未捕捉的异常,则转到errorPage指定的页面。errorPage指定的页面通常isErrorPage属性为true,且内置Exception对象为未捕捉的异常。

    contentType

    有效的文档类型

    客户端浏览器根据该属性判断文档类型。

    info

    任意字符串

    指明该JSP的信息,该信息可以通过Servlet.getServletInfo()方法获取。

    trimDirective
    Whitespaces

    truefalse

    是否去掉指令前后的空白字符。默认为false

    isELIgnored

    truefalse

    指明当前页面是否忽略EL表达式。默认为false,表示不忽略。

    • pageEncodingcontentType属性
      • pageEncoding属性:指明当前JSP页面使用的编码格式。pageEncoding属性的值要与JSP页面的真实编码保持一致,否则会出现乱码。
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
      • contentType属性:在JSP页面编译成Servlet文件时,对应response.setContentType()方法。

    pageEncoding属性与contentType属性只设置其中一个属性时,另一个属性的默认与设置的相同。如果两个属性都不设置的话,两个属性的默认值都为“ISO-8859-1”。一般情况下,至少设置其中一个。

    • errorPageisErrorPage属性
      • 创建一个JSP页面,编写代码如下:
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>My JSP 'page.jsp' starting page</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="expires" content="0">
      </head>
      <body>
        This is my JSP page. <br>
        <%
            if(true){
                throw new RuntimeException();
            }
        %>
      </body>
    </html>
      • 发布Web工程,并访问http://localhost:8080/jsp/01_directive/page.jsp。

          页面访问报错,提示JSP页面的throw new RuntimeException();这句报错。当页面报错时,是不希望用户看到这样的错误页面,而是友好的错误信息。

      • 创建一个JSP页面,用于页面报错的友好提示信息。
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>My JSP 'error.jsp' starting page</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
      </head>
      <body>
        this is error page.<br>
      </body>
    </html>
      • 在第一个JSP页面中增加如下代码,设置如果当前页面出现错误,利用error.jsp页面进行错误信息的提示。
    <%@ page language="java" pageEncoding="UTF-8" errorPage="error.jsp"%>
      • 重新发布Web工程,并访问http://localhost:8080/jsp/01_directive/page.jsp。

          这时再次访问当前的JSP页面,会发现显示的是error.jsp页面的内容。这样的处理使得报错更好友,但是还存在一个问题,就是通过HttpWatch工具抓取会发现响应状态码为200,并不是错误的状态码。这就说明了虽然页面报错并进行了相关提示,但实际上JSP页面将错误隐藏起来,这样不利于之后的处理。

      • error.jsp页面中增加如下代码,设置如果当前JSP页面错误,响应对应的状态码,以便之后处理。
    <%@ page language="java" pageEncoding="UTF-8" isErrorPage="true"%>
      • 重新发布Web工程,并访问http://localhost:8080/jsp/01_directive/page.jsp。
      • error.jsp页面中,可以使用JSP内置对象exception获取异常信息等功能,该对象只能在错误页面中。
    <%@ page language="java" pageEncoding="UTF-8" isErrorPage="true"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>My JSP 'error.jsp' starting page</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
      </head>
      <body>
        this is error page.<br>
        <%=exception.getMessage() %>
      </body>
    </html>
      • JSP页面中指定错误页面虽然可以,但是操作繁琐(实际开发要为每一个JSP页面指定)。还可以使用web.xml文件配置错误页面信息。
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" 
        xmlns="http://java.sun.com/xml/ns/javaee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
      <!-- 配置对应状态码为404的错误页面 -->
      <error-page>
          <!-- 设置对应的状态码 -->
          <error-code>404</error-code>
          <!-- 配置错误页面路径 -->
          <location>/directive/error.jsp</location>
      </error-page>
      <!-- 配置对应异常的错误页面 -->
      <error-page>
          <!-- 设置对应的异常 -->
          <exception-type>java.lang.RuntimeException</exception-type>
          <!-- 配置错误页面路径 -->
          <location>/directive/error.jsp</location>
      </error-page>
    </web-app>

    1.2. include指令

    include指令用于在JSP页面中静态包含另一个文件,该文件可以是JSP页面、HTML页面、文本文件或一段Java代码。include语法格式如下:

    <%@ include file="包含文件的路径" %>

    设置包含文件的路径只能是常量,不能是变量。

    include.jsp页面:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>My JSP 'include.jsp' starting page</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
      </head>
      <body>
          欢迎你,现在的时间是:
        <%@ include file="date.jsp" %>
      </body>
    </html>

    date.jsp页面

    <%
        out.println(new java.util.Date().toString());
    %>

    1.3. taglib指令

    JSP页面支持标签,使用标签功能可以实现视图代码重用,很少量的代码可以实现很复杂的显示效果。要使用标签功能必须先声明标签库以及标签前缀。taglib指令用于指明JSP页面使用的JSP标签库。taglib指令的语法格式如下:

    <%@ taglib prefix="标签前缀" uri="标签库的完整路径" %>

    目前使用最多的是如下标签库:

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

    2. JSP动作标签

    2.1. <jsp:include>标签

    这个动作标签用于在当前页面中包含静态和动态的资源,一旦被包含的页面执行完毕,请求处理将在调用页面中继续进行。这个动作标签与javax.servlet.RequestDispatcher类的include方法一致。

    <jsp:include flush="boolean值" page="被包含页面的路径"></jsp:include>
    • flush属性:该属性是可选的。默认值为false,表示当前页面输出使用了缓冲区,在包含之前不刷新缓冲区。true表示刷新缓冲区。
    • page属性:指定被包含资源的相对路径,该路径是相对于当前JSP页面的URL

    include标签与include指令的区别:

    语法

    相对路径

    发生时间

    包含的对象

    描述

    <%@ include file=”url”%>

    相对于当前文件

    转换期间

    静态

    包含的内容被JSP容器分析

    <jsp:include page=”url”>

    相对于当前页面

    请求处理期间

    静态和动态

    包含的内容不进行分析

    2.2. <jsp:forward>标签

    这个动作标签运行在运行时将当前的请求转发给一个静态的资源、JSP页面或者Servlet,请求被转向到的资源必须位于同JSP发送请求相同的上下文环境中。这个动作标签与javax.servlet.RequestDispatcher类的forward()方法的作用相同。

    这个动作标签的语法格式如下:

    <jsp:forward page="请求转发到页面的路径"></jsp:forward>

    具体用法如下:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>My JSP 'forward.jsp' starting page</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
      </head>
      <body>
          <h1>forward.jsp</h1>
          <% System.out.println("forward jsp start..."); %>
        <jsp:forward page="include.jsp?flag=true"></jsp:forward>
        <% System.out.println("forward jsp end..."); %>
      </body>
    </html>

    转换成Servlet后的代码

    out.write("  	<h1>forward.jsp</h1>
    ");
    out.write("  	");
    System.out.println("forward jsp start..."); 
    out.write("
    ");
    out.write("    ");
    if (true) {
       _jspx_page_context.forward("include.jsp?flag=true");
       return;
    }
    out.write("
    ");
    out.write("    ");
    System.out.println("forward jsp end..."); 

    2.3. <jsp:param>标签

    这个动作标签与<jsp:include>标签、<jsp:forward>标签配合使用,以键值对形式为其他标签提供参数内容。这个动作标签的语法格式如下:

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

    具体用法参考如下代码:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>My JSP 'forward.jsp' starting page</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
      </head>
      <body>
        <jsp:forward page="include.jsp">
            <jsp:param value="true" name="flag"/>
        </jsp:forward>
      </body>
    </html>

    3. JSP内置对象

    3.1. out输出流对象

    内置对象outjavax.servlet.jsp.JspWriter类的实例,与response.getWriter()方法的作用相同,都是服务器端向客户端输出的字符串内容。该对象的常用方法如下:

    Method Summary

    abstract  void

    clear() 
              Clear the contents of the buffer.

    abstract  void

    flush() 
              Flush the stream.

     int

    getBufferSize() 
              This method returns the size of the buffer used by the JspWriter.

    abstract  int

    getRemaining() 
              This method returns the number of unused bytes in the buffer.

     boolean

    isAutoFlush() 
              This method indicates whether the JspWriter is autoFlushing.

    abstract  void

    print(String s) 
              Print a string.

    abstract  void

    println(String x) 
              Print a String and then terminate the line.

    3.2. pageContext上下文对象

    内置对象pageContextjavax.servlet.jsp.PageContext类的实例,该对象是JSP的四大作用域对象之一,pageContext对象代表当前JSP页面编译后的内容,多用于JSP页面之间共享数据内容。

    • pageContext对象的常用方法

    Method Summary

    abstract  Object

    getAttribute(String name) 
              Returns the object associated with the name in the page scope or null if not found.

    abstract  void

    removeAttribute(String name) 
              Remove the object reference associated with the given name from all scopes.

    abstract  void

    setAttribute(String name, Object value) 
              Register the name and value specified with page scope semantics.

    • pageContext对象获取其他八个内置对象

    Method Summary

    abstract  JspWriter

    getOut() 
              The current value of the out object (a JspWriter).

    abstract  Exception

    getException() 
              The current value of the exception object (an Exception).

    abstract  Object

    getPage() 
              The current value of the page object (In a Servlet environment, this is an instance of javax.servlet.Servlet).

    abstract  ServletRequest

    getRequest() 
              The current value of the request object (a ServletRequest).

    abstract  ServletResponse

    getResponse() 
              The current value of the response object (a ServletResponse).

    abstract  ServletConfig

    getServletConfig() 
              The ServletConfig instance.

    abstract  ServletContext

    getServletContext() 
              The ServletContext instance.

    abstract  HttpSession

    getSession() 
              The current value of the session object (an HttpSession).

    • pageContext对象操作其他三个域

    Method Summary

    abstract  Object

    findAttribute(String name) 
              Searches for the named attribute in page, request, session (if valid), and application scope(s) in order and returns the value associated or null.

    abstract  Object

    getAttribute(String name, int scope) 
              Return the object associated with the name in the specified scope or null if not found.

    abstract  void

    removeAttribute(String name, int scope) 
              Remove the object reference associated with the specified name in the given scope.

    abstract  void

    setAttribute(String name, Object value, int scope) 
              Register the name and value specified with appropriate scope semantics.

    上述方法中的scope参数表示其他三个域常量:

    Field Summary

    static int

    APPLICATION_SCOPE 
              Application scope: named reference remains available in the ServletContext until it is reclaimed.

    static int

    REQUEST_SCOPE 
              Request scope: the named reference remains available from the ServletRequest associated with the Servlet until the current request is completed.

    static int

    SESSION_SCOPE 
              Session scope (only valid if this page participates in a session): the named reference remains available from the HttpSession (if any) associated with the Servlet until the HttpSession is invalidated.

    3.3. request请求对象

    内置对象requestjavax.servlet.ServletRequest类的实例,代表着客户端的请求。具体用法请参考Request对象内容。

    3.4. response响应对象

    内置对象responsejavax.servlet.ServletResponse类的实例,代表着服务器端的响应。具体用法请参考Response对象内容。

    3.5. config配置对象

    内置对象configjavax.servlet.ServletConfig类的实例,ServletConfig对象封装了配置在web.xml文件中初始化JSP的参数,JSP通过config对象获取这些参数值。具体用法请参考ServletConfig对象内容。

    3.6. session会话对象

    内置对象sessionjavax.servlet.http.HttpSession类的实例,sessioncookie是解决Http协议的无状态问题的两种解决方案。如果在JSP页面中使用<%@ page session=”false”%>指令的话,则在当前JSP页面中不能使用session内置对象。但一般情况下,不会禁止使用session对象,具体用法请参考HttpSession对象内容。

    3.7. application应用对象

    内置对象applicationjavax.servlet.ServletContext类的实例,ServletContext封装了JSP所在的Web应用程序的信息,整个Web应用程序对应一个ServletContext对象。具体用法请参考ServletContext对象内容。

    3.8. page页面对象

    内置对象pagejavax.servlet.jsp.HttpJspPage类的实例,page对象代表当前JSP页面,是当前JSP编译后的Servlet类的对象。page相当于普通Java类中的关键字this

    3.9. exception异常对象

    内置对象exceptionjava.lang.Exception类的实例,该对象封装了JSP中抛出的异常信息。exception对象只能在使用<%@ page isErrorPage=”true”%>指令的JSP页面中。

    4. JSPJavaBean

    4.1. JavaBean概述

    JavaBean本质上就是一个Java类,只不过这个类需要遵循一些编码的规范。在JSP页面中,既可以使用普通类一样实例化JavaBean类的对象,调用方法,也可以利用JSP提供的动作标签访问JavaBean

    一个标准的JavaBean具有以下几个特性:

    • 是一个公开(public)的类。
    • 有一个默认的无参构造方法。
    • 提供SetterGetter方法用于设置和获取JavaBean的属性。

    换句话讲,只要是符合上述条件的类,都可以看作是JavaBean。下面就是一个JavaBean实例:

    public class User {
        public String name;
        public Boolean married;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Boolean isMarried() {
            return married;
        }
        public void setMarried(Boolean married) {
            this.married = married;
        }
    }

    4.2. 内省

    SUN公司开发了一套API,方便更好地操作JavaBean的属性,这套API被称之为内省(Introspector)。内省的出现有利于对JavaBean的属性操作,减少了代码量,内省依赖于Java的反射。

    通过内省来操作JavaBean的属性,具体步骤如下:

    • 通过Class类对象获取BeanInfo实例。
    • 通过BeanInfo实例获取所有属性描述符对象。
    • 通过属性描述符对象操作对应JavaBean的属性。
    public class Demo {
        @Test
        public void Demo() throws Exception{
            Class c = User.class;
            Object obj = c.newInstance();
            //1 通过Class类对象获取BeanInfo实例
            BeanInfo info = Introspector.getBeanInfo(User.class);
            //2 通过BeanInfo实例获取所有属性描述符对象
            PropertyDescriptor[] pds = info.getPropertyDescriptors();
            /*
             * 3 通过属性描述符对象操作对应JavaBean的属性
             *  * 获取属性名称
             *  * 获取读方法
             *  * 获取写方法
             */
            for (PropertyDescriptor pd : pds) {
                // 获取并输出JavaBean的属性名称
                System.out.println(pd.getName());
                // 获取并输出JavaBean的属性类型
                System.out.println(pd.getPropertyType());
                // 判断当前获取的JavaBean的属性名称是否为"name"
                if (pd.getName().equals("name")) {
                    // 获取JavaBean的name属性的写方法
                    Method wmd = pd.getWriteMethod();
                    wmd.invoke(obj, "longestory");
                    // 获取JavaBean的name属性的读方法
                    Method rmd = pd.getReadMethod();
                    System.out.println(rmd.invoke(obj));
                }
            }
        }
    }

    4.3. BeanUtils工具

    虽然Java提供了反射和内省相关的API,用于操作JavaBean组件的属性。但这些API方法使用起来很复杂,BeanUtils工具是Apache基于Java的内省封装的一个工具包。

    BeanUtils工具包使用时,需要依赖logging日志包。

    • 通过BeanUtils工具操作JavaBean的属性相关简单了不少。
    public class Demo {
        @Test
        public void Demo() throws Exception{
            Class c = User.class;
            Object obj = c.newInstance();
            BeanUtils.setProperty(obj, "name", "longestory");
            BeanUtils.setProperty(obj, "age", "14");
            BeanUtils.setProperty(obj, "married", true);
            
            String name = BeanUtils.getProperty(obj, "name");
            System.out.println(name);
        }
    }
    • 通过BeanUtils工具的populate()方法来操作JavaBean
    public class Demo {
        @Test
        public void Demo() throws Exception{
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("name", "longestory");
            map.put("age", "18");
            map.put("married", true);
            
            Class c = User.class;
            Object obj = c.newInstance();
            
            BeanUtils.populate(obj, map);
            System.out.println(obj);
        }
    }
    • 通过populate()方法将一个Map集合内容设置到对应的JavaBean中,自定义一个工具类来完成复用。
    public class CommonUtils {
        public static <T> T toBean(Map map, Class<T> clazz) {
            try {
                T bean = clazz.newInstance();
                BeanUtils.populate(bean, map);
                return bean;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    下面通过一个案例来掌握BeanUtils封装内省的内容。

    • 创建一个JSP页面用于显示用户注册信息。
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>用户注册页面</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
      </head>
      <body>
        <form action="/12_jsp/regist" method="post">
              用户名:<input type="text" name="username"/><br/>
              密码:<input type="password" name="password"/><br/>
              确认密码:<input type="password" name="repassword"/><br/>
              邮箱:<input type="text" name="email"/><br/>
          <input type="submit" value="注册"/>
        </form>
      </body>
    </html>
    • 创建一个JavaBean用于封装用户注册信息。
    public class Person {
        private String username;
        private String password;
        private String email;
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        public String getEmail() {
            return email;
        }
        public void setEmail(String email) {
            this.email = email;
        }
        @Override
        public String toString() {
            return "Person [username=" + username + ", password=" + password + ", email=" + email + "]";
        }
    }
    • 创建一个Servlet用于接收用户注册信息。
    public class PersonServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            Person person = CommonUtils.toBean(request.getParameterMap(), Person.class);
            System.out.println(person);
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }
    • 配置Web工程的web.xml文件。
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" 
        xmlns="http://java.sun.com/xml/ns/javaee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
      <display-name></display-name>
      <servlet>
        <servlet-name>PersonServlet</servlet-name>
        <servlet-class>app.java.exam.PersonServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>PersonServlet</servlet-name>
        <url-pattern>/regist</url-pattern>
      </servlet-mapping>    
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>
    • 发布Web工程,并访问http://localhost:8080/jsp/index.jsp进行测试。

    4.4. JSP动作标签

    JSP中可以像使用普通类一样访问JavaBeanJSP提供了三个动作标签<jsp:useBean><jsp:setProperty><jsp:getProperty>来访问JavaBean

    • <jsp:useBean>动作标签

    该动作标签用于实例化JavaBean,或者定位一个已经存在的JavaBean实例。

    该动作标签的语法格式:

    <jsp:useBean id="实例名称" class="实例全类名" scope="指定范围"></jsp:useBean>
      • id属性:用于标识JavaBean实例的名称。需要注意的是,指定的名称是区分大小写的,并遵照Java语言变量命名的约定。
      • class属性:指定JavaBean实例的完整类名。
      • scope属性:指定一个范围,在这个范围中,JavaBean实例的引用是可用的,实际上也是指定JavaBean实例的生命周期。备选取值有pagerequestsessionapplication,默认值为page

    <jsp:useBean>动作标签的实际作用可以利用下述Java代码进行解释:

    <jsp:useBean id="user" class="app.java.bean.User" scope="session" />
    
    User user = (User)session.getAttribute("user");
    if(user == null) {
        user = new User();
        session.setAttribute("user", user);
    }
    • <jsp:setProperty>动作标签

    该动作标签与<jsp:useBean>一起使用,用于设置JavaBean的属性。

    该动作标签的语法格式:

    <jsp:setProperty property="属性名称" name="实例名称" value="属性值"/>
    • <jsp:getProperty>动作标签

    该动作标签用于访问一个Bean的属性,并把属性的值转化成一个String,然后发送到输出流中。如果属性是一个对象,将调用该对象的toString()方法。

    该动作标签的语法格式:

    <jsp:getProperty property="属性名称" name="实例名称"/>

    5. EL表达式语言

    5.1. EL表达式语法

    JSP中可以使用ELExpression Language)表达式。EL表达式是用“${}”括起来的脚本,用来更方便地读取对象。EL表达式写在JSPHTML代码中,而不能写在“<%%>”的JSP脚本中。

    如果在JSP页面中使用了<%@ page isELIgnored=”true”%>指令的话,该JSP页面会忽略EL表达式。如果忽略某个EL表达式的话,可以在EL表达式之前添加“”(例如${1+2})。

    EL表达式的值为null时,会在JSP页面上显示空白,即什么都不显示。

    EL表达式具有一些运算符,如下表

    运算符

    说明

    范例

    结果

    +

    ${17+5}

    22

    -

    ${17-5}

    12

    *

    ${17*5}

    85

    /div

    ${17/5}${17 div 5}

    3

    %mod

    取余

    ${17%5}${17 mod 5}

    2

    ==eq

    等于

    ${5==5}${5 eq 5}

    true

    !=ne

    不等于

    ${5!=5}${5 ne 5}

    false

    <lt

    小于

    ${3<5}${3 lt 5}

    true

    >gt

    大于

    ${3>5}${3 gt 5}

    false

    <=le

    小于等于

    ${3<=5}${3 le 5}

    true

    >=ge

    大于等于

    ${3>=5}${3 ge 5}

    false

    &&and

    并且

    ${true&&false}${true and false}

    false

    !not

    ${!true}${not true}

    false

    ||or

    或者

    ${true||false}${true or false}

    true

    empty

    是否为空

    ${empty “”},可以判断字符串、数据、集合的长度是否为0,为0返回trueempty还可以与not!一起使用。${not empty “”}

    true

    值得注意的是旧版本的Servlet规范不支持EL表达式,例如Tomcat 4.x以及以前的版本都不支持EL表达式。

    EL表达式提供了获取JavaBean对象以及属性的简单方式。某些情况下EL表达式完全可以替代JSP脚本或者JSP行为,例如:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>My JSP 'expression.jsp' starting page</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
      </head>
      <body>
        <jsp:useBean id="user" class="app.java.bean.User" scope="session" />
        <!-- 相当于session.getArribute("person") -->
        欢迎您,${person}.
        <!-- 相当于person.getAge() -->
        <!-- 也相当于<jsp:getProperty name="person" property="age"> -->
            您的年龄为${person.age}.
      </body>
    </html>

    5.2. EL表达式内置对象

    EL表达式不仅可以读取对象,还内置了十一个隐藏对象,这些内置对象无需创建,可以直接使用。而EL表达式中的内置对象中,最重要的是获取四大域相关的内置对象,如下表:

    标识符

    描述

    示例

    pageScope

    包含apge作用域内变量的Map

    使用<jsp:useBean id=”user” class=”app.java.bean.User” scope=”page”>声明pageScope范围内的User对象后,${pageScope.user.name}将输出该对象的name属性值

    requestScope

    包含request作用域内变量的Map

    使用<jsp:useBean id=”user” class=”app.java.bean.User” >声明requestScope范围内的User对象后,${requestScope.user.name}将输出该对象的name属性值。useBean标签默认的作用域为request

    sessionScope

    包含session作用域内变量的Map

    使用<jsp:useBean id=”user” class=”app.java.bean.User” scope=”session”>声明sessionScope范围内的User对象后,${sessionScope.user.name}将输出该对象的name属性值

    applicationScope

    包含application作用域内变量的Map

    使用<jsp:useBean id=”user” class=”app.java.bean.User” scope=”applcation”>声明applcation Scope范围内的User对象后,${ applcation Scope.user.name}将输出该对象的name属性值

    除了上述获取四大域相关的内置对象以外,还有其他内置对象,但实际使用率并不高。

    类别

    标识符

    描述

    示例

    请求参数

    param

    包含所有参数的Map,可以获取参数,返回String

    ${param.foo}${param[‘foo’]}

    paramValues

    包含所有参数的Map,可以获取参数数组,返回String[]

    当提交多个参数,例如index.jsp?a=first&a=second,提交的参数a为多个值{“first”, “second”}。使用param只能获取第一个值,而使用paramValues能获取到所有值,${paramValues.a[0]}将输出“first”, ${paramValues.a[1]}将输出“second”

    头信息

    header

    包含所有头信息的Map,返回String

    ${header.host}可能返回localhost:8080

    headerValues

    包含所有头信息的Map,返回String[]

    ${headerValues.host[0]},当头信息为数组时可以获取多个值。

    初始化参数

    initParam

    包含所有初始化参数的Map

    ${initParam.encoding}

    Cookie

    cookie

    包含所有CookieMapkeyCookiename属性

    使用<%response.addCookie(new Cookie(“user”, “king”))%>设置Cookie后,${cookie.user}返回该Cookie${cookie.user.name}返回user${cookie.user.value}返回king

    pageContext

    包含页面内的变量的Map,包含requestresponsepage等所有内置对象

    ${pageContext.request.remoteAddr}将返回客户端IP地址,相当于执行<%=pageContext.getRequest().getRemoteAddr()%>

    之前在页面中编写请求资源路径时,都是固定内容。在掌握了EL表达式后,可以如下方式编写请求资源路径:

    <a href="${pageContext.request.contextPath }/index.jsp">请求</a>

    5.3. EL表达式函数

    EL函数库是由第三方对EL表达式的扩展,目前学习的EL函数库是由JSTL(关于JSTL会在后面的内容学到)添加的。EL函数库就是定义了一些有返回值的静态方法,然后通过EL表达式调用。当然不只是JSTL可以定义EL函数库,我们也可以自定义EL函数库。

    因为EL函数库是第三方提供的,所有要想使用的话,首先需要使用taglib指令引入。

    <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

    JSTL提供的EL函数库包含的函数具体如下:

    • String toUpperCase(String input):将一个字符串转换成大写。
    • String toLowerCase(String input):将一个字符串转换成小写。
    • int indexOf(String input, String substring):检索字符串。
    • boolean contains(String input, String substring):判断一个字符串是否包含另一个字符串。
    • boolean containsIgnoreCase(String input, String substring):判断一个字符串是否包含另一个字符串(忽略大小写)。
    • boolean startsWith(String input, String substring):判断一个字符串是否以另一个字符串开始。
    • boolean endsWith(String input, String substring):判断一个字符串是否以另一个字符串结束。
    • String substring(String input, int beginIndex, int endIndex):按照指定开始位置和结束位置截取字符串。
    • String substringAfter(String input, String substring):截取指定字符后的所有字符串。
    • String substringBefore(String input, String substring):截取指定字符前的所有字符串。
    • String escapeXml(String input):将字符串内容进行转义。
    • String trim(String input):将字符串的前后空格去掉。
    • String replace(String input, String substringBefore, String substringAfter):将一个字符串中的某个字符,利用另一个字符替换。
    • String[] split(String input, String delimiters):将一个字符串利用指定分隔符分割。
    • int length(Object obj):返回指定内容的长度。
    • String join(String array[], String separator):使用指定连接符将数组中的每个元素连接。

    下面是上述函数的具体使用方式:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>My JSP 'MyJsp.jsp' starting page</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
      </head>
      <body>
          <%
            String[] strs = {"a", "b","c"};
            List list = new ArrayList();
            list.add("a");
            pageContext.setAttribute("arr", strs);
            pageContext.setAttribute("list", list);
        %>
        
        ${fn:length(arr) }<br/><!--3-->
        ${fn:length(list) }<br/><!--1-->
        ${fn:toLowerCase("Hello") }<br/> <!-- hello -->
        ${fn:toUpperCase("Hello") }<br/> <!-- HELLO -->
        ${fn:contains("abc", "a")}<br/><!-- true -->
        ${fn:containsIgnoreCase("abc", "Ab")}<br/><!-- true -->
        ${fn:contains(arr, "a")}<br/><!-- true -->
        ${fn:containsIgnoreCase(list, "A")}<br/><!-- true -->
        ${fn:endsWith("Hello.java", ".java")}<br/><!-- true -->
        ${fn:startsWith("Hello.java", "Hell")}<br/><!-- true -->
        ${fn:indexOf("Hello-World", "-")}<br/><!-- 5 -->
        ${fn:join(arr, ";")}<br/><!-- a;b;c -->
        ${fn:replace("Hello-World", "-", "+")}<br/><!-- Hello+World -->
        ${fn:join(fn:split("a;b;c;", ";"), "-")}<br/><!-- a-b-c -->
        
        ${fn:substring("0123456789", 6, 9)}<br/><!-- 678 -->
        ${fn:substring("0123456789", 5, -1)}<br/><!-- 56789 -->
        ${fn:substringAfter("Hello-World", "-")}<br/><!-- World -->
        ${fn:substringBefore("Hello-World", "-")}<br/><!-- Hello -->
        ${fn:trim("     a b c     ")}<br/><!-- a b c -->
        ${fn:escapeXml("<html></html>")}<br/> <!-- <html></html> -->
      </body>
    </html>

    我们也可以自定义EL函数库,具体自定义EL函数库的步骤如下:

    • 创建一个Java类,该类包含具有返回值的静态方法。
    package app.java.el.functions;
    
    public class MyFunctions {
        public static String test() {
            return "自定义EL函数库测试";
        }
    }
    • WEB-INF目录下创建一个“.tld”文件,用于配置自定义EL函数库。
    <?xml version="1.0" encoding="UTF-8" ?>
    <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
      version="2.0">
        
      <tlib-version>1.0</tlib-version>
      <short-name>myfn</short-name>
      <uri>http://www.myfn.com/jsp/functions</uri>
    
      <function>
        <name>test</name>
        <function-class>app.java.el.functions</function-class>
        <function-signature>String test()</function-signature>
      </function>
    </taglib>
    • JSP页面中添加tagllib指令,导入自定义EL函数库。
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@ taglib prefix="ls" uri="/WEB-INF/myfunctions.tld" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>自定义EL函数库</title>
      </head>
      <body>
        <h1>${ls:test() }</h1>
      </body>
    </html>
  • 相关阅读:
    React class & function component 的区别
    Webpack 4 + React + Typescript 搭建启动模版
    JavaScript的数据类型及其检测
    react SyntheticEvent 合成事件机制
    数组的排序
    Ajax 和 Ajax的封装
    go 结构的方法总结
    go 结构的方法2
    go struct 的方法1
    go 函数闭包
  • 原文地址:https://www.cnblogs.com/aaron911/p/7799265.html
Copyright © 2011-2022 走看看