一、JSP页面技术

1.1 JSP简介

(1)JSP的概念

  • JPS全称是Java Server Page,它和Servlet一样,也是sun公司推出的一套开发动态web资源的技术。称为jsp/servlet规范。JSP的本质其实就是一个 Servlet。

(2)JSP和HTML以及Servelt的使用场景

类别 适用场景
HTML 只能开发静态的资源,不能包含Java代码,无法添加动态数据
Servlet 写Java代码,可以输出页面内容,但不是很方便。开发效率低。
JSP 它包括了HTML的展示技术,同时具备了Servlet输出的动态资源的能力。但是不适合作为控制器来用 。

(3)JSP简单的入门

  • 第一步:创建Java Web工程
  • 第二步:在index.jsp中填写内容

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    2. <html>
    3. <head>
    4. <title>JSP的入门</title>
    5. </head>
    6. <body>
    7. 这是第一个JSP页面
    8. </body>
    9. </html>
  • 第三步:部署项目

    • 沿用会话管理工程的部署方式即可。
  • 第四步:测试运行

(4)JSP的说明

  • JSP的原理
    • 客户端提交请求
    • Tomcat服务器解析请求地址
    • 找到JSP页面
    • Tomcat将JSP页面翻译称Servlet的Java文件
    • 将翻译好的Java文件编译成class文件
    • 返回到客户端浏览器上。
    • 结束。
  • 执行过程分析图。

JSP和EL表达式 - 图1

  • JSP的.Java文件分析
    • 当我们打开index.jsp翻译的java文件看到的就是public final class index_jsp extend org.apache.jasper.runtime.HttpJspBase类的声明,然后我们在tomca的源码中找到类的声明,如下图:

JSP和EL表达式 - 图2

  • 这张图一出场,就表明我们写的JSP它本质是一个HttpServlet了。

JSP和EL表达式 - 图3

1.2 JSP的语法

(1)Java代码块

  • 在JSP中,可以使用java脚本代码。形式为:<% 此处写Java代码 %>
  • 不过,在实际开发过程中,极少使用此种形式编写java代码。同时需要注意的是:
    • 这个代码块里面的内容有tomcat负责翻译,翻译之后是servlet的成员变量 。
  • 示例:

    1. <!--Java代码块-->
    2. <% System.out.println("这是Java代码块");%>
    3. <hr/>

    (2)JSP表达式

  • 在JSP中,可以使用特定的表达式语法,形式为:<%=表达式%>

  • JSP在翻译完后是out.print(表达式内容);
  • 所以:<%out.print(“当前时间”)%>和<%=”当前时间”%>是一样的。在实际开发中这种表达式语法也很少用。
  • 示例:

    1. <!--JSP表达式-->
    2. <%="这是JSP表达式"%><br/>
    3. 就相当于<br/>
    4. <%System.out.println("这是没有JSP表达式输出的");%>

    (3)JSP的声明

  • 在JSP中也可以声明一些变量、方法、静态方法等等。形式为:<%!声明的内容%>

  • 使用JSP声明需要注意的是:
    • 里面的内容会被tomcat翻译成servlet的全局变量(成员变量)或类方法(静态方法。)
  • 示例:

    1. <!--JSP声明-->
    2. <%! String str = "声明语法格式";%>
    3. <%=str%>

    (4)JSP的注解

  • 在使用JSP时,它有自己的注释:<%—— 注释 ——%>

  • 需要注意的是:
    • 在Jsp中可以使用html的注释,但是只能注释html元素,不能注释java程序片段和表达式。同时,被html注释部分会参与翻译,并且会在浏览器上显示
    • jsp的注释不仅可以注释java程序片段,也可以注释html元素,并且被jsp注释的部分不会参与翻译成.java文件,也不会在浏览器上显示。 ```html <%@ page contentType=”text/html;charset=UTF-8” language=”java” %>

<% out.println(“这是Java代码块”);%>


<%=”这是JSP表达式”%>
就相当于
<%out.println(“这是没有JSP表达式输出的”);%>


<%! String str = “声明语法格式”;%> <%=str%>


<%—JSP注释—%>

  1. <a name="lc4jk"></a>
  2. ## 1.3 JSP的指令
  3. <a name="hPc52"></a>
  4. ### (1)page指令
  5. - language:告知引擎,脚本使用的时Java,默认是Java,支持Java,不写也行。
  6. - extends:告知引擎 ,JSP对应的Servlet的父类是哪个,不需要写,也不需要改。
  7. - import:告知引擎,导入哪些包(类 )。
  8. - 注意:引擎会自动导入:
  9. - java.lang.*.javax.servlet.*
  10. - javax.servlet.http.*.javax.servlet.jsp.*;
  11. - 导入的格式:
  12. - <%@page import="java.util.Date,java.util.UUID"%>
  13. - <%@page import="java.util.Date"%>
  14. - <%@page import="java.util.UUID"%> (如果是用的是Eclipse:Alt+/ 自动导入)
  15. - session:告知引擎是否产生HttpSession对象,即是否在代码中调用request.getSession()方法 。默认是true。
  16. - buffer:JspWriter用于输出JSP内容到页面上。告知引擎,设定它的缓存大小。默认是8kb。
  17. - errorPage:告知引擎,当前页面出现异常后,应该转发到哪个页面上(路径写法:/代表当前应用)
  18. - 注意:当在errorPage上使用了isErrorPage=true之后,ie8有时候不能正常显示,配置全局错误页面在:web.xml文件。如下代码:
  19. ```xml
  20. <error-page>
  21. <!--java异常类的包-->
  22. <exception-type>java.lang.Exception</exception-type>
  23. <!--要配置的错误页面的地址-->
  24. <location>/error.jsp</location>
  25. </error-page>
  26. <error-page>
  27. <error-code>404</error-code>
  28. <location>/404.html</location>
  29. </error-page>
  • 当使用了全局错误页面,就无需再写errorPage来实现转到错误页面,而是由服务器负责跳转到错误页面了。
    • isErrorPage:告知引擎,是否抓住异常。如果该属性为true,页面中就可以使用exception对象,打印异常的详细信息。默认是false
    • contentType:告知引擎,响应正文的MIME类型。
  • contentType=”text/html;charset=UTF-8” 它相当于response.setContentType(“text/html;charset=UTF-8”)
    • pageEncoding:告知引擎,翻译jsp时(从磁盘上读取jsp文件)所用的码表。
  • pageEncoding=“UTF-8”相当于告知引擎用UTF-8读取jsp文件。
    • isELIgnored*:告知引擎,是否忽略EL表达式,默认是false,不忽略。

(2)include指令

  • 静态包含:
    • 语法格式:<%@include file=””%>,该指令是包含外部页面。属性:file,以“/”开头,就代表当前应用。
  • 使用示例:

JSP和EL表达式 - 图4

  • 静态包含的特点:当被包含的jsp页面被翻译成servlet时,在jsp页面上声明的变量时全局变量(成员变量),且修饰权限符是默认的。

JSP和EL表达式 - 图5

  • 动态包含
    • 语法格式:

(3)taglib指令

  • 语法格式:<%taglib uri=”” prefix=””%>
    • 作用:该指令用于引入外部的标签库。html标签和jsp标签不用引入。
    • 属性:uri:外部标签的URI地址。prefix:使用外部标签的前缀

1.4 jsp的隐式对象

(1)隐式对象的认识(九大隐式对象)

  • 什么是隐式对象?
    • 它指的是在jsp中,可以不声明就直接使用的对象。它只存在于jsp中,因为java类中的变量必须先声明再使用。其实jsp中的隐式对象也并非是未声明的,只是它是在翻译成java文件时声明的。所以我们在jsp中可以直接使用。 | 隐式对象名称 | 类型 | 备注说明 | | —- | —- | —- | | request | javax.servlet.http.HttpServletRequest | 请求对象 | | response | javax.servlet.http.HttpServletResponse | 响应对象 | | session | javax.servlet.http.HttpSession | page指令可以控制开关 | | application | javax.servlet.ServletContext |
      | | page | java.lang.Object | 当前jsp对应的servlet引用实例(等价于) | | config | javax.servlet.ServletConfig |
      | | exception | java.lang.Throwable | page指令有开关 | | out | javax.servlet.jsp.JspWRITER | 字符输出流,相当于printwriter | | pageContext | javax.servlet.jsp.PageContext | 很重要 |

(2)pageContext对象

  • 简介:
    • 它是JSP独有的对象,Servlet中没有这个对象。本身也是一个域(作用范围)对象,但是它可以操作其他3个域对象中的属性。而且还可以获取其他8个隐式对象。
  • 生命周期:
    • 它是一个局部变量,所以它的生命周期随着JSP的创建而诞生,随着JSP的结束而消失。每个JSP页面都有一个独立的PageContext。
  • 常用方法

JSP和EL表达式 - 图6

  • 注意:操作页面域的方法定义在了父类JspContext中了

JSP和EL表达式 - 图7

(3)四大域对象

域对象名称 范围 级别 备注说明
PageContext 页面范围 最小,只能在当前页面使用 因为范围小,开发中用的很少
ServletRequest 请求范围 一次请求或当前请求转发使用 当请求转发之后,再次转发时请求域中的数据会丢失。
HttpSession 会话范围 多次请求数据共享时使用 多次请求共享数据,但不同的客户端不能共享。
ServletContext 应用范围 最大,整个应用都可以使用 尽量少用,如果 对数据有修改需要做同步处理。

二、EL表达式和JSTL

2.1 EL表达式的概念与使用

(1)什么是EL?

  • EL表达式 ,全称是Expression Language。意为表达式语言,它是Servlet规范中的一部分,是JSP2.0规范加入的内容。其作用是用于在JSP页面上获取数据,从而让我们的JSP脱离Java代码块和JSP表达式。。
  • 基本语法:
    • EL表达式的语法非常简单,写为${表达式内容},例如:在浏览器中输出请求域中的名称为message的内容。假定,我们在请求域中存入了一个名称为message的数据。(request.setAttribute(“message”,”EL”);),此时在jsp中获取的方式,如下表显示: | java代码块 | JSP表达式 | EL表达式 | | —- | —- | —- | | <% String message = (String)request.getAttribute(“message”);
      out.write(message); %> | <%=request.getAttribute(“message”)%> | ${message} |

(2)EL表达式的入门案例

  • 第一步:创建Java web工程
  • 第二步:创建jsp页面

    1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    2. <html>
    3. <head>
    4. <title>EL表达式入门案例</title>
    5. </head>
    6. <body>
    7. <%--使用java代码在请求域中存入一个名称为message的数据--%>
    8. <% request.setAttribute("message","Expression Language");%>
    9. Java代码块获取:<% out.print(request.getAttribute("message"));%>
    10. <br/>
    11. JSP表达式获取:<%=request.getAttribute("message")%>
    12. <br/>
    13. EL表达式获取:${message}
    14. </body>
    15. </html>
  • 第三步:部署工程

  • 第四步:测试

(3)EL表达式的基本用法

  • 在前面的概述介绍中,我们介绍了EL表达式的作用,它就是用于获取数据的,那么它是从哪获取数据呢?它只能从四大域中获取数据,调用的就是findAttribute(name,value);方法,根据称由域的范围从小到大逐个域中查找,找到就返回,找不到就什么都不显示。它可以获取对象,可以是对象中关联其他对象,可以是一个List集合,也可以是一个Map集合。具体代码如下:创建两个实体类:User和Address ```java /**

    • 用户的实体类
    • @author 小哈
    • @Company http://www.xiaoha.com */ public class User implements Serializable{

      private String name = “小哈”; private int age = 18; private Address address = new Address();

      public String getName() {

      1. return name;

      } public void setName(String name) {

      1. this.name = name;

      } public int getAge() {

      1. return age;

      } public void setAge(int age) {

      1. this.age = age;

      } public Address getAddress() {

      1. return address;

      } public void setAddress(Address address) {

      1. this.address = address;

      }
      }

/**

  • 地址的实体类
  • @author 小哈
  • @Company http://www.HausenLee.com */ public class Address implements Serializable {

    private String province = “北京”; private String city = “昌平区”; public String getProvince() {

    1. return province;

    } public void setProvince(String province) {

    1. this.province = province;

    } public String getCity() {

    1. return city;

    } public void setCity(String city) {

    1. this.city = city;

    } } ```

  • 获取四大域中的数据
    • JSP代码
      1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
      2. <%@ page import="com.itheima.domain.User" %>
      3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      4. <html>
      5. <head>
      6. <title>EL入门</title>
      7. </head>
      8. <body>
      9. <%--EL表达式概念:
      10. 它是Expression Language的缩写。它是一种替换jsp表达式的语言。
      11. EL表达式的语法:
      12. ${表达式}
      13. 表达式的特点:有明确的返回值。
      14. EL表达式就是把内容输出到页面上
      15. EL表达式的注意事项:
      16. 1.EL表达式没有空指针异常
      17. 2.EL表达式没有数组下标越界
      18. 3.EL表达式没有字符串拼接
      19. EL表达式的数据获取:
      20. 它只能在四大域对象中获取数据,不在四大域对象中的数据它取不到。
      21. 它的获取方式就是findAttribute(String name)
      22. --%>
      23. <br/>-----------获取对象数据---------------------<br/>
      24. <% //1.把用户信息存入域中
      25. User user = new User();
      26. pageContext.setAttribute("u",user);
      27. %>
      28. ${u}===============输出的是内存地址<%--就相当于调用此行代码<%=pageContext.findAttribute("u")%> --%><br/>
      29. ${u.name}<%--就相当于调用此行代码<% User user = (User) pageContext.findAttribute("u");out.print(user.getName());%> --%><br/>
      30. ${u.age}
      31. <br/>-----------获取关联对象数据------------------<br/>
      32. ${u.address}==========输出的address对象的地址<br/>
      33. ${u.address.province}${u.address.city}<br/>
      34. ${u["address"]['province']}
      35. <br/>-----------获取数组数据---------------------<br/>
      36. <% String[] strs = new String[]{"He","llo","Expression","Language"};
      37. pageContext.setAttribute("strs", strs);
      38. %>
      39. ${strs[0]}==========取的数组中下标为0的元素<br/>
      40. ${strs[3]}
      41. ${strs[5]}===========如果超过了数组的下标,则什么都不显示<br/>
      42. ${strs["2"]}=========会自动为我们转换成下标<br/>
      43. ${strs['1']}
      44. <br/>-----------获取List集合数据-----------------<br/>
      45. <% List<String> list = new ArrayList<String>();
      46. list.add("AAA");
      47. list.add("BBB");
      48. list.add("CCC");
      49. list.add("DDD");
      50. pageContext.setAttribute("list", list);
      51. %>
      52. ${list}<br/>
      53. ${list[0] }<br/>
      54. ${list[3] }<br/>
      55. <br/>-----------获取Map集合数据------------------<br/>
      56. <% Map<String,User> map = new HashMap<String,User>();
      57. map.put("aaa",new User());
      58. pageContext.setAttribute("map", map);
      59. %>
      60. ${map}<br/>
      61. ${map.aaa}<%--获取mapvalue,是通过get(Key) --%><br/>
      62. ${map.aaa.name}${map.aaa.age}<br/>
      63. ${map["aaa"].name }
      64. </body>
      65. </html>

(4)EL表达式的注意事项

  • 在使用EL表达式时,它帮我们做了一些处理,使我们在使用时可以避免一些错误。它没有空指针异常,没有数组下标越界,没有字符串拼接。
  • 使用细节:
    • EL表达式除了能在四大域中获取数据,同时它可以访问其他隐式对象,并且访问对象有返回值的方法.

(5)EL表达式的运算符

  • EL表达式中运算符如下图所示,它们都是一目了然的:

JSP和EL表达式 - 图8
JSP和EL表达式 - 图9

  • 有两个特殊的运算符。使用方法如下:
    1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    2. <%@ page import="com.itheima.domain.User" %>
    3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    4. <html>
    5. <head>
    6. <title>EL两个特殊的运算符</title>
    7. </head>
    8. <body>
    9. <%--empty运算符:
    10. 它会判断:对象是否为null,字符串是否为空字符串,集合中元素是否是0
    11. --%>
    12. <% String str = null;
    13. String str1 = "";
    14. List<String> slist = new ArrayList<String>();
    15. pageContext.setAttribute("str", str);
    16. pageContext.setAttribute("str1", str1);
    17. pageContext.setAttribute("slist", slist);
    18. %>
    19. ${empty str}============当对象为null返回true<br/>
    20. ${empty str1 }==========当字符串为空字符串是返回true(注意:它不会调用trim()方法)<br>
    21. ${empty slist}==========当集合中的元素是0个时,是true
    22. <hr/>
    23. <%--三元运算符
    24. 条件?真:假
    25. --%>
    26. <% request.setAttribute("gender", "female"); %>
    27. <input type="radio" name="gender" value="male" ${gender eq "male"?"checked":""} >
    28. <input type="radio" name="gender" value="female" ${gender eq "female"?"checked":""}>
    29. </body>
    30. </html>

2.2 EL表达式的11个隐式对象

(1)EL隐式对象的介绍

  • EL表达式也为我们提供隐式对象,可以让我们不声明直接来使用,十一个对象见下表,需要注意的是,它和JSP的隐式对象不是一回事: | EL中的隐式对象 | 对应的Java类型 | 对应jsp隐式对象 | 备注说明 | | —- | —- | —- | —- | | PageContext | javax.servlet.jsp.PageContext | PageContext | 它们完全一样 | | Application | java.util.Map | 没有 | 应用层范围 | | SessionScope | java.util.Map | 没有 | 会话范围 | | RequestScope | java.util.Map | 没有 | 请求范围 | | PageScope | java.util.Map | 没有 | 页面层范围 | | Header | java.util.Map | 没有 | 请求消息头Key,值是value(单个值) | | HeaderValues | java.util.Map | 没有 | 请求消息头Key,值是一个数组(一个消息头,多个值) | | Param | java.util.Map | 没有 | 请求参数Key,值是value(单个值) | | ParamValues | java.util.Map | 没有 | 请求参数Key,值是一个数组(一个参数名称多个值) | | InitParam | java.util.Map | 没有 | 全局参数,Key是参数名称,value是参数值 | | Cookie | java.util.Map | 没有 | Key是cookie的名称,value是cookie对象 |

2.3 JSTL

(1)JSTL的概述

  • JSTL的全称是:JSP Standard Tag Libary。它是JSP中标准的标签库。它是由Apache实现的。
  • 它由以下5个部分组成: | 组成 | 作用 | 备注说明 | | —- | —- | —- | | Core | 核心标签库 | 通用逻辑处理 | | Fmt | 国际化有关 | 需要不同地域显示不同语言时使用 | | Functions | EL函数 | EL表达式可以使用的方法 | | SQL | 操作数据库 | 不用 | | xml | 操作xml | 不用 |

(2)使用要求

  • 要想使用JSTL标签库,在javaweb工程中需要导入坐标。首先是在工程的WEB-INF目录中创建一个lib目录,接下来把jstl的jar拷贝到lib目录中,最后在jar包上点击右键,然后选择【Add as Libary】添加。如下图所示:

JSP和EL表达式 - 图10

(3)核心标签库

  • 在我们实际开发中,用到的jstl标签库主要以核心标签库为准,偶尔会用到国际化标签库的标签。下表为常用的核心标签库 | 标签名称 | 功能分类 | 分类 | 作用 | | —- | —- | —- | —- | | (说明:c为自定义名称前缀) | 流程控制 | 核心标签库 | 用于判断 | | | 流程控制 | 核心标签库 | 用于多个条件判断 | | | 迭代操作 | 核心标签库 | 用于循环遍历 |
  • 使用案例

    1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    2. <%--导入jstl标签库 --%>
    3. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    4. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    5. <html>
    6. <head>
    7. <title>JSTL的常用标签</title>
    8. </head>
    9. <body>
    10. <%-- c:if c:choose c:when c:otherwise --%>
    11. <% pageContext.setAttribute("score","F"); %>
    12. <c:if test="${pageScope.score eq 'A' }">
    13. 优秀
    14. </c:if>
    15. <c:if test="${pageScope.score eq 'C' }">
    16. 一般
    17. </c:if>
    18. <hr/>
    19. <c:choose>
    20. <c:when test="${pageScope.score eq 'A' }">
    21. AAA
    22. </c:when>
    23. <c:when test="${pageScope.score eq 'B' }">BBB
    24. </c:when>
    25. <c:when test="${pageScope.score eq 'C' }">CCC
    26. </c:when>
    27. <c:when test="${pageScope.score eq 'D' }">DDD
    28. </c:when>
    29. <c:otherwise>其他</c:otherwise>
    30. </c:choose>
    31. <%-- c:forEach 它是用来遍历集合的
    32. 属性:
    33. items:要遍历的集合,它可以是EL表达式取出来的
    34. var:把当前遍历的元素放入指定的page域中。 var的取值就是key,当前遍历的元素就是value
    35. 注意:它不能支持EL表达式,只能是字符串常量
    36. begin:开始遍历的索引
    37. end:结束遍历的索引
    38. step:步长。i+=step
    39. varStatus:它是一个计数器对象。里面有两个属性,一个是用于记录索引。一个是用于计数。
    40. 索引是从0开始。计数是从1开始
    41. --%>
    42. <hr/>
    43. <% List<String> list = new ArrayList<String>();
    44. list.add("AAA");
    45. list.add("BBB");
    46. list.add("CCC");
    47. list.add("DDD");
    48. list.add("EEE");
    49. list.add("FFF");
    50. list.add("GGG");
    51. list.add("HHH");
    52. list.add("III");
    53. list.add("JJJ");
    54. list.add("KKK");
    55. list.add("LLL");
    56. pageContext.setAttribute("list",list);
    57. %>
    58. <c:forEach items="${list}" var="s" begin="1" end="7" step="2">
    59. ${s}<br/>
    60. </c:forEach>
    61. <hr/>
    62. <c:forEach begin="1" end="9" var="num">
    63. <a href="#">${num}</a>
    64. </c:forEach>
    65. <hr/>
    66. <table>
    67. <tr>
    68. <td>索引</td>
    69. <td>序号</td>
    70. <td>信息</td>
    71. </tr>
    72. <c:forEach items="${list}" var="s" varStatus="vs">
    73. <tr>
    74. <td>${vs.index}</td>
    75. <td>${vs.count}</td>
    76. <td>${s}</td>
    77. </tr>
    78. </c:forEach>
    79. </table>
    80. </body>
    81. </html>