说明:JSP很久就学过,但学了忘忘了学,很难受。因此这篇文章纯粹是为了记录一些学习笔记,以便后面复习,如有记录有误的地方,忘指出!
一、什么是JSP
JSP即java server pages,它是JavaWeb的动态资源。JSP = html + java脚本 + jsp动作标签(包含EL表达式)
1、JSP中java脚本
* <% ... %>:代码段,Java语句
* <%= ... %>:表达式,只是表达式!表达式的值会被输出到客户端(现在很少有,常用EL表达式来代替)
* <%! ... %>:定义,定义成员!例如例如成员变量,方法等(很少有,常用JSTL标签库的set标签)
2、JSP真身
* JSP也是Servlet
* JSP会在第一次被请求时编码成.java,再编码成.class文件,它其实就是一个Servlet,在处理请求时执行service()方法。
查看真身可以得到,jsp中有9个对象可以无需创建即可使用,它们就是jsp九大内置对象。
3、九大内置对象
补充:
JavaWeb三大组件:servlet、filter、listener
JSP四大作用域:page(pageContext)、request(HttpServletRequest)、session(HttpSession)、application(ServletContext)
Servlet三大作用域:request、session、application ↵
无需在jsp中声明即可使用的9个对象
* out(JspWriter):等同与response.getWriter(),用来向客户端发送文本数据;
* config(ServletConfig):对应“真身”中的ServletConfig;
* page(当前JSP的真身类型):当前JSP页面的“this”,即当前对象,引用为Object类型;
* pageContext(PageContext):页面上下文对象,它是最后一个没讲的域对象;
* exception(Throwable):只有在错误页面中可以使用这个对象;
* request(HttpServletRequest):即HttpServletRequest类的对象;
* response(HttpServletResponse):即HttpServletResponse类的对象;
* application(ServletContext):即ServletContext类的对象;
* session(HttpSession):即HttpSession类的对象,不是每个JSP页面中都可以使用,如果在某个JSP页面中设置<%@page session=”false”%>,说明这个页面不能使用session。
补充:
pageContext对象是PageContext类型
* 域对象:只在当前jsp页面中有效的域,通常用来让jsp与当前jsp中标签之间共享数据
* 获取其他8个内置对象:可以获取其他8个内置对象(调用get方法)
* 代理其他域对象:可以用pageContext来操作其他3个域。
4、JSP的三大指令(重要)
* page指令
* include指令
* taglib指令
1. page指令
常用属性:
* import:等同与import语句
--> <%@ page import="java.util.*" %>
--> <%@ page import="java.util.*, java.net.*" %>
--> 在一个JSP页面中可以给出多个page指令,而且import是可以重复出现的
<%@ page import="java.util.*" %>
<%@ page import="java.next.*" %>
* pageEncoding:指定当前页面的编码
--> 如果pageEncoding没有指定,那么默认为contentType的值;
--> 如果pageEncoding和contentType都没有指定,那么默认值为iso-8859-1
* contentType:等同与调用response.setContentType("text/html;charset=xxx");
--> 如果没有指定contentType属性,那么默认为pageEncoding的值;
--> 如果contentType和pageEncoding都没有指定,那么默认值为iso-8859-1
* errorPage:如果当前页面出现异常,那么跳转到errorPage指定的jsp页面。例如:<%@ page errorPage="a.jsp" %>
* isErrorPage:上面示例中指定a.jsp为错误页面,但在a.jsp中不能使用内置对象exception,保有a.jsp中使用<%@page isErrorPage="true"%>时,才能在a.jsp中使用错误页面。
* autoFlush:当autoFlush为true时,表示out流缓冲区满时会自动刷新。默认为true
* buffer:指定out流的缓冲区大小,默认为8KB
* isELIgnored:当前JSP页面是否忽略EL表达式,默认为false,表示不忽略,即支持EL表达式
不常用的属性:
* language:当前JSP编译后的语言!默认为java,当前也只能选择java
* info:当前JSP的说明信息
* isThreadSafe:当前JSP是否执行只能单线程访问,默认为false,表示支持并发访问
* session:当前页面是否可以使用session,默认为false,表示支持session的使用。
* extends:指定JSP真身的父类!
2、include指令
语法:<%@include file="页面"%> (静态包含),常用作抽取出JSP重复的片段
include指令的作用是包含指定的页面!在jsp被编译成java文件之前会把两个jsp文件合并,然后再编译成一个java文件。
注:请求转发的include是动态包含,它会编译成两个.java文件,两个.class文件
3、taglib指令
taglib指令是用来在当前jsp页面中导入第三方的标签库(常用JSTL标签库)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
prefix:指定标签前缀,这个东西可以随意起名()
uri:指定第三方标签库的uri(唯一标识)
5、JSP动作标签
JSP动作标签是用来替代一部分java脚本,使非java开发人员也可以向jsp中添加动态信息
常见动作标签:
<jsp:include>
例如:<jsp:include page="xxx"/>,用来包含指定的页面。
例如在a.jsp中存在如下内容:<jsp:include page="b.jsp"/>
a.jsp和b.jsp分别编码成Servlet,然后在执行Servlet时才会执行包含过程。这也是include指令与include标签的区别。
<jsp:forward>
例如:<jsp:forward page="xxx"/>,用来转发到指定页面
例如在a.jsp中存在如下内容:<jsp:fowrad page="b.jsp"/>
a.jsp中的内容不会显示在浏览器上,而只是显示b.jsp的内容。而且在<jsp:forwad>标签下面的内容不会被执行。
<jsp:param>
该标签是<jsp:include>和<jsp:forward>的子标签,用来向其他页面传递参数。
<jsp:include page="/b.jsp">
<jsp:param value="zhangSan" name="username"/>
</jsp:include>
在b.jsp中可以使用request.getParameter("username")来获取参数值。
二、EL表达式(非常重要)
语法:${..}
它是可以在JSP页面中直接使用的语言,常用来代替java脚本中的<%=...%>
例如:输出表达式的值:${1+2} 会在页面上输出3
判断数组,集合,数据等是否为空 ${empty ""} 返回true
EL一共11个内置对象
常用:
EL操作四大域的内置对象:它们是Map类型
pageScope
requestScope
sessionScope
applicationScope
${pageScope.user}:输出pageContext.getAttribute("user")
${requestScope.user}:输出request.getAttribute("user");
${sessionScope.user}:输出session.getAttribute("user");
${applicationScope.user}:输出application.getAttribute("user");
${user} (全域查找)
依次在pageScope、requestScope、sessionScope、applicationScope中查找user
如果查找到,那么立刻停止查找。
操作JavaBean
<%
User user = new User();
user.setUsername("zhangSan");
user.setPassword("123");
pageContext.setAttribute("user", user); //一定要先保存到域对象中,EL表达式中才能输出
%>
${pageScope.user.username}
${pageScope.user.password}
操作List
<%
User user = new User();
user.setUsername("zhangSan");
user.setPassword("123");
List list = new ArrayList();
list.add(user);
pageContext.setAttribute("list", list);
%>
${pageScope.list[0].username}
${pageScope.list[0].password}
操作Map
<%
User user = new User();
user.setUsername("zhangSan");
user.setPassword("123");
Map map = new HashMap();
map.put("u1", user);
pageContext.setAttribute("map", map);
%>
${pageScope.map.u1.username}
${pageScope.map.u1.password}
注:pageContext内置对象:PageContext类型 pageContext域可以获取JSP的其他8大域对象
${pageContext.request},等同pageContext.getRequest()
${pageContext.session},等同pageContext.getSession()
${pageContext.request.contextpath},获取项目名
${pageContext.session.id},获取sessionId
三、EL函数库
使用EL函数库需要在JSP页面中导入标签库:
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/function"%>
<%
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 -->
四、JSTL(JSP标准标签库) 重要
JSTL:JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL)
四大标签库:core(核心标签库)、fmt(格式化标签库)、sql(过时)、xml(过时)
core标签库:导入核心标签库<%taglib prefix="c" uri="http://java.sun.com/jstl/core"%>
常用标签:
<c:set> 标签:创建属性,赋值
* <c:set var="a" value="hello"/> 创建名为a,值为hello的域属性,默认范围:page域
* <c:set var="a" value="hello" scope="session"/> 范围为session域
<c:out>标签:输出,相当于java脚本中的<%=...%>
* <c:out value="aaa"/> 输出字符串aaa
* <c:out value="${aaa"/> 输出域属性aaa,其中与${aaa}相同
* <c:out value="${aaa}" default="xxx"/>如果${aaa}不存在,那么输出xxx字符串
* <c:out value="${aaa}" escapeXml="true"/>如果${aaa}中包含特殊字符,那么转义它。这可以防止javascript攻击
<c:remove>
* <c:remove var="a"/> 删除名为a的域属性
* <c:remove var="a" scope="page"/> 删除page域中名为a的域属性
<c:url> 可以获取项目名
* <c:url value="/AServlet"/> 输出URL:/项目名/AServlet
* <c:url value="/AServlet" var="url" scope="page"/> 把生成的url保存到page域中,而不会输出
* <c:url value="/AServlet">:输出URL:/项目名/AServlet?username=%xx%xx%xx%xx%xx%xx,其中张三会被URL编码
<c:param name="username" value="张三"/>
</c:url/>
<c:if>
* <c:if test="${条件}"> 当条件为true时执行标签体内容
hello
</c:if>
<c:choose> 相当于if...else
* <c:choose>
<c:when test="${条件1}">a</c:when>
<c:when test="${条件2}">b</c:when>
<c:when test="${条件3}">c</c:when>
<c:otherwise>d</c:otherwise>
</c:choose>
等同与:
if() {
} else if() {
} else if() {
} else if() {
} else {
}
<c:forEach>
可以用来遍历数组、List、Map、
1. 计数循环
<c:forEach begin="1" end="10" var="i">
${i}
</c:forEach>
等同于
for(int i = 1; i <= 10; i++) {
out.println(i);
}
<c:forEach begin="1" end="10" var="i" step="2">
${i}
</c:forEach>
等同于
for(int i = 1; i <= 10; i+=2) {
out.println(i);
}
-------------
2. 遍历数组
<%
String[] names = {"zhangSan", "liSi", "wangWu", "zhaoLiu"};
pageContext.setAttribute("ns", names);
%>
<c:forEach var="item " items="${ns } ">
<c:out value="name: ${item } "/><br/>
</c:forEach>
-------------
3. 遍历List
<%
List<String> names = new ArrayList<String>();
names.add("zhangSan");
names.add("liSi");
names.add("wangWu");
names.add("zhaoLiu");
pageContext.setAttribute("ns", names);
%>
<c:forEach var="item" items="${ns }">
<c:out value="name: ${item }"/><br/>
</c:forEach>
4. 遍历Map
<%
Map<String,String> stu = new LinkedHashMap<String,String>();
stu.put("number", "N_1001");
stu.put("name", "zhangSan");
stu.put("age", "23");
stu.put("sex", "male");
pageContext.setAttribute("stu", stu);
%>
<c:forEach var="item " items="${stu }">
<c:out value="${item.key }: ${item.value } "/><br/>
</c:forEach>
5. 循环状态对象
循环状态对象是用来说明循环的状态的,属性如下:
count:int类型,当前以遍历元素的个数;
index:int类型,当前元素的下标;
first:boolean类型,是否为第一个元素;
last:boolean类型,是否为最后一个元素;
current:Object类型,表示当前项目。
<c:forEach var="item" items="${ns }" varStatus="vs" >
<c:if test="${vs.first } ">第一行:</c:if>
<c:if test="${vs.last } ">最后一行:</c:if>
<c:out value="第${vs.count } 行: "/>
<c:out value="[${vs.index } ]: "/>
<c:out value="name: ${vs.current } "/><br/>
</c:forEach>
格式化标签库fmt:导入格式化标签库<%taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt"%>
常用的标签库:格式化时间、数字
<%
Date date = new Date();
pageContext.setAttribute("d", date);
%>
<fmt:formatDate value="${d }" pattern="yyyy-MM-dd HH:mm:ss "/>
----------------------------------------------------------------------------
<%
double d1 = 3.5;
double d2 = 4.4;
pageContext.setAttribute("d1", d1);
pageContext.setAttribute("d2", d2);
%>
<fmt:formatNumber value="${d1 }" pattern="0.00 "/><br/>
<fmt:formatNumber value="${d2 }" pattern="#.## "/>
* pattern:0.00,表示小数不足两位时,使用0补足两位
* pattern:#.##,表示小数不足两位时,有几位显示几位,不会补足