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 , include 和 taglib.
- page 指示类型告诉容器如何转译当前的JSP页面
<%@ page language="java" import="java.util.Date"%>
- include 指示类型告知容器将别的JSP页面包括进来进行转译.
<%@ include file="top.jsp" %>
与<jsp:include page="top.jsp">的区别 执行时间上: |
- 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学习笔记(第二版)》