JSP

1. 

//servlet中
resp.setContentType("text/html;charset=UTF-8");
//等同于JSP中
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

2. JSP指示元素的主要目的, 在于指示容器在将JSP转化成Servlet是, 一些必须遵循的信息.语法:

<%@ 指示类型 [属性="值"]* %>

3. JSP有三种常用的指示元素: page , includetaglib.

  • page 指示类型告诉容器如何转译当前的JSP页面  
    <%@ page language="java" import="java.util.Date"%>
  • include 指示类型告知容器将别的JSP页面包括进来进行转译.
    <%@ include file="top.jsp" %>

与<jsp:include page="top.jsp">的区别 

  执行时间上: 
   <%@ include file=”relativeURI”%> 是在翻译阶段执行, 最后只有一个class文件
   <jsp:include page=”relativeURI” flush=”true” /> 在请求处理阶段执行
  引入内容的不同: 
   <%@ include file=”relativeURI”%> 引入静态文本(html,jsp),在JSP页面被转化成servlet之前和它融和到一起。 
   <jsp:include page=”relativeURI” flush=”true” /> 引入执行页面或servlet所生成的应答文本。当前页面转译成的Servlet中会取得RequestDispatcher对象, 并            执行include()方法, 将请求交给被include的页面转译成的Servlet, 而后再回到当前的Servlet.

  • taglib 指示类型告知容器如何转译这个页面中的标签库
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

4. 声明(Declaration)元素 <%! java语言 %> , 为转译后的Servlet添加类成员或方法, 因为Servlet默认是单实例的, 所以需要当心数据共享线程安全问题

1 <%!
2     String name = "admin";
3     String password = "admin";
4     
5     boolean checkUser(String name, String password) {
6         return this.name.equals(name) && this.password.equals(password);
7     }
8 %>

如果想要在JSP载入时做一些初始化工作, 或是做一些结尾动作, 可以在<%! %>中定义 jspInit()jspDestory() , 这个两个方法在编译后的Servlet所继承的父类(HttpJspBase, 它继承了HttpServlet)中init(), destroy()方法中会调用(会先调用 jspInit()/jspDestory(), 然后调用 _jspInit()/_jspDestory())

5. Scriptlet元素 <% java语言 %> , 其中包含的内容会被转译为Servlet源码 _jspService() 中的内容, 且代码的顺序不变.

6. 表达式元素 <%= java表达式 %> , 其中的表达式会直接转译为_jspService()方法中 out 对象输出时的指定内容(所以不能有分号). <%= new Date() %>  -->  out.print(new Date());

7. JSP隐式对象, 只能在 <% %> 和 <%=  %> 之间使用, 因为这些对象在转译为Servlet后, 是 _jspService() 中的局部对象, 无法在 <%!  %> 之间使用

out 转译后对应JspWriter对象, 其内部关联一个PrintWriter对象, 该对象主要模拟了 BufferedWriter 和 PrintWriter 的功能
request 转译后对应HttpServletRequest对象
response 转译后对应HttpServletResponse对象
config 转译后对应ServletConfig对象
application 转译后对应ServletContext对象
session 转译后对应HttpSession对象
pageContext  转译后对应PageContext对象, 它提供了JSP页面资源的封装(所以隐式对象都可以通过它获取), 并可设置页面范围属性
exception 转译后对应Throwable对象, 代表由其他JSP页面抛出的异常对象, 只会出现于JSP错误页面(isErrorPage设置为true的JSP页面)
page 转译后对应this

8. JSP会转成Servlet, 有三种时刻可能会发生错误. 可以通过 <%@ page errorPage="error.jsp"%>指定错误处理页面, 负责将由容器处理, 一般是直接显示异常信息和堆栈信息

  • JSP转译为Servlet时. 如果JSP页面中有一些错误的语法, 导致容器在转译是不知道怎样将那些语法转译成Servlet的 .java 文件, 就会发生错误. 比如: <%@ page buffer="16"%> 缺少单位.
  • Servlet源码编译时. 比如忘了引入JSP页面中用到的类文件
  • 运行时发生错误. 最常见的如 NullPointerException

9. EL表达式中属性的查找顺序: page --> request --> session --> application.

10. EL读取属性时

  • 如果使用点(.)运算符, 则左边可以是JavaBean 或 Map对象
  • 如果使用 [] 运算符, 则左边可以是 JavaBean, Map, 数组 或 List 对象

11. EL中有11个隐式对象, 其中除了 pageContext 隐式对象对应JSP的 PageContext 之外, 其他都是对应 Map 类型.

  • pageContext 对应 PageContext 类型, PageContext本身是个JavaBean, 只要是getXXX()方法, 就可以用 ${pageContext.xxx}来取得.
  • 属性范围相关隐式对象: 与属性范围相关的 EL 隐式对象有 pageScope, requestScope, sessionScope 和 applicationScope, 分别可以取得使用JSP隐式对象pageContext, request, session 和 application 的 setAttribute() 方法所设置的属性对象. 默认从 pageScope 开始查找. EL 隐式对象仅代表作用范围, 不等同于JSP内置对象.
  • 请求参数相关对象: 与请求参数相关的EL隐式对象有 param 与 paramValues. ${param.user} == <%= request.getParameter("user")%>    ${paramValues.favors[0]} == <%= request.getParameterValues("favors")[0]%> (可以获取窗口复选项的值)
  • 标头(Header)相关隐式对象: header 与 headerValues ,  ${header["User-Agent"]} == <%=request.getHeader("User-Agent")%>,  headerValues 等同于request.隔天Head二Values()方法.
  • cookie 隐式对象: 获取用户的Cookie设置值, ${cookie.name}
  • 初始参数隐式对象: initParam 可以用来获取web.xml中设置的 ServletContext 初始参数, 也就是在<context-param>中设置的初始参数.  ${initParam.initCount} == <%= request.getInitParameter("initCount")%>

12. EL 运算符: +,  -,  *,  /,  %或mod,  ?:,  and,  or,  not,  <或lt,  >或gt,  <=或le,  >=或ge,  ==或eq,  !=或ne

13. 自定义EL函数, 1)必须为public类, 2)调用的方法必须为public static 方法

 1 /**
 2  * 计算collection长度的EL自定义类
 3  *
 4  * @author kaitang.yi
 5  * @date 2013-8-1 下午4:46:41
 6  */
 7 public class Util {
 8     public static int length(Collection<?> coll) {
 9         return coll.size();
10     }
11 }

在WEB-INF目录下新建一个后缀为 .tld 的xml文件, 如: tonny.tld

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" 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-jsptaglibrary_2_1.xsd">
    
    <tlib-version>1.0</tlib-version>
    <short-name>tonny</short-name>
    <uri>http://tonny.cc/util</uri>
    <function>
        <description>Collection Length</description>
        <name>length</name>        <!-- 函数名 -->
        <function-class>tonny.study.el.Util</function-class>    <!-- 对应类 -->
        <function-signature>int length(java.util.Collection)</function-signature>    <!-- 对应到类的哪个方法 -->
    </function>
    
</taglib>

JSP页面引用

<%@ taglib prefix="util" uri="http://tonny.cc/util" %>
${util:length(requestScope.someList)}

参考:

《JSP&Servlet学习笔记(第二版)》

原文地址:https://www.cnblogs.com/ykt8465279130/p/3229241.html