1. JSP 入门学习

  • Java Server Pages:Java 服务器端页面,一个特殊的页面,其中既可以写 HTML 标签,又可以写 Java 代码,用于简化书写。
  • 原理:JSP 本质上就是一个 Servlet,转换后的 Java 文件就是调用输出流的 write 方法响应到界面上面。
  • 转换后的 Java 文件和 class 文件在什么地方?
    • 转换后的文件为项目运行期间产生的临时文件,部署在 Tomcat 上的文件还是 JSP 文件,转换后的文件在 Tomcat 安装目录下的 work 文件夹内。
    • 对于 IDEA,会为添加了 Tomcat 的项目单独建立一份配置文件,在使用的 CATALINA_BASE 目录下的 work 文件夹中。
  • JSP 脚本:JSP 定义 Java 代码的方式
    • <% 代码 %>:定义的 Java 代码,在 Servlet 的 service 方法中。service 方法中可以定义什么,该脚本中就可以定义什么。
    • <%! 代码 %>:定义的 Java 代码,代码在 JSP 转换后的 Servlet 类的成员位置,可以定义成员变量、成员方法、静态代码块等。
    • <%=代码 %>:定义的 Java 代码,会调用输出流的 write 方法输出到页面上,常用于取变量值。输出语句中可以定义什么,该脚本中就可以定义什么,此方法也在 service 方法中。
  • JSP 注释:
    • HTML 注释:<!-- -->,只能注释 HTML 代码片段,且在浏览器查看源码的时候可以看到此注释。
    • JSP 注释:<%-- --%>,可以注释所有代码,浏览器看不到此注释,推荐使用。

2. JSP 指令

  • 作用:用于配置 JSP 页面,导入资源文件
  • 格式:<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>
  • page 指令:配置 JSP 页面的。属性:
    • contentType:能够设置响应体的 MIME 类型以及字符集,等同于 response.setContentType(),一般取值为 text/html;charset=UTF-8
    • pageEncoding:可以设置当前页面的字符集,如果是高级的 IED,上述属性就能够设置,低级工具则需要此属性或者手动修改页面的字符集。
    • import:导入所需 jar 包。会转换为 Java 文件中 的 import
    • language:设置页面的编程语言,只能取 Java,但必须写上
    • errorPage:如果当前页面发生异常(因为本质为 Servlet),跳转至指定的错误页面(jsp)
    • isErrorPage:从上述属性跳转到的错误界面就是错误界面,此属性为 true,则可以获取上述界面发生的异常的对象。
      • true:是,可以使用内置对象 exception
      • false:否,也是默认值。不可以使用内置对象 exception
  • include 指令:包含页面的,导入页面的资源文件。(了解)
    • <%@ include file="index.jsp"%>:则会把 index.jsp 页面的东西展示在此页面上方。
  • taglib:导入资源,一般用来导入标签库,如 JSTL
    • <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      • prefix:自定义的前缀
    • 需要先把所需 jar 包添加到项目的构建路径再使用。

3. JSP 内置对象

  • 内置对象:在 JSP 页面中不需要获取和创建,可以直接使用的对象。

  • 变量名真实类型作用
    pageContextPageContext当前页面共享数据,还可以获取其他八个内置对象
    requestHttpServletRequest一次请求访问的多个资源共享(转发)
    sessionHttpSession一次会话的多个请求间共享
    applicationServletContext所有用户间共享数据
    responseHttpServletResponse响应对象
    pageObject当前页面(Servlet)的对象,Java 中的 this
    outJspWriter输出对象,数据输出到页面上
    configServletConfigServlet 的配置对象
    exceptionThrowable异常对象
  • JSP 的内置对象一共有 9 个。

  • request 对象:service 方法中的参数,无法在 <%! %> 中使用。

  • response 对象:service 方法中的参数,无法在 <%! %> 中使用。

  • out 对象:字符输出流对象。可以将数据输出到页面上。和 response.getWriter() 类似。

    • 在 Tomcat 服务器真正给客户端做出响应之前,会先找 response 缓冲区数据,再找 out 缓冲区数据。
    • 所以,response.getWriter() 数据输出永远在 out.write() 之前。
    • 一般输出数据到界面使用 out 对象,不使用 response.getWriter() 对象。

4. EL 表达式

  • Expression Language 表达式语言

  • 作用:替换和简化 JSP 页面中 Java 代码的编写

  • 语法:${表达式}

  • JSP 默认支持 el 表达式的。如果要忽略 el 表达式

    • 设置 JSP 中 page 指令中属性:isELIgnored="true" 可以忽略当前 JSP 页面中所有的 el 表达式
    • \${表达式}:忽略当前这个 el 表达式
  • 用于运算:

    • 算数运算符: + - * /(或者div) %(或者mod)
    • 比较运算符: > < >= <= == !=
    • 逻辑运算符: &&(and) ||(or) !(not)
    • 空运算符:empty
      • 功能:用于判断字符串、集合、数组对象是否为 null 或者长度是否为 0,返回值为 boolean 类型,经 EL 表达式,转换为字符串。
      • ${empty list}:判断字符串、集合、数组对象是否为 null 或者长度为 0
      • ${not empty str}:表示判断字符串、集合、数组对象是否不为 null 并且长度大于 0
  • 获取值:

    • el 表达式能从域对象中获取值,最后调用 toString,返回一个字符串

    • ${域名称.键名}:从指定域中获取指定键的值

      • 域名称 pageScope → 域对象 pageContext
      • 域名称 requestScope → 域对象 request
      • 域名称 sessionScop → 域对象 session
      • 域名称 applicationScope → 域对象 application(ServletContext)
      • 例如:在 request 域中存储了 name= 张三,通过 ${requestScope.name} 获取
      • 如果获取为 null,则自动转化为空字符串""
    • ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。

    • 上述方法获取的值是一个字符串,如果是一个对象,则会调用对象的 toStirng 方法展示到界面上。

      • 四个域对象的 setAttribute() 方法,接收的都是 Object 对象。
    • ${域名称.键名.属性名}:获取对象的值

      • 假设属性名为 username,则会去调用对象中的 username → Username → getUsername() 方法,来获取对应的值,所以说,本质上调用的是对象的 getter 方法。

      • 同样的,域名称可以省略,从小到大查找。

      • 例如:user 对象中有一个 Date birthday;,Date 类中有方法 getMonth(),则可通过 ${user.birthday.month} 来获取对应的月,调用了 getter 方法。

      • 扩展:如果想获取格式化后的 Date 字符串,则可以写一个逻辑视图,并没有对应的成员变量,只是为了提供需要的格式

        private Date birthday;
        //逻辑视图
        public String getBirStr() {
            if (birthday == null) return "";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return sdf.format(birthday);
        }
        

        然后通过 ${user.birStr} 来获取对应的字符串。

    • ${域名称.键名[索引]}:获取 List 集合中对应索引位置的值

      • EL 做了内部优化,倘若访问越界,并不会报异常,只会返回一个空的字符串""
    • 获取 Map 集合的值:

      • ${域名称.键名.key名称}
      • ${域名称.键名["key名称"]}
  • 隐式对象,就是不需要创建就能使用的对象

    • el 表达式中有 11 个隐式对象
    • pageContext:(重点掌握)
      • 获取 JSP 其他八个内置对象(jsp 一共 9 个内置对象)
      • ${pageContext.request.contextPath}:动态获取虚拟目录
      • 本质是调用 pageContext 的 getRequest() 方法获取 request 对象,然后通过 request 对象的 getContextPath() 方法获取项目的虚拟目录。

5. JSTL

  • JavaServer Pages Tag Library JSP 标准标签库

  • 是由 Apache 组织提供的开源的免费的 JSP 标签

  • 作用:用于简化和替换 JSP 页面上的 Java 代码

  • 使用步骤:

    • 导入 jstl 相关 jar 包
    • 引入标签库:taglib 指令,一般使用下列语句:
      • <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    • 使用标签
  • if 标签:

    • 必须属性 test:接受 boolean 表达式

      • 如果表达式为 true,则显示 if 标签体内容,如果为 false,则不显示标签体内容
      • 一般情况下,test 属性值会结合 el 表达式一起使用
    • c:if 标签没有 else 情况,想要 else 情况,则可以再定义一个 c:if 标签

    • <c:if test="true">
      	<h1>我是真...</h1>
      </c:if>
      <br>
      
      <%
      	List list = new ArrayList();
      	list.add("aaaa");
      	request.setAttribute("list",list);
      	request.setAttribute("number",4);
      %>
      
      <c:if test="${not empty list}">
      	遍历集合...
      </c:if>
      <br>
      <c:if test="${number % 2 != 0}">
      		${number}为奇数
      </c:if>
      <c:if test="${number % 2 == 0}">
      	${number}为偶数
      </c:if>
      
  • choose 标签:相当于 Java 代码的 switch 语句

    • 使用 choose 标签声明
    • 使用 when 标签做判断
    • 使用 otherwise 标签做其他情况的声明
    • <c:choose>
      	<c:when test="${number == 1}">星期一</c:when>
      	<c:when test="${number == 2}">星期二</c:when>
      	<c:otherwise>数字输入有误</c:otherwise>
      </c:choose>
      
  • foreach 标签:相当于 Java 代码的 for 语句,begin 和 end 都包括

    • for 循环:

      • begin:开始值

      • end:结束值

      • var:临时变量

      • step:步长

      • varStatus:循环状态对象

        • index:容器中元素的索引,从 0 开始,一般在容器中使用
        • count:循环次数,从 1 开始
      • <c:forEach begin="1" end="5" var="i" step="2" varStatus="s">
            ${i} - ${s.count}  <br>
        </c:forEach>
        1 - 1
        3 - 2
        5 - 3
        
    • 遍历容器:

      • items:容器对象

      • var:容器中元素的临时变量

      • varStatus:循环状态对象

        • index:容器中元素的索引,从 0 开始
        • count:循环次数,从 1 开始
      • <%
            List list = new ArrayList();
            list.add("aaa");
            list.add("bbb");
            list.add("ccc");
            request.setAttribute("list", list);
        %>
        
        <c:forEach items="${list}" var="str" varStatus="s">
            ${s.index} ${s.count} ${str}<br>
        </c:forEach>
        
        0 1 aaa
        1 2 bbb
        2 3 ccc
        

6. 从 List 取出数据到 JSP 页面的案例

  • <%
        List list = new ArrayList();
        list.add(new User("张三",23,new Date()));
        list.add(new User("李四",24,new Date()));
        list.add(new User("王五",25,new Date()));
        request.setAttribute("list",list);
    %>
    
    <table border="1" width="500" align="center">
        <tr>
            <th>编号</th>
            <th>姓名</th>
            <th>年龄</th>
            <th>生日</th>
        </tr>
        <c:forEach items="${list}" var="user" varStatus="s">
                <tr>
                    <td>${s.count}</td>
                    <td>${user.name}</td>
                    <td>${user.age}</td>
                    <td>${user.birStr}</td>
                </tr>
            </c:if>
        </c:forEach>
    </table>