JSP
一、JSP概述
1、什么是JSP
Servlet和JSP都是由SUN公司提供的动态Web资源开发技术
JSP看起来像HTML,但是JSP中可以书写Java代码,可以展示动态的数据
JSP本质上就是一个Servlet!!
2、JSP的由来
Servlet本质上是一段JAVA程序,适合来处理用户提交的请求,但是处理的结果,不适合由Servlet向外输出(Servlet不适合向外输出一个完整的页面)
HTML是页面的开发技术,也是作为页面来展示数据,但是HTML本质上是一个文档,不能展示动态的数据。
JSP也是页面的开发技术,也可以作为页面来展示数据,并且JSP中可以书写Java代码,可以展示动态的数据
JSP的出现既解决了Servlet不适合向外输出完整页面的问题,也解决了HTML无法展示动态数据的问题。
JSP既可以当做一个Servlet使用,也可以当做HTML使用
3、修改JSP模板
《参考课件》
4、验证:JSP本质上是一个Servlet!
(1)HTML执行过程: 如果浏览器请求服务器, 请求的是一个HTML文件, 服务器会根据浏览器请求的资源路径, 找到对应的HTML文件, 将HTML文件(内容)响应给浏览器, 让浏览器去解析, 显示在窗口中
(2)JSP执行过程: 如果浏览器请求服务器, 请求的是一个JSP文件, 服务器会根据请求的资源路径找打对应的JSP, 先将JSP翻译成一个Servlet程序(java文件), 再编译Servlet程序, 最后执行Servlet程序, JSP中的所有的html代码都会通过Servlet程序原封不动的发送给浏览器.
二、JSP语法
1、模板元素(!)
模板元素其实就是书写在JSP中的html代码
或者说, 除了JSP特有的元素之外的其他内容都是模板元素
模板元素在翻译后的Servlet中, 是直接被out.write原样输出到浏览器中
2、JSP表达式
格式: <%= 常量/变量/表达式 %>
作用: 计算表达式的值, 再原样输出到当前位置!(表达式的主要作用就是用来输出用的!)
示例:
<%= "Hello JSP" %>
<% String name = "王海涛"; %>
<%= name %>
<%= 123+345 %>
3、JSP脚本片段
格式: <% 若干JAVA语句 %>
作用: 在翻译后的Servlet中, 其中的JAVA语句被直接复制粘贴到对应的位置执行!
示例:
<%-- 使用循环语句输出5遍"Hello JSP" --%>
<%
//脚本片段中只能书写符合Java语法的语句!!
for(int i=0;i<5;i++){
out.write("Hello JSP<br/>");
}
%>
<hr/>
<% for(int i=0;i<5;i++){ %>
Hello JSP<br/>
<% } %>
4、JSP注释
格式: <%-- 注释的内容 --%>
作用: (1)将暂时不需要执行的代码注释掉
(2)为代码添加注释(解释代码)
JSP注释不会参与翻译, 在翻译之前就直接被丢弃了!!
注意: 注释不能交叉嵌套
<!-- html注释内容 -->
/* Java代码注释 */
5、JSP指令(page指令!!)
JSP指令的作用是指挥JSP解析引擎如何来翻译JSP中的其他部分的内容
5.1.page指令
– 作用是用来声明当前JSP的基本属性信息(JSP使用的编码、JSP所依赖的jar包。)
(1)<%@ page language=“java”%>
了解, 指定当前JSP使用的开发语言是Java. (不指定也是Java语言, 所以可以省略不写!)
(2)<%@ page import=""%>
熟悉, 用来导入JSP在运行时所依赖的jar包, 示例:
<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Date"%>
(3)<%@ page errorPage=""%>
-- 当前JSP在运行时如果抛出了异常, 将会跳转到errorPage所指定的友好错误提示页面
比如: 在02.jsp中添加errorPage属性如下:
<%@ page errorPage="/err_page.jsp"%>
当02.jsp页面在运行时抛出了异常, 将会跳转到err_page.jsp这个友好错误提示页面. 而不是给用户显示500错误页面.
如果整个Web应用的Servlet和JSP都需要配置友好错误提示页面, 可以在web.xml文件中, 为整个Web应用进行配置!!
(4)<%@ page pageEncoding="utf-8"%>
只要保证pageEncoding属性指定的编码和jsp文件保存时使用的编码一致, 就可以防止JSP文件的乱码问题!
(如果是在JSP中获取请求参数, 这里仍然需要按照之前的方式来处理!)
5.2.include指令
– 用于JSP页面的包含效果
<%@include file=“所包含JSP文件的路径” %>
示例:
<!-- 将头部包含进来 -->
<%@include file="/include/_header.jsp" %>
<h1 style="text-align:center;height:300px;background:red">
购物车页面的主体
</h1>
<!-- 将尾部包含进来 -->
<%@include file="/include/_footer.jsp" %>
5.3.taglib指令
– 用于引入JSTL标签库
后面会讲解和使用JSTL标签库(c:set、c:if、c:forEach)
如果在当前JSP中需要使用JSTL标签库中的标签, 使用之前必须通过taglib指令先引入JSTL标签库, 否则将会不起作用!
三、JSP九大隐式对象(了解)
1、九大隐式对象 – 在JSP中, 不用事先声明, 也不用获取, 直接可以使用的九个对象
page 相当于Servlet中的this
request HttpServletRequest
response HttpServletResponse
config ServletConfig
application ServletContext
session HttpSession
exception Exception
out JspWriter相当于response.getWriter()
pageContext PageContext
2、pageContext对象
2.1.可以作为入口对象来获取其他八大隐式对象
pageContext.getRequest();
pageContext.getResponse();
pageContext.getSession();
pageContext.getConfig();
…
…
在Servlet中获取当前Web应用的虚拟路径:
request.getContextPath() /day17
在JSP中获取当前Web应用的虚拟路径:
<%= request.getContextPath() %>
${ pageContext.request.contextPath }
2.2.pageContext可以作为域对象使用
生命周期:
访问JSP开始时创建pageContext对象
访问JSP结束时销毁pageContext对象
作用范围: 仅仅当前JSP范围内
主要功能: 在当前JSP范围内实现资源的共享
四大作用域范围: ServletContext > Session > Request > pageContext
四、JSP标签技术!!!
在JSP页面中写入大量的java代码会导致JSP页面中html代码和java代码混杂在一起,会造成页面非常的混乱,难于维护
于是在JSP的2.0版本中,sun提出了JSP标签技术,推荐使用标签来代替JSP页面中java代码,并且推荐,JSP2.0以后不要在JSP页面中出现任何一行java代码。
1、EL表达式 – 主要用来(从域中)获取数据
1.1.获取常量/变量(必须先存入域中)/表达式的值
1.获取常量、变量(先存入域中)、表达式的值
${ “Hello EL” }
${ 123+456 }
<br/>
<%= "Hello EL" %>
<%= 123+456 %>
<hr/>
<% String name = "赵云"; %>
<%= name %>
<%-- 上面通过JSP表达式获取name, 是在当前JSP运行环境
中获取名称为name的变量的值 --%>
<%
request.setAttribute("name", "request张飞");
session.setAttribute("name", "session张飞");
%>
${ name }
<%-- 通过EL获取name, 是在四大域中寻找名称为name的属性
值, 如果找到就返回name属性的值, 如果找不到就什么
也不输出!!
在寻找时, 是按照从小到大的顺序到四大域中寻找指定
名称的属性值!!
--%>
1.2.获取域中数组或集合中的数据
2.获取域中数组或集合中的数据
<%
String[] names =
{ “王海涛”, “齐雷”, “陈子枢”, “刘沛霞” };
request.setAttribute(“names”, names);
%>
${ names[0] }
${ names[1] }
${ names[2] }
${ names[3] }
1.3.获取域中map集合中的数据
3.获取域中map集合中的数据
<%
Map map = new HashMap();
map.put(“name”, “刘德华”);
map.put(“age”, 18);
map.put(“nickname”, “Andy”);
request.setAttribute("map", map);
%>
${ map.name }
${ map.age }
${ map.nickname }
${ map["name"] }
2、JSTL标签库(c:forEach)
!!!注意: 在使用JSTL标签库之前, 需要注意两点:
(1)先导入JSTL标签库的jar包
(2)在使用JSTL标签的JSP页面中通过taglib指令先引入标签库, 才能使用!!
2.1.c:set标签
(1)往域中添加一个域属性
<c:set var=“name” value=“张三丰” scope=“request”/>
${ name }
(2)修改域中已有的域属性
<c:set var="name" value="张无忌" scope="request"/>
${ name }
(3)修改域中map集合中的元素
<%
Map map = new HashMap();
map.put("name", "刘德华");
map.put("age", 18);
map.put("nickname", "Andy");
request.setAttribute("map", map);
%>
修改前:
${ map.name }
${ map.age }
${ map.nickname }
<hr/>
<c:set target="${map}" property="name" value="阿凡达"/>
<c:set target="${map}" property="nickname" value="小达达"/>
修改后:
${ map.name }
${ map.age }
${ map.nickname }
2.2.c:if标签
2、c:if标签
<c:if test=" 3 > 5 " > y e s < / c : i f > < c : i f t e s t = " { 3>5 }">yes</c:if> <c:if test=" 3>5">yes</c:if><c:iftest="{ !(3>5) }">no</c:if>
<!-- 模拟判断用户是否登录 -->
<%
session.setAttribute("user", "张三");
session.removeAttribute("user");
%>
<c:if test="${ user == null }">
<a href="#">您好, 请登录...</a>
</c:if>
<c:if test="${ user != null }">
欢迎, ${ user } 回来...
</c:if>
2.3.c:forEach标签
(1)遍历域中的数组或集合中的元素
<%
List list = new ArrayList();
list.add(“张三”);
list.add(“李四”);
list.add(“王五”);
list.add(“刘能”);
request.setAttribute(“list”, list);
for(Object o : list){
System.out.println(o);
}
%>
<c:forEach items="${list}" var="o">
${ o }<br/>
</c:forEach>
(2)遍历域中的map集合中的元素
<%
Map<Object, Object> map = new HashMap();
map.put(“name”, “刘德华”);
map.put(“age”, 18);
map.put(“nickname”, “Andy”);
request.setAttribute(“map”, map);
for(Map.Entry<Object,Object> e : map.entrySet()){
System.out.print(e.getKey() + " : ");
System.out.println(e.getValue());
}
%>
<c:forEach items="${map}" var="entry">
${ entry.key } : ${ entry.value } <br/>
</c:forEach>
(3)打印1-100之间的数, 使用逗号分隔
<%
for(int i=1;i<=100;i++){}
%>
<c:forEach begin=“1” end=“100” var=“i”>
${ i },
</c:forEach>
(4)打印1-100之间的奇数, 使用逗号分隔, 将位置是3的倍数的数值设置颜色为红色
<c:forEach begin=“1” end=“100” var=“i” step=“2”>
${ i },
</c:forEach>
<hr/>
<c:forEach begin="1" end="100" var="i"
varStatus="status" step="2">
<span
<c:if test="${ status.count%3 == 0 }">
style="color:red"
</c:if>
>${ i }<c:if test="${ !status.last }">,</c:if>
</span>
</c:forEach>
<!--
varStatus="status" 用于指定表示循环状态信息的对象, 通过
该对象, 可以获取如下内容:
first -- Boolean, 当前被遍历的元素是否是第一个
last -- Boolean, 当前被遍历的元素是否是最后一个
count -- 数值, 表示当前被遍历的元素是第几个
index -- 索引, 表示当前被遍历的元素的索引值(索引值+i的值)
-->