- JSP的执行过程:
* JSP会被翻译成Servlet,编译成class进行执行的.
- JSP的嵌入Java代码:JSP的脚本元素
* <%! %> :翻译成类中的成员部分. 定义变量,定义方法,定义类.Servlet是线程不安全的,尽量少在类中定义成员属性!!
* <% %> :翻译成类的service方法内部的内容. 定义变量,定义类,直接写代码块.
* <%= %> :翻译成service方法内部的out.print();
eclipse 创建一个JSP文件
发现eclipse 创建的JSP文件是 iso-8859-1的编码格式
修改jsp默认的编码格式:
之后再次创建的jsp文件就是UTF-8编码格式的
【JSP的指令】
- 指令的语法:
<%@ 指令名称 属性名称=”属性值” 属性名称=”属性值” ...%>
- JSP中有三个指令:page指令, include指令, taglib指令.
-
JSP中page指令:<%@ page %> -- 设置JSP的.
* language :JSP脚本中使用的语言.现在只能写java.
* contentType :设置浏览器打开这个JSP的时候采用的默认的字符集的编码.
* pageEncoding :设置文件保存到本地硬盘,以及生成Servlet后,Servlet保存到硬盘上的编码.
* import :在JSP中引入类对象.但是import可以出现多次.
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
* extends :设置JSP翻译成Servlet后继承的类,默认值:org.apache.jasper.runtime.HttpJspBase,这个值要想修改,这个类必须是HttpServlet的子类
* autoFlush :设置JSP的缓存自动刷出.true:自动刷出.
* buffer :设置JSP的缓冲区的大小,默认8kb.
* session :设置在JSP中是否可以直接使用session对象.默认值是true.
* isELIgnored :设置在JSP中是否忽略EL表达式.默认值是false不忽略.
* errorPage :设置错误友好页面的提示. <错误页面的路径,注意,不需要工程名>
* isErrorPage :通过这个设置显示JSP的错误信息.<true:可以在错误页面显示详细错误信息,默认为false>
<%= exception.getMessage() %>
* 设置全局的错误友好页面:
* 在web.xml中设置:(一般工程上使用这种方法)
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>
-
JSP中的include指令:指示JSP包含其他的页面.(静态包含)
<%@ include file="logo.jsp" %>
<%@ include file="menu.jsp" %>
<h1>BODY部分</h1>
<%@ include file="footer.jsp" %>
-
JSP中的taglib指令:指示JSP引入标签库.
<%@ taglib uri="标签的URI的路径" prefix="标签的别名" %>
【JSP的内置对象】
- JSP的内置对象:在JSP中可以直接使用的对象.
- JSP中有9大内置对象:
* request HttpServletRequest getParameter(),setAttribute(String name,Object value);
* response HttpServletResponse setHeader(String name,String value);getOutputStream();getWriter();
* session HttpSession setAttribute();getAttribute();
* application ServletContext setAttribute();getAttribute();
* page Object toString();wait();
* pageContext PageContext setAttribute();getAttribute();
* config ServletConfig getServletName();getServletContext();
* out JspWriter write(),print();
* exception Throwable getMessage(),getCause(); 设置isErrorPage=”true”
- page内置对象 :真实对象是Object,就是JSP翻译成Servlet后的类的引用.
- out内置对象 :out和response.getWriter是不是同一个对象?区别是什么?
* 不是out真实对象JspWriter ,response获得Writer是PrintWriter.
Out对象与Response对象输出原理分析:
-
pageContext内置对象 :
pageContext对象的功能:
获得其他的8个内置对象 : <编写通用性代码或者框架的时候.>
向JSP的四个域中存取数据;
* 向JSP的四个域中存取数据 :
JSP的四个域范围:
* PageScope :当前页面中有效. pageContext PageContext
* RequestScope :一次请求范围. request HttpServletRequest
* SessionScope :一次会话范围. session HttpSession
* ApplicationScope :应用范围 application ServletContext
【在Servlet中如何获取这四个域对象】
* PageContext :
JspFactory fac = JspFactory.getDefaultFactory();
PageContext pageContext = fac.getPageContext(this, request,response, null,false,JspWriter.DEFAULT_BUFFER,true);
* HttpServletRequest
Servlet中默认就有;
* HttpSession
HttpSession session = request.getSession();
* ServletContext
ServletContext servletContext = request.getServletContext();
ServletContext servletContext = this.getServletContext();
注意:pageContext 可以向这四个域中存放数据(因为pageContext可以获取其它8个内置对象)
【JSP的动作标签】列出6个.
- 标签的作用:简化代码.
- <jsp:forward /> :用于页面的转发.
* <jsp:forward page="/demo1-jsp/demo3-object/demo3.jsp"></jsp:forward>
- <jsp:include /> :用于页面的包含.(动态包含)
*****静态包含和动态包含的区别?(<%@ include%>和<jsp:include>)
- <jsp:param /> :用于带有路径的标签下,传递参数.
- <jsp:useBean /> :用于在JSP中使用JavaBean.
- <jsp:setProperty /> :用于在JSP中向JavaBean设置属性的.
- <jsp:getProperty /> :用于在JSP中获得JavaBean的属性.
EL表达式:
【EL的概述】
- 为什么学习EL:
* 简化JSP的代码,而且减少<%%>
- 使用EL表达式:
* 语法:${ EL表达式 }
- EL的功能:
* 获取数据:(JSP的四个域)
* 执行运算:
* 操作WEB开发的常用的对象:
* 调用Java中方法:--很少用.
【EL获取数据】
<h3>存取是普通的单值数据</h3>
<%
pageContext.setAttribute("name", "pValue");
request.setAttribute("name", "rValue");
session.setAttribute("name", "sValue");
application.setAttribute("name", "aValue");
%>
<%=pageContext.getAttribute("name") %> <!-- 如果没找到 返回null -->
<%=request.getAttribute("name") %><!-- 如果没找到 返回null -->
<%=session.getAttribute("name") %><!-- 如果没找到 返回null -->
<%=application.getAttribute("name") %><!-- 如果没找到 返回null -->
<hr/>
<!-- 使用EL表达式获取-->
${ pageScope.name } <!-- 返回的是"" -->
${ requestScope.name }<!-- 返回的是"" -->
${ sessionScope.name }<!-- 返回的是"" -->
${ applicationScope.name }<!-- 返回的是"" -->
<hr/>
间接方法:
${ name } <!-- 类似findAttribute("name") 先从page域中查找,没找到去request域中查询,没有找到去session域中找,没有找到就去application域中找 -->
<h3>获取数组的数据</h3>
<%
String[] arrs = {"李旭华","李冠希","杨凤","杨如花"};
pageContext.setAttribute("arrs", arrs);
%>
${ arrs[0] }
${ arrs[1] }
${ arrs[2] }
${ arrs[3] }
<h3>获取List集合的数据</h3>
<%
List<String> list = new ArrayList<String>();
list.add("李芙蓉");
list.add("杨芙蓉");
list.add("王凤");
pageContext.setAttribute("list", list);
%>
${ list[0] }
${ list[1] }
${ list[2] }
<h3>获取Map集合的数据</h3>
<%
Map<String,String> map = new HashMap<String,String>();
map.put("aaa","李旭华");
map.put("bbb","杨久君");
map.put("ccc","李芮");
map.put("ddd","李凤");
pageContext.setAttribute("map", map);
%>
<!-- 注意: map 的key 不能以数字开头 如果 ${map.111} 就会报错-->
${ map.aaa }
${ map.bbb }
${ map.ccc }
${ map.ddd }
<h3>获取对象的数据</h3>
<%
User user = new User(1,"aaa","123");
pageContext.setAttribute("user", user);
%>
${ user.id }
${ user.username }
${ user.password }
<h2>获取map中的对象</h2>
<%
Map map = new HashMap<String,User>();
User user1 = new User();
user1.setName("Tom1");
user1.setPassword("111");
map.put("a111",user1);
User user2 = new User();
user2.setName("Tom2");
user2.setPassword("222");
map.put("b222",user2);
pageContext.setAttribute("map", map);
%>
${ map.a111.name } - ${ map.a111.password }
${ map.b222.name } - ${ map.b222.password }
<h3>获取对象的集合的数据</h3>
<%
User user1 = new User(1,"aaa","123");
User user2 = new User(2,"bbb","123");
User user3 = new User(3,"ccc","123");
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
userList.add(user3);
pageContext.setAttribute("userList", userList);
%>
${ userList[0].id } - ${ userList[0].username } - ${ userList[0].password }<br/>
${ userList[1].id } - ${ userList[1].username } - ${ userList[1].password }<br/>
${ userList[2].id } - ${ userList[2].username } - ${ userList[2].password }<br/>
***** .和[]的区别.
* []用于有下标的数据(数组,list集合) .用于有属性的数据(map,对象)
* 如果属性名中包含有特殊的字符.必须使用[] ${ header["User-Agent"] }
【EL执行运算】
<h3>EL执行算数运算</h3>
<%
pageContext.setAttribute("n1", "10");
pageContext.setAttribute("n2", "20");
pageContext.setAttribute("n3", "30");
pageContext.setAttribute("n4", "40");
%>
${ n1 + n2 + n3 }
<h3>EL执行逻辑运算</h3>
${ n1 < n2 } - ${ n1 lt n2 } <!-- less than --><br/>
${ n1 > n2 } - ${ n1 gt n2 } <!-- great than --><br/>
${ n1 <= n2 } - ${ n1 le n2 } <!-- less equal --><br/>
${ n1 >= n2 } - ${ n1 ge n2 } <!-- great equal --><br/>
${ n1 == n2 } - ${ n1 eq n2 } <!-- equal --><br/>
<h3>EL执行关系运算</h3>
${ n1<n2 && n3 < n4 } - ${ n1<n2 and n3 < n4 }<br/>
${ n1<n2 || n3 < n4 } - ${ n1<n2 or n3 < n4 }<br/>
${ !(n1 < n2) } - ${ not(n1<n2) }
<h3>EL执行三元运算</h3>
${ n1 < n2 ? "正确":"错误" }
<h3>empty运算</h3>
${ user == null } - ${ empty user }
${ user != null } - ${ not empty user }
【EL操作WEB开发的常用对象11个】
<!--
pageScope,requestScope,sessionScope,applicationScope - 获取JSP中域中的数据
param,paramValues - 接收参数.
例如:从jsp1跳到jsp2 有带参数 http://localhost/day11_web/visit/jsp2.jsp?id=111&name=Tom
获取这个参数的时候就可以使用:
${ param.id }
${ param.name }
header,headerValues - 获取请求头信息
initParam - 获取全局初始化参数 (web.xml 中的全局初始化参数)
cookie - WEB开发中cookie
pageContext - WEB开发中的pageContext.
-->
<h3>接收请求的参数</h3>
例如: http://localhost:8080/day11_web/visit/jsp2.jsp?id=18&name=Tom&hobby=basketball&hobby=football
<%= request.getParameter("id") %>
<%= request.getParameter("name") %>
<%= Arrays.toString(request.getParameterValues("hobby")) %>
<hr/>
${ param.id }
${ param.name }
${ paramValues.hobby[0] }
${ paramValues.hobby[1] }
<h3>获取请求头</h3>
<%= request.getHeader("User-Agent") %>
<hr/>
${ header["User-Agent"] }
<h3>获取全局初始化参数</h3>
${ initParam.username }
<h3>获取Cookie中的值</h3>
${ cookie.history.value }
<h3>获取PageContext中的对象</h3>
客户机的IP地址:${ pageContext.request.remoteAddr }
工程路径:${ pageContext.request.contextPath }
<h3>EL表达式嵌套问题</h3>
<c:set var="str" value="a-b-c-d-e-f-g" scope="page"></c:set>
<c:forEach var="i" items="${fn:split(str,'-') }"> // 正确, EL表达式需要嵌套的时候,内层的不用¥
${i }
</c:forEach>
<c:forEach var="i" items="${fn:split(${str},'-') }"> // 不正确, EL表达式需要嵌套的时候,内层的不用${}
${i }
</c:forEach>
【JSTL的概述】
-
为什么学习JSTL:
* JSTL和EL结合 替换页面中<%%>
-
JSTL的标签库:包含了五类标签.
* core(核心标签),fmt(国际化标签),xml(XML标签),sql(SQL标签),fn(JSTL提供EL函数库)
- 使用JSTL:
* 引入JSTL的相关的jar包.
* 在页面中引入标签库.<%@ taglib uri=”” prefix=””%>
【JSTL的核心标签的用法】
详细文档下载地址:https://download.csdn.net/download/tanghui20/11003929
* set // 往域里面存变量
<c:set var="n1" value="10" scope="page"></c:set>
<c:set var="n2" value="20" scope="page"></c:set>
var – 变量名称 value – 变量值 scope – 哪个域(page|request|session|application)
*out
<c:out value="${n3}" default="40"></c:out> // 如果n3为空,就输出默认值40 相当于 ${empty n3 ? "40":n3 }
<c:out value="<h1>标题一</h1>" escapeXml="false"></c:out> // 是否需要转译
* if //
注意:
1- jstl if 中没有else
2- if中 test="${}" $与"直接不能有空格; 如: test=" ${} " 这样就不能正常判断;
用法一:
<c:if test="${n1 < n2 }">
n1小于n2
</c:if>
用法二:
<c:if test="${n1 < n2 }" var="flag" scope="page"> //var 表示: 将test中计算出来的值存在flag 中,并保存在page域中
n1小于n2
</c:if>
${flag }
* forEach
<%
String[] arrs = {"Tom1","Tom2","Tom3"};
pageContext.setAttribute("arrs", arrs);
List list = new ArrayList();
list.add("Tom1");
list.add("Tom2");
list.add("Tom3");
pageContext.setAttribute("list", list);
Map map = new LinkedHashMap();
map.put("aaa", "Tom1");
map.put("bbb", "Tom2");
map.put("ccc", "Tom3");
pageContext.setAttribute("map", map);
%>
</br>
<h3>遍历数组</h3>
<c:forEach var="i" items="${arrs }">
${i }
</c:forEach>
</br>
<h3>遍历集合</h3>
<c:forEach var = "i" items="${list }">
${i }
</c:forEach>
</br>
<h3>遍历map</h3>
<c:forEach var="entry" items="${map }">
${entry.key }
${entry.value }
</br>
</c:forEach>
</br>
<c:forEach var="i" begin="1" end="10" step="2">
${i}
</c:forEach>
<h3>遍历1-100</h3>
<!-- step 表示:每次加几 ; varStatus 表示第几个;用status.count -->
<c:forEach var="i" begin="0" end="100" step="5" varStatus="status">
<c:if test="${status.count%3 == 0 }">
<font color="red">${i }</font>
</c:if>
<c:if test="${status.count%3 != 0 }">
${i }
</c:if>
</c:forEach>
【JSTL的提供EL的函数库】