JSP概述
什么是JSP
JSP和Servlet都是由SUN公司提供的动态Web资源开发技术。
JSP看起来像一个HTML,但和HTML不同的是,JSP中可以书写Java代码,可以通过Java代码展示动态的数据。
静态Web资源:任何人在任何条件下访问时,看到的都是相同的效果,这样的资源叫做静态Web资源。(html、css、js等)
动态Web资源:不同的人,在不同的条件下访问时,看到的都是不同的效果,这样的资源叫做动态Web资源。(Servlet、jsp、php、.NET等)
JSP本质上是一个Servlet程序
思考1:为什么要学习JSP?
- Servlet是一段Java程序,适合处理业务逻辑,但是Servlet不适合向浏览器输出一个html网页。
- html可以作为页面返回,但是html是一个静态Web资源,无法展示动态数据。
- 而JSP也是页面的开发技术,也可以作为页面返回,并且JSP中可以书写Java代码,可以通过Java代码展示动态的数据。
- 因此,JSP的出现即解决了Servlet不适合输出页面的问题,也解决了HTML无法展示动态数据的问题!
思考2:为什么说JSP本质是一个Servlet?
在JSP第一次被访问时,会翻译成一个Servlet程序。访问JSP后看到的html网页,其实是翻译后的Servlet执行的结果。(也就是说,访问JSP后看到的网页,是JSP翻译后的Servlet输出到浏览器的。)
JSP执行过程
访问服务器中的JSP文件,其执行过程为:
- 当浏览器请求服务器中的某一个JSP文件(例如:localhost/09-jsp/test.jsp),服务器会根据请求资源的路径去寻找该文件:
- 如果找到了,JSP翻译引擎会将JSP翻译成一个Servlet程序(JSP----> xxx.java----> xxx.class),然后Servlet程序再执行,执行的结果是向浏览器输出一个HTML网页!
- 如果没有找到,服务器将会响应一个404页面,通知浏览器请求的资源不存在。
访问服务器中的HTML文件,其执行过程为:
- 当浏览器请求服务器中的某一个HTML文件时(例如:localhost/09-jsp/test.html),服务器会根据请求资源的路径去寻找该文件:
- 如果找到了,服务器会将html文件的内容作为响应实体发送给浏览器,浏览器再解析html并显示在网页上。
- 如果没有找到,服务器将会响应一个404页面,通知浏览器请求的资源不存在。
JSP语法
模版元素
模板元素是指写在JSP中的html内容
或者除了JSP特有内容以外的其他内容称之为模板元素
模板元素在翻译后的Servlet中,被out.write原封不动的发送给浏览器,由浏览器负责解析并显示。
JSP表达式
格式:<%= 常量、变量、表达式 %>
作用:计算表达式的结果,将结果输出到浏览器中,由浏览器负责解析并显示。
<%= "Hello JSP..." %>
<% String name = "林青霞"; %>
<%= name %>
<%= 100+123 %>
<%= Math.random() %>
JSP脚本片段
格式:<% 若干Java语句 %>
作用:在翻译后的Servlet中,将脚本片段中的Java语句复制粘贴到Servlet的对应的位置执行。例如:
在JSP中代码如下:
<!-- 在页面上输出5行"hello JSP" -->
<%
for(int i=0; i<5; i++){
out.write("Hello JSP...<br/>");
}
%>
在翻译后的Servlet中代码如下:
...
for(int i=0; i<5; i++){
out.write("Hello JSP...<br/>");
}
...
另外,在某一个脚本片段中的Java代码可以是不完整的,但是在JSP中所有的脚本片段加在一起,必须是完整符合Java语法。例如,在JSP中代码如下:
<% for(int i=0;i<5;i++){ %>
Hello JSP~~~<br/>
<% } %>
在翻译后的Servlet中:
for(int i=0;i<5;i++){
out.write("\r\n");
out.write("\t\t\tHello JSP~~~<br/>\r\n");
out.write("\t");
}
JSP指令
指令的格式:<%@ 指令名称 若干属性声明... %>
指令的作用:用于指挥JSP解析引擎如何将一个JSP翻译成一个Servlet程序。
1、page指令:用于声明JSP的基本属性信息(比如JSP使用的编码,JSP使用的开发语言等)
<%@ page language="java"%>
-- language属性用于指定当前JSP使用的开发语言,目前只有java语言支持
<%@ page import="java.util.Date"%>
-- import属性用于导入包,如果不导入包,在使用其他包下的类时,就需要在类名前面加上包路径,例如: java.util.Date date = new java.util.Date();
<%@ page pageEncoding="UTF-8"%>
-- pageEncoding属性是用于指定当前JSP使用的编码,Eclipse工具会根据这个编码保存JSP文件。
保证pageEncoding属性指定的编码和JSP文件保存时使用的编码相同,可以避免JSP文件出现乱码!
2、taglib指令:用于引入JSTL标签库或者其他的自定义标签库
JSP标签技术
在JSP页面中写入大量的java代码会导致JSP页面中html代码和java代码混杂在一起,会造成jsp页面结构的混乱,导致后期难于维护,并且代码难以复用。
于是在JSP的2.0版本中,sun提出了JSP标签技术,推荐使用标签来代替JSP页面中java代码,并且推荐,JSP2.0以后不要在JSP页面中出现任何一行java代码。
EL表达式
格式:${ 常量/表达式/变量 }
(放在EL中的变量得先存入域中,才可以获取变量的值)
作用:(1)计算放在其中的表达式的结果,将结果输出在当前位置。
(2)主要作用:用于从域对象中获取数据,将获取到的数据输出在当前位置。
域对象:pageContext、request、session、application
1、获取常量、表达式、变量的值(变量得先存入域中)
${ "hello el" }
hello el <br/>
${ 100+123 }
${ 12*12 > 143 ? "yes" : "no" } <br/>
<%
String name = "马云";
request.setAttribute( "name123" , name );
%>
${ name123 }
<%= request.getAttribute("name123") %>
<%-- 在EL表达式中书写变量,底层会根据变量名到四个作用域中寻找该名称的属性值
如果找到对应的属性值, 就直接返回, 输出到当前位置; 如果找不到就接着寻找
直到找完四个作用域, 最后还找不到就什么都不输出!
到四个作用域中寻找的顺序为: pageContext->request->session->application
--%>
JSP中的代码:
<%-- 获取从Servlet转发带过来的域中的数组中的元素 --%>
${ names[0] } <%-- 刘德华 --%>
${ names[1] } <%-- 郭富城 --%>
${ names[2] } <%-- 张学友 --%>
${ names[3] } <%-- 黎明 --%>
3、获取作用域中map集合中的元素
Servlet中的代码:
//声明一个map集合,为集合添加元素, 并将map集合存入到域中
Map map = new HashMap();
map.put( "name" , "尼古拉斯赵四" );
map.put( "age" , 28 );
map.put( "addr", "中国" );
request.setAttribute( "map1", map );
//将请求转发到jsp, 在JSP中获取域中的数组中的元素
request.getRequestDispatcher( "/02-el.jsp" ).forward(request, response);
JSP中的代码:
${ map1.name } <%-- 尼古拉斯赵四 --%>
${ map1.age } <%-- 28 --%>
${ map1.addr } <%-- 中国 --%>
4、获取作用域中JavaBean对象的属性值
Bean:指可重用的组件
JavaBean:指Java中可重用的组件
业务Bean:专门用于处理业务逻辑(例如:处理注册请求时,在将用户的注册信息保存到数据库之前,需要对注册薪资进行校验)
实体Bean:是专门用于封装数据的(例如:User user = new User() …)
Servlet中的代码:
//声明一个User对象, 为对象的属性赋值, 并将User对象存入到域中
User u1 = new User();
u1.setName( "刘德华" );
u1.setAge( 18 );
u1.setAddr( "中国香港" );
request.setAttribute( "user" , u1 );
//将请求转发到jsp, 在JSP中获取域中的数组中的元素
request.getRequestDispatcher( "/02-el.jsp" ).forward(request, response);
JSP中的代码:
<%--
${ user.getName() }
${ user.getAge() }
${ user.getAddr() } --%>
<hr/>
<%-- user.name 底层调用的仍然是 getName()方法--%>
${ user.name }
<%-- user.age 底层调用的仍然是 getAge()方法--%>
${ user.age }
<%-- user.addr 底层调用的仍然是 getAddr()方法--%>
${ user.addr }
JSTL标签库是为JavaWeb开发人员提供的一套标准通用的标签库;
JSTL标签库和EL配合使用可以取代JSP中大部分的Java代码;
-
导入JSTL的开发包
-
在使用JSTL标签库的JSP中引入JSTL(taglib指令)
其中常用的标签如下:
1、<c:set></c:set>
– 用于往域中添加属性,或者修改域中已有的属性值
c:set 标签属性总结:
(1)var -- 指定存入作用域中的属性名称
(2)value -- 指定存入作用域中属性的值
(3)scope -- 指定将属性存入哪一个作用域中,默认值是page,表示pageContext域
可取值: a)page表示pageContext域 b)request表示request域
c)session表示session域 d)application表示ServletContext域
代码示例:
<%-- request.setAttribute("name", "张三"); --%>
<c:set var="name" value="张三" scope="request"/>
${ name }
<% String job = "java开发工程师"; %>
<c:set var="job" value="<%= job %>" scope="request"/>
${ job }
<c:set var="name" value="张三丰" scope="request"/>
${ name }
2、<c:if></c:if>
– 构造简单的 if…else…结构语句
c:if 标签属性总结:
test属性 – 指定一个布尔表达式,当表达式的结果为true时,将会执行(输出)c:if标签中的内容,如果表达式结果为false,将不会输出c:if标签中的内容
代码示例:往域中存入一个成绩, 根据成绩判断成绩所属的等级
<c:if test="${ 3>5 }">yes</c:if>
<c:if test="${ 3<=5 }">no</c:if>
<hr>
<!-- 根据成绩判断成绩所属的等级 -->
<c:set var="score" value="-35"/>
<c:if test="${ score>=80 and score<=100 }">您的成绩属于: 优秀!</c:if>
<c:if test="${ score>=60 and score<80 }">您的成绩属于: 中等!</c:if>
<c:if test="${ score>=0 and score<60 }">您的成绩属于: 不及格!</c:if>
<c:if test="${ score<0 or score>100 }">您的成绩有误!</c:if>
3、<c:forEach></c:forEach>
– 对集合或数组等中元素进行循环遍历或者是执行指定次数的循环.
(1) 遍历域中数组或集合中的元素
<%
String[] name = {"王海涛","刘沛霞","陈子枢","齐雷"};
request.setAttribute( "names", name );
%>
<c:forEach items="${ names }" var="name" varStatus="vs">
${ vs.count }, ${ vs.first }, ${ vs.last }, ${ name } <br/>
</c:forEach>
(2) 遍历域中map集合中的元素
<%
//声明一个map集合并将map集合存入域中
Map<Object,Object> map = new HashMap<Object,Object>();
map.put( "name" , "尼古拉斯.赵四" );
map.put( "age" , 35 );
map.put( "addr" , "中国" );
request.setAttribute( "map1", map );
%>
<c:forEach items="${ map1 }" var="entry">
${ entry } <br/>
</c:forEach>
(3) 遍历0~100之间的整数,将是3的倍数的数值输出到浏览器中
<c:forEach begin="1" end="100" var="i" step="1">
${ i%3==0 ? i:""}
</c:forEach>
<hr/>
<c:forEach begin="1" end="100" var="i" step="1">
<c:if test="${ i%3==0 }">
${ i }
</c:if>
</c:forEach>
c:forEach 标签属性总结:
在这里插入代码片(1)items: 指定需要遍历的集合或数组
(2)var: 指定用于接收遍历过程中的每一个元素
(3)begin: 指定循环从哪儿开始
(4)end: 指定循环到哪儿结束
(5)step: 指定循环时的步长, 默认值是1
(6)varStatus: 用于表示循环遍历状态信息的对象, 这个对象上有如下属性:
first属性: 表示当前遍历是否是第一次, 若是, 则返回true;
last属性: 表示当前遍历是否是最后一次, 若是, 则返回true;
count属性: 记录当前遍历是第几次