11.JSP应用,EL表达式
12.JSTL标签,自定义标签
13.MVC架构,junit单元测试
<11>.JSP应用,EL表达式
1.jsp基础
(1)什么是jsp?
sun公司制订的一种服务器端的动态页面技术规范。
注:
虽然使用servlet也可以生成动态页面,但是过于繁琐(需要使用out.print语句),并且不利于页
面的维护(如果修改页面,就需要修改java代码),所以,sun才推出了jsp规范。
jsp是一个以.jsp为后缀的文件,主要内容是html和少量的java代码。容器会将jsp转换成一个
servlet然后执行。
(2)如何写一个jsp文件?
1)step1.写一个以.jsp为后缀的文件
2)step2.可以添加如下内容:
a.html(css,js): 直接写。
b.java代码:
第一种:java代码片断
<% java代码 %>
第二种: jsp表达式
<%= java表达式 %>
第三种: jsp声明 (a1.jsp)
<%! 声明一个变量或者方法 %>
c.隐含对象:
什么隐含对象?
-直接可以使用的对象。
为什么可以使用这些隐含对象?
-容器会自动添加获得这些对象的代码。
有哪些隐含对象?
out,request,response
session
application
pageContext: 容器会为每一个jsp实例创建唯一的一个符合PageContext接口要求的对象,该对象会一直存在,除非jsp实例被删除。
作用1:绑订数据。(a2.jsp,a3.jsp)
注:绑订到pageContext上的数据,只有对应的jsp实例能够访问,类似于“钱包”。
作用2:提供了一些方法,用于获得其它所有隐含对象。
config: ServletConfig (a4.jsp)
exception: 获得异常的描述性信息。(a5.jsp,a6.jsp)
注:只有当page指令的isErrorPage
属性值为true时,才能使用。
page (了解) jsp实例本身。
注:jsp实例是jsp对应的servlet对象。
d.指令
什么是指令?
告诉容器将jsp转换成一个servlet时,做一些额外的处理,比如导包。
指令的语法:
<%@ 指令名 属性=值 %>
page指令
import属性:导包。
pageEncoding属性:设置jsp页面的编码。
contentType属性:设置 response.setContentType的内容。
errorPage属性:指定一个异常处理页面。当jsp运行时发生了异常,容器会调用异常处理页面。
isErrorPage属性:缺省值是false,如果为true, 就可以使用exception隐含对象。
session属性: (a7.jsp)缺省值是true,如果为false,则不能够使用session隐含对象了。
include指令
告诉容器,在将jsp转换成servlet时,将file属性指定的文件的内容插入到该指令所在的位置。
file属性:指定被包含的文件名。
注:
被包含的jsp并没有真正执行,只是负责提供内容。所以,被包含的文件也可以是其它类型的文件,比如html文件。
taglib指令
导入jsp标签。
e.注释 (a8.jsp)
<!-- 注释的内容 -->
注: 如果被注释的内容是java代码,java代码会执行,但是执行结果并不会在浏览器端显示楚来。
<%-- 注释的内容 --%>
注:如果被注释的内容是java代码,不会执行。
(3)jsp是如何执行的?
step1. 容器要将jsp转换成一个servlet。
html(css,js) ----> 在service方法里面,使用out.write输出。
<% %> ----> 在service方法里面,照搬。
<%= %> ----> 在service方法里面,使用 out.print输出。
<%! %> ----> 添加新的属性或者方法。
2.jsp标签和el表达式
(1)什么是jsp标签?
是sun公司为了替换jsp中的java代码而推出的一种技术,语法类似于html标签(有开始标记、属性、结束标签、标签体)。
注:
因为在jsp当中写java代码,不利于jsp文件的维护,比如美工去修改带有java代码的jsp文件就很不方便,所以sun才推出了jsp标签技术规范。
使用jsp标签,美工修改就很方便,另外,jsp页面变得简洁,方便代码的复用。
(2)什么是el表达式?
是一套简单的运算规则,用于给jsp标签的属性赋值。
注: el表达式也可以脱离jsp标签直接使用。
(3)el表达式的使用
1)读取bean的属性
注(了解):
如果一个类,满足如下几个条件,我们就可以称之为是一个javabean。
public class
public 构造器
最好实现Serializable接口
有一些属性及对应的get/set方法
方式一 ${user.username} e1.jsp
注:
a.执行过程:
容器依次从pageContext-->request-->session-->application中查找绑订名为"user"的对象(即调用getAttribute方法),接下来,调用该对象的"getUsername"方法,然后输出。
b.优点:
el表达式比java代码更简洁。
会将null转换成""输出。
如果依据绑订名找不到对应的对象,不会发生空指针异常。
c.可以使用pageScope,requestScope,sessionScope,applicationScope来指定查找范围
方式二 ${user[‘username’]}
注:
a. [ ]里面还可以使用绑订名。
b. [ ]里面还可以使用从零开始的下标,用于读取数组中指定下标的某个元素的值。
2)使用el表达式做一些简单的运算 (e2.jsp)
a.算术运算
+,-,*,/,%
注:
+ 只能求和。
b.关系运算
>,<,==,!=,>=,<=
c.逻辑运算
&&, ||,!
d.empty运算
判断集合是否为空或者是否为一个空字符串,如果是,返回true。
3)读取请求参数值 (e3.jsp)
a.${param.username}
等价于request.getParameter("username");
b.${paramValues.interest}
等价于request.getParameterValues("interest");
练习 使用el表达式输出某个员工的所有信息。
Employee类(ename,salary,age)
<12>.JSTL标签,自定义标签
1.jstl
(1)什么是jstl?
apache开发的一套jsp标签,后来捐献给了sun,sun将其命名为jsp standard taglib,简称为jstl。
(2)如何使用jstl?
step1.导包。(jstl)
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
step2.使用taglib指令导入jsp标签。
<%@ taglib uri="" prefix=""%>
uri属性:指定jsp标签的命名空间。
注:
命名空间是为了区分同名的元素在元素前添加的一段说明。为了防止命名空间也冲突,经常使用域名来允当命名空间。prefix属性:指定命名空间的别名。
(3)if标签 (if.jsp)
1)语法
<c:if test="" var="" scope="">
标签体
</c:if>
2)用法
a.当test属性值为true,执行标签体的内容。
b.test属性可以使用el表达式来计算。
c.var属性用来指定绑订名,scope属性指定绑订范围(可以是 page,request,session,application),绑订值是test属性值。
(4)choose标签 (choose.jsp)
1)语法
<c:choose>
<c:when test="">
标签体
</c:when>
<c:otherwise>
</c:otherwise>
</c:choose>
2)用法
a.when可以出现1次或者多次,相当于一个if语句,当test属性值为true时,执行标签体的内容。
b.otherwise可以出现0次或者1次,相当于最后那个else(表示例外)。
(5)forEach标签 (forEach.jsp)
1)语法
<c:forEach items="" var="" varStatus="">
</c:forEach>
2)用法
a.用来遍历集合或者数组。
b.items属性用来指定要遍历的集合或者数组,可以使用el表达式来赋值。
c.var属性用来指定绑订名。
注:
绑订范围固定是pageContext。
该标签每次从集合或者数组中取一个元素,然后将该元素绑订到pageContext上。
d.varStatus属性用来指定绑订名。
注:
绑订范围固定是pageContext。
绑订值是一个特殊的对象,该对象由该标签内部创建,用来获得当前遍历的状态。比如,该对象提供了如下几个方法:
getIndex(): 获得当前正在被遍历的元素的下标(从0开始)。
getCount():获得当前正在被遍历的元素的序号(从1开始)。
2.自定义标签
step1.写一个java类,继承SimpleTagSupport类。
注:
标签技术有两种,一种是复杂标签技术(old),一种是简单标签技术(new)。继承SimpleTagSupport类属于简单标签技术。
step2.override doTag方法
注:
在该方法里面,写处理逻辑。
step3.在.tld文件里面描述该标签。
注:
该文件要添加到WEB-INF下,可以参考c.tld文件来写。
参考代码
/**
* 标签类的要求:
* 1.继承SimpleTagSupport类。
* 2.override doTag方法,在该方法里写处理逻辑。
* 3.标签有哪些属性,标签类也得有对应的属性,并且属性名要相同,类型要匹配,还得有对应的set方法。
*/
public class HelloTag
extends SimpleTagSupport{
private String msg;
private int qty;
public HelloTag() {
System.out.println(
"HelloTag的构造器");
}
public void setMsg(String msg) {
System.out.println(
"HelloTag的setMsg方法...");
this.msg = msg;
}
public void setQty(int qty) {
System.out.println(
"HelloTag的setQty方法...");
this.qty = qty;
}
@Override
public void doTag() throws JspException, IOException {
System.out.println(
"HelloTag的doTag方法...");
/*
* 通过继承自SimpleTagSupport类提供的
* 方法来获得pageContext。
* pageContext提供了获得其它所有隐含对象
* 的方法。
*/
PageContext pctx =
(PageContext)getJspContext();
JspWriter out = pctx.getOut();
for(int i = 0; i < qty; i ++){
out.println(msg + "<br/>");
}
}
}
参考配置
<tag>
<name>hello</name>
<tag-class>tag.HelloTag</tag-class>
<!--
body-content用来设置标签体的内容。有三个值。
empty: 该标签没有标签体。
scriptless:该标签有标签体,但是,标签体里面不能够出现java代码。即不能够出现<% %> <%= %> <%! %>
JSP:该标签有标签体,并且标签体里面可以出现java代码。但是,只有复杂标签技术才支持该值。
-->
<body-content>empty</body-content>
<attribute>
<name>msg</name>
<!--
值为true,表示该属性是必须的。
-->
<required>true</required>
<!--
值为true,表示该属性可以动态赋值(比如使用el表达式来赋值)
-->
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>qty</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
练习
将day09-lab工程中的listUser.jsp的java代码使用jsp标签和el表达式来代替。
练习
开发一个date标签,可以按照指定的日期格式输出当前的系统日期。
<d:date pattern="yyyy-MM-dd"%>
<13>.Servlet声明周期
1.MVC是什么?
是一种软件架构思想、其核心思想是,在设计一个软件的时候,应该将软件划分成模型、视图、控制器这三种不同类型的模块。其中,模型负责数据处理(业务逻辑),视图负责数据展现(表示逻辑),控制器负责协调模型和视图。
注:
视图将请求发送给控制器,由控制器来选择对应的模型来处理;模型返回的结果也要给控制器,由控制器选择对应的视图来展现。
2.如何使用MVC?
在开发一个web应用时,我们可以使用servlet充当控制器,使用jsp充当视图,使用java类充当模型。它们的关系如下图所示:
3.MVC的优点?
a.将数据处理与数据展现分开,方便代码的维护。
注:
比如,模型返回的数据,可以使用不同的视图来展现。又比如,要调用新的模型,不用修改视图。
b.方便测试。
注:
比如,将业务逻辑写在java类里面,可以直接测试。如果将业务逻辑写在servlet类里面,需要部署整个应用才能测试。
c.方便分工协作。
4.MVC的缺点
使用MVC,会增加代码量,增加软件设计的难度、相应会增加软件开发的成本。所以,只有有一定规模、并且要求具有良好的维护性与扩展性的软件,才需要使用MVC。
# 练习
将day12-lab中所有jsp移到WEB-INF下,修改代码,使之正常运行。
5.实现一个MVC框架(SmartMVC)
(1)目标
实现一个通用的控制器(DispatcherServlet)。
注:
使用SmartMVC来开发一个web应用,只需要开发模型和视图。
(2)架构
1)主要组件
a. DispatcherServlet (控制器)
接收请求,依据HandlerMapping的配置,调用处理器来处理。依据处理器返回的结果(视图名),调用对应的视图来展现处理结果。
b. HandlerMapping (映射处理器)
负责提供请求路径与处理器的对应关系。
c. Controller (处理器)
负责处理业务逻辑,返回视图名。
2)这几个组件的关系。
step1.请求先发送给DispatcherServlet,DispatcherServlet收到请求之后,会依据HandlerMapping的配置,调用对应的处理器来处理。
step2.处理器(Controller)处理请求,返回视图名给DispatcherServlet。
step3.DispatcherServlet会依据视图名调用对应的视图。