JSP出现的原因是因为在Servlet中编写HTML代码太费事,所以才出现了JSP技术,JSP最终是要被编译成Servlet才能处理用户请求,因此JSP拥有Servlet的所有功能和特性。
重写jsp方法
<%! /* 全局变量 */ Properties properties = new Properties(); /* 重写init方法 */ public void jspInit() { } /* 重写destory方法 */ public void jspDestroy() } /* 声明其他方法 */ public void hello() { } %>
指令标签
指令标签不会产生任何内容输出到网页中,主要是用于定义整个JSP页面的相关信息。
page指令
page指令用于定义整个JSP页面的相关属性,这些属性在JSP被服务器解析成Sevlet时会被转换为相应的Java程序代码。page指令共15个。
语法规则
<%@ page attr1="value1" attr2="value2" %>
常用
language属性
定义JSP页面所用的脚本语言,默认是Java
extends属性
指定servlet从哪一个类继承
import属性
导入要使用的Java类
contentType属性
指定当前JSP页面的MIME类型和字符编码(对于浏览器)
pageEncoding属性
JSP页面编码格式(对于文件)
session属性
指定JSP页面是否使用session
buffer属性
指定out对象使用缓冲区的大小
autoFlush属性
控制out对象的 缓存区
info属性
定义JSP页面的描述信息
isErrorPage属性
指定当前页面是否可以作为另一个JSP页面的错误处理页面
errorPage属性
指定当JSP页面发生异常时需要转向的错误处理页面
isELIgnore属性
指定当前页面是否可以作为另一个JSP页面的错误处理页面
isThreadSafe属性
指定对JSP页面的访问是否为线程安全
isScriptingEnabled属性
确定脚本元素能否被使用
include指令
包含其他文件。
语法规则
<%@ include file="" %>
taglib指令
引入标签库的定义。
语法规则
<%@ taglib prefix="fix" uri="dir" %>
动作标签
常用
jsp:include
<jsp:include page="date.jsp" />
它与指令标签里的include区别在于:首先他俩都会被转换为ServletA,在ServletA里的不同点在于指令include是将data.jsp中代码嵌入ServletA中,而动作include是将data.jsp转换为ServletB后,该ServletB相应的结果嵌入ServletA中。
jsp:forward
jsp:forward page="/charter2/fighting/cookie/login.jsp" />
请求转发标签,是我在JSP中遇到的第一个坑,在写session的时候,我是在WebContent下的index.jsp里使用了该标签,将请求转发给charter2/fighting/cookie/login.jsp,导致的问题就是我即使在登陆成功后保存了cookie,但是再次访问http://localhost:8080/JavaWebPartice时,表单仍旧没有记住我的账号密码。原因就在于这个标签是后台转发,也就是将请求index.jsp的这个request对象转发到后台,这个request对象里并没有登陆的cookie信息,真正的cookie信息存储在http://localhost:8080/JavaWebPartice/charter2/fighting/cookie/login.jsp里,只有访问这个地址,我保存的cookie再次访问时才能显示出来。也就是说我应该在index.jsp里使用重定向而不是请求转发。
注意:不应该使用动作标签forward将请求转发到登录页,因为这是后台转发。浏览器记录的该地址里并不会有cookie信息,因为转发到的登路页的request对象是index.jsp的request。所以应该在index.jsp里使用重定向的方式,重定向到login.jsp。
jsp:param
<jsp:forward page="login.jsp"> <jsp:param value="userName" name="ming"/> </jsp:forward>
可以为其他标签传递参数
jsp:useBean
<jsp:useBean id="bean" class="com.bjs.Book" />
以上代码表示在JSP中创建一个Book对象。
EL表达式
开启
默认情况下,JSP页面中的EL表达式是被禁用的,如果要启用EL表达式,可以在每个jsp页面的顶部设置:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%>
在整个项目中都允许使用EL的话,可以在web.xml里设置
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <el-ignored>false</el-ignored> </jsp-property-group> </jsp-config> </web-app>
只有在xsd以下配置el-ignored才有效,所有这里要切换一下校验版本。我在想是不是后期不在使用JSP作为展示页面的时候,也就不需要jstl和el表达式了,所以dtd就不在支持这些了?。
四大作用范围
切记EL表达式只能获取:
pageScope-----
requestScope
sessionScope
applicationScope
// 使用拿到cookie里的某个值:cookie.key.value <c:out value="${cookie.username.value }"></c:out> // 拿到page、rquest、session、application里的值,直接使用**Scope.key <c:out value="${requestScope.username }"></c:out>
cookie是一个对象,而**Scope是一个map集合,直接拿即可,不需要在使用.value了。
JSTL核心标签库
引入
maven下载javax.servlet.jsp.jstl标签库并deploy到项目里,并在jsp页面中引入
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
就可以在jsp页面中使用jstl核心库了。
JSTL中scope和ELl中scope
<body> <%! String username1 = "吉吉1"; %> <% /* page没有setAttribute属性!pageScope也拿不到ji属性 */ String username2 = "吉吉2"; request.setAttribute("mao", "毛毛"); session.setAttribute("ke", "可可"); application.setAttribute("mi", "咪咪"); %> <c:set var="data1" value="1111"></c:set><!-- 没设置,默认scope=page --> <c:set var="data2" value="2222" scope="page"></c:set> <c:set var="data3" value="3333" scope="request"></c:set> <c:set var="data4" value="4444" scope="session"></c:set> <c:set var="data5" value="5555" scope="application"></c:set> ==<c:out value="pageScope只能拿到当前页面使用set(包含jsp:setProperty等等)标签设置的值(未指定scope或指定为page):" ></c:out><br> ==<c:out value="${data1 }" ></c:out></br><!-- 没指定查找范围,默认开始从page->application四个范围内依次查找 --> <!-- 输出:1111 --> ==<c:out value="${pageScope.data1 }" ></c:out></br> <!-- 输出:1111 --> ==<c:out value="${pageScope.data2 }" ></c:out></br> <!-- 输出:2222 --> ==<c:out value="${requestScope.data1 }" ></c:out></br> <!-- 无输出 --> ==<c:out value="${sessionScope.data1 }" ></c:out></br> <!-- 无输出 --> ==<c:out value="${applicationScope.data1 }" ></c:out></br> <!-- 无输出 --> ==<c:out value="${username1 }" ></c:out></br> <!-- 无输出 --> ==<c:out value="${pageScope.username1 }" ></c:out></br> <!-- 无输出 --> ==<c:out value="${username2 }" ></c:out></br> <!-- 无输出 --> ==<c:out value="${pageScope.username2 }" ></c:out></br> <!-- 无输出 --> <%-- ==<c:out value="${pageContext.page.username1 }" ></c:out></br> --%><!-- 报错 --> =============================================================</br> ==<c:out value="param(获取单值)或paramValues(获取多值集合)" ></c:out><br> ==<c:out value="${param }" ></c:out></br> <!-- 输出:{} --> ==<c:out value="${paramValues }" ></c:out></br> <!-- 输出:{} --> =============================================================</br> ==<c:out value="requestScope能拿到request中设置的值或set标签中scope为request中的值" ></c:out></br> ==<c:out value="${requestScope.data1 }" ></c:out></br> <!-- 无输出 --> ==<c:out value="${requestScope.data2 }" ></c:out></br> <!-- 无输出 --> ==<c:out value="${requestScope.data3 }" ></c:out></br> <!-- 输出:3333 --> ==<c:out value="${requestScope.mao }" ></c:out></br> <!-- 输出:毛毛 --> =============================================================</br> ==<c:out value="sessionScope能拿到request中设置的值或set标签中scope为request中的值" ></c:out></br> ==<c:out value="${sessionScope.data4 }" ></c:out></br> <!-- 输出:4444 --> ==<c:out value="${sessionScope.ke }" ></c:out></br> <!-- 输出:可可 --> =============================================================</br> </body>
JSTL常用标签
设置、移除、输出标签
<c:set var="name" value="maomao"></c:set> ==<c:out value="${name }"></c:out><br> <!-- maomao --> <c:remove var="name"/> ==<c:out value="${name }"></c:out><br> <!-- -->
异常标签:catch
<c:catch var="e"> <% int num = 100 / 0; %> </c:catch> <c:out value="${e }"></c:out>
条件标签:if、choose、when、otherwise
<c:set var="isNew" value="true"></c:set> <c:set var="isLong" value="true"></c:set> <!-- 使用if --> <c:if test="isNew"> <c:out value="是新的"></c:out> </c:if> <!-- 实现if else if else --> <c:choose> <c:when test="${isNew }"> <c:out value="是新的"></c:out> </c:when> <c:when test="${isLong }"> <c:out value="是长的"></c:out> </c:when> <c:otherwise> <c:out value="是又旧又短的"></c:out> </c:otherwise> </c:choose>
循环标签:foreach、forTokens
<% String[] users1 = {"毛毛","可可","吉吉","熊大","熊二"}; request.setAttribute("users1", users1); String users2 = "毛毛&可可,吉吉&熊大#熊二"; request.setAttribute("users2", users2); %> <c:forEach items="${requestScope.users1 }" var="user" varStatus="id"> ${user } </c:forEach> ===================遍历使用给定字符分割字符串后的数组======================== <c:forTokens items="${requestScope.users2 }" delims="&,#" var="user"> ${user } </c:forTokens>
URL操作标签
c:import
该标签可以导入站内或其他网站的静态或动态文件到web项目中,而jsp:include只能导入站内资源。
<!-- 可导入站内/站外的动态/静态文件 --> <c:import url="el_catch.jsp"></c:import> <c:import url="http://m.weather.com.cn/m/p5/weather1.htm" charEncoding="UTF-8"></c:import>
c:url
<!-- 生成URL地址标签 --> <c:url value="el_catch.jsp;JESESSIONID=456" var="url"> <c:param name="user" value="123"></c:param> </c:url> <a href="${url }">提交</a> <!-- http://localhost:8080/JavaWebPartice/charter6/el_catch.jsp;JESESSIONID=456?user=123 -->
c:redirect
<!-- 生成URL地址标签 --> <c:url value="el_catch.jsp;JESESSIONID=456" var="url"> <c:param name="user" value="123"></c:param> </c:url> <a href="${url }">提交</a> <!-- http://localhost:8080/JavaWebPartice/charter6/el_catch.jsp;JESESSIONID=456?user=123 --> <!-- 重定向 --> <%-- <c:redirect url="/charter5/model2/goodsForm.jsp"></c:redirect> --%> <c:redirect url="${url }"></c:redirect>
c:param
只用于为其他标签提供参数信息,它与<c:import>、<c:redirect>、<c:url>标签组合可以实现动态定制参数。
<c:param name="paramName" value="paramValue"></c:param>
接下来要读
MVC发展线