Java相关课程系列笔记之十JSP学习笔记建议用WPS打开.docx
《Java相关课程系列笔记之十JSP学习笔记建议用WPS打开.docx》由会员分享,可在线阅读,更多相关《Java相关课程系列笔记之十JSP学习笔记建议用WPS打开.docx(21页珍藏版)》请在冰豆网上搜索。
Java相关课程系列笔记之十JSP学习笔记建议用WPS打开
JSP学习笔记
Java相关课程系列笔记之十
笔记内容说明
JSP(程祖红老师主讲,占笔记内容100%);
目录
一、JSP基础1
1.1什么是JSP1
1.2为什么要使用JSP1
1.3JSP与Servlet的关系1
1.4如何写一个JSP文件1
1.5JSP是如何运行的1
1.6隐含对象2
1.7指令2
1.8JSP注释3
1.9案例:
创建emplist.jsp页面,将表示逻辑交给JSP处理3
二、JSP标签和EL表达式4
2.1什么是JSP标签4
2.2JSTL及其使用4
2.3什么是EL表达式4
2.4EL表达式的使用4
三、JSTL中的几个核心标签7
3.1if7
3.2choose7
3.3forEach7
3.4url8
3.5set8
3.6remove8
3.7catch8
3.8import8
3.9redirect8
3.10out8
3.11JSP标签是如何运行的8
3.12案例:
将员工列表中的Java代码改为JSP标签,并添加分页9
四、自定义标签10
4.1如何写一个自定义标签10
4.2JavaEE5.0中,如何使用EL表达式和JSTL10
4.3案例:
自定义标签10
4.4案例:
修改之前员工列表中的日期显示11
五、MVC13
5.1什么是MVC13
5.2使用MVC的目的13
5.3如何使用MVC来开发一个Web应用程序(JavaEE)13
5.4MVC的优缺点13
5.5案例:
简易贷款(贷款数小于余额数*10)13
5.6修改5.5案例,使用户无法直接访问view.jsp页面15
1、JSP基础
1.1什么是JSP
JSP(JavaServerPage)是Java服务器端动态页面技术。
是sun公司制订的一种服务器端的动态页面生成技术规范。
1.2为什么要使用JSP
因为直接使用Servlet,虽然也可以生成动态页面。
但是,编写繁琐(需要使用out.println来输出),并且维护困难(如果页面发生了改变,需要修改Java代码),所以sun指定了JSP规范。
1.3JSP与Servlet的关系
JSP其实是一个以.jsp为后缀的文件,容器会自动将.jsp文件转换成一个.java文件(其实就是一个Servlet),然后调用该Servlet。
所以,从本质上讲,JSP其实就是一个Servlet。
1.4如何写一个JSP文件
step1:
创建一个以“.jsp”为后缀的文件。
step2:
在该文件里面,可以添加如下的内容:
1)HTML(CSS、JS):
直接写即可
2)Java代码:
形式一:
Java代码片段:
<%Java代码%>
形式二:
JSP表达式:
<%=Java表达式%>
形式三:
JSP声明:
<%!
%>
3)指令
1.5JSP是如何运行的
step1:
容器依据.jsp文件生成.java文件(也就是先转换成一个Servlet):
1)HTML(CSS、JS)放到service方法里,使用out.write输出
2)<%%>也放到service方法里,照搬,不改动。
3)<%=%>也会放到service方法里,使用out.print输出。
4)<%!
%>给Servlet添加新的属性或者新的方法(转成.java文件后,声明内的部分添加在service方法之外)。
这样就把一个JSP变成了一个Servlet容器。
◆注意事项:
out.writer方法只能输出简单的字符串,对象是没法输出的。
优点是把null自动转换成空字符串输出。
如:
<%out.println(newDate());%>不能用writer
step2:
容器接下来就会调用Servlet来处理请求了(会将之前生成的.java文件进行编译、然后实例化、初始化、调用相应的方法处理请求)
step3:
隐含对象
1)所谓隐含对象(共9个),指的是在.jsp文件里面直接可以使用的对象,比如out、request、response、session、application(ServletContext上下文)、exception、pageContext、config、page。
2)之所以能直接使用这些对象,是因为容器会自动添加创建这些对象的代码。
(JSP仅仅是个草稿,最终会变为一个Servlet。
)
1.6隐含对象
1)exception对象:
当jsp页面运行时发生了异常,容器会将异常信息封装到该对象,可以使用该对象提供的方法来输出异常的信息。
另外,必须在页面设置isErrorPage="true"指令才能使用该隐含对象。
2)pageContext对象:
容器会为每一个JSP实例(JSP所对应的那个Servlet对象)创建唯一的一个符合pageContext接口的对象,称之为page上下文。
该对象会一直存在,除非JSP实例被销毁。
它作用:
①绑定数据(绑定的数据只有对应的JSP实例才可以访问):
setAttribute、removeAttribute、getAttribute。
②找到其他八个隐含对象(详情看JSP标签)。
3)config对象:
即ServletConfig,可以使用该对象获得初始化参数。
例如:
step1:
a5.jsp页面
company:
<%=config.getInitParameter("company")%>
step2:
web.xml配置
a5
/a5.jsp
--jsp初始化参数-->
company
chang
a5
/a5.html
step3:
测试输入/a5.html
4)page对象:
JSP实例本身(一般不用)。
1.7指令
1)指令是什么
通知容器,在将.jsp文件转换成.java文件时,作一些额外的处理,比如导包。
2)指令的语法
<%@指令名称属性名=属性值%>
3)page指令
①import属性:
导包。
例如:
<%@pageimport="java.util.*"%>
--注意:
没有分号!
-->
<%@pageimport="java.util.*,java.text.*"%>
--多个包以逗号隔开!
都在一个双引号里-->
eg:
页面显示系统时间
currenttime:
<%out.println(newDate());%>
currenttime:
<%=newDate()%>
◆注意事项:
两个是等价,newDate()会被放入out.print();里
②contenType属性:
设置response.setContentType的内容。
例如:
<%@pageimport="java.util.*"contentType="text/html;charset=utf-8"%>
--属性之间用空格隔开-->
③pageEncoding属性:
告诉容器.jsp的文件的编码格式,这样,容器在获取jsp文件的内容(即解码)时,不会出现乱码。
最好加入,有些容器默认以ISO-8859-1编码。
例如:
<%@pagecontentType="text/html;charset=utf-8"pageEncoding="utf-8"%>
④session属性:
true/false,缺省值true,如果值为false,则容器不会添加获得session的语句。
例如:
<%@pagesession="false"%>
sessionID:
<%=session.getId()%>
--报错:
sessioncannotberesolved-->
⑤isELIgnored属性:
true/false,缺省值true,如果值为false,则告诉容器不要忽略el表达式。
J2EE5.0需要使用isELIgnored="false",否则EL表达式无效。
⑥isErrorPage属性:
true/false,缺省值false,如果值为true,表示这是一个错误处理页面(即专门用来处理其他JSP产生的异常,只有值为true时,才能使用exception隐含对象去获取错误信息)。
例如:
<%=exception.getMessage()%>
⑦errorPage属性:
设置一个错误处理页面。
例如:
step1:
a3.jsp页面,测试输入a3.jsp?
num=100a
<%@pageerrorPage="a4.jsp"%>
<%Stringnum=request.getParameter("num");
intsum=Integer.parseInt(num)+100;out.println(sum);%>
step2:
a4.jsp页面
<%@pageisErrorPage="true"pageEncoding="UTF-8"
contentType="text/html;charset=utf-8"%>
<%=exception.getMessage()%>
--获取到错误信息:
Forinputstring:
"100a"-->
◆注意事项:
页面最好添加:
DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">,否则会影响到CSS样式,甚至JS。
如IE有个混杂模式,即自动降级,为了兼容老的页面。
4)include指令
file属性:
①对于页面的公共部分,我们可以使用相同的jsp文件,并使用include指令导入,如此实现代码的优化。
②告诉容器,在将.jsp文件转换成.java文件时,在指令所在的位置插入相应的文件的“内容“(由file属性来指定)。
插入的页面并未运行,而是机械的将内容插入。
例如:
<%@includefile="head.jsp"%>
5)taglib指令
导入JSP标签<%@tagliburi="命名空间"prefix="前缀"%>
①uri:
在standard.jar/META-INF/c.tld中查找,详情看2.2
②prefix:
前缀,用于代表命名空间。
例如:
<%@tagliburi="prefix="c"%>
iftest="${1>0}">今天运气太好了
if>
1.8JSP注释
1)
--注释内容-->:
允许注释的内容是Java代码,如果是Java代码,会被容器执行,但是执行的结果会被浏览器忽略(不会显示出来)
2)<%--注释内容--%>:
注释的内容不能是Java代码,如果是Java代码,会被容器忽略。
1.9案例:
创建emplist.jsp页面,将表示逻辑交给JSP处理
详见Servlet笔记第9章。
2、
JSP标签和EL表达式
2.1什么是JSP标签
sun公司制定的一种技术规范,利用JSP标签(类似于HTML标签)来代替JSP中的Java代码。
这样作的好处是,JSP页面会更加简洁,并且更好维护(比如,将这样的页面交给美工,可以很方便地去修改)。
2.2JSTL及其使用
1)什么是JSTL:
JavaStandardTaglib(Java标准标签库,apache开发了一套标签,捐献给了sun,sun将其命名为JSTL)。
2)如何使用:
step1:
将JSTL标签对应的jar(标签类)文件拷贝到WEB-INF\lib下,standard.jar、jstl.jar
step2:
使用taglib指令引入JSP标签
2.3什么是EL表达式
是一套简单的计算规则,用于给JSP标签的属性赋值,也可以直接输出。
注意事项:
新建工程,J2EE选1.4可直接使用EL表达式,JavaEE5.0需要使用isELIgnored属性,否则无法使用!
!
详见1.7。
2.4EL表达式的使用
1)访问bean的属性(就是普通的Java类,有属性和get/set方法)
第一种方式:
例如:
${user.name},容器会依次从4个隐含对象中pageContext、request、session、application中查找(getAttribute)绑定名为"user"的对象。
接下来,会调用该对象的"getName"方法(自动将n变大写然后加get),最后输出执行结果。
优点:
①会自动将null转换成""输出。
②如果绑定名称对应的值不存在,会不报null指针异常,会输出""。
◆注意事项:
依次是指先从pageContext中查找,如果找不到,再查找request,如果找到了,则不再向下查找。
如果要指定查找范围,可以使用pageScope、requestScope、sessionScope、applicationScope来指定查找的范围。
eg:
jsp页面测试
<%Useruser=newUser();user.setName("chang");user.setAge(22);
request.setAttribute("user",user);Useruser2=newUser();user2.setName("bo");user2.setAge(22);session.setAttribute("user",user2);%>
name:
<%Useruser=(User)request.getAttribute("user");out.println(user.getName());%>
--用Java代码输出-->
--chang-->
name:
${user.name}
--用EL表达式输出-->
--chang-->
name:
${sessionScope.user.name}
--指定查找范围-->
--bo-->
第二种方式:
比如${user["name"]},与第一种方式是等价的!
容器会依次从4个隐含对象中pageContext、request、session、application中查找(getAttribute)绑定名为"user"的对象。
接下来,会调用该对象的"getName"方法(自动将n变大写然后加get),最后输出执行结果。
优点:
①中括号[]里面可以出现变量。
②中括号[]里面可以出现下标从0开始的数组。
◆注意事项:
v中括号[]里的字符串用双引号、单引号都可以!
vEL表达式中没引号的为变量,有引号的为字符串。
eg:
jsp页面测试
step1:
User类
privateStringname;privateintage;privateString[]interest;
privateIdCardcard;……get/set方法
step2:
IdCard类
privateStringcardNo;……get/set方法
step3:
jsp页面
<%Useruser=newUser();user.setName("chang");user.setAge(22);
user.setInterest(newString[]{"台球","乒乓球"});
user.setCard(newIdCard("1008611"));request.setAttribute("user",user);%>
name:
${user["name"]}
--基本类型,与${user.name}等价-->
<%request.setAttribute("propname","age");%>
name:
${user[propname]}
--变量-->
interest:
${user.interest}
--数组地址-->
interest:
${user.interest[1]}
--数组某个元素的值-->
IdCard:
${user.card.cardNo}
--引用类型-->
2)进行一些简单的计算,计算的结果可以用来给JSP标签的属性赋值,也可以直接输出。
①算术运算:
“+”、“-”、“*”、“/”、“%”
◆注意事项:
"+"号操作不能连接字符串。
如"abc"+"bcd"会报错!
"100"+"200"=${"100"+"200"}可以!
②关系运算:
“>”、“>=”、“<”、“<=”、“!
=”、"=="
◆注意事项:
“eq”也可判断是否相等
eg:
相关测试
1>0?
${1>0}
--true-->
<%request.setAttribute("str1","abc");request.setAttribute("str2","bcd");%>
${str1==str2}
--false-->${str1=="abc"}
--true-->
eq:
${str1eq"abc"}
--true-->${sessionScope.str1=="abc"}
--false-->
③逻辑运算:
"&&"、"||"、"!
",与Java中的一样
④empty运算:
判断是否是一个空字符串,或者是一个空的集合,如果是,返回true。
以下四种情况都是true:
A.空字符串。
B.空集合。
C.null。
D.根据绑定名找不到值。
eg:
相关测试
<%request.setAttribute("str3","");%>
空字符串:
${emptystr3}
--true-->
<%Listlist1=newArrayList();//list1.add("abc");//false
request.setAttribute("list1",list1);%>
空集合:
${emptylist1}
--true-->
<%request.setAttribute("obj",null);%>
null:
${emptyobj}
--true-->
找不到值:
${emptyabc}
--true-->
3)获取请求参数值
①${param.username}等价于request.getParameter("username");
②${paramValues.city}等价于request.getParameterValues("city");
eg:
相关测试a6.jsp页面
username:
${param.username}
--测试输入:
a6.jsp?
usernme=1-->
interest:
${paramValues.interest[0]}
--测试输入:
a6.jsp?
username=6&interest=cooking&interest=fishing-->
3、
JSTL中的几个核心标签
3.1if
1)语法:
iftest=""var=""scope="">
if>
当test属性值为true,执行标签体的内容,test属性可以使用EL表达式。
2)var属性:
用来指定绑定名称。
3)scope属性:
指定绑定范围,可以是page(pageContext)、request、session、application
◆注意事项:
可以在if标签里写Java代码。
3.2choose
1)语法:
choose>
--用于分支,当满足某个条件,执行某一个分支-->
whentest="">
--分支,可多次出现-->
when>
...
otherwise>
--当其他分支都不满足条件,则执行该标签的内容-->
otherwise>
choose>
◆注意事项:
vwhen和otherwise必须要放到choose标签里面才能使用。
vwhen可以出现1次或者多次,otherwise可以出现0次或者1次,表例外。
eg:
相关测试
<%Personp=newPerson();p.setName("常");p.setGender("x");
request.setAttribute("p",p);%>
性别:
choose>
whentest="${p.gender=='m'}">男
when>
whentest="${p.gender=='f'}">女
when>
otherwise>保密
otherwise>
choose>
3.3forEach
1)语法:
用法一(遍历集合):
forEachvar=""items=""carStatus="">
forEach>
①items属性:
用来指定要遍历的集合,可以使用EL表达式。
②var属性:
指定绑定名,绑定范围是pageContext,绑定值是从集合中取出的某个元素。
③carStatus属性:
指定绑定名,绑定范围是pageContext,绑定值是一个由容器创建的一个对象,该对象封装了当前迭代的状态。
比如,该对象提供了getIndex、getCount方法,其中,getIndex会返回当前迭代的元素的下标(从0开始),getCount会返回当前迭代的次数(从1开始)。
用法二(指定位置迭代):
forEachvar=""begin=""end="">
forEach>
①begin:
如果指定了items,那么迭代就从items[begin]开始进行迭代;如果没有指定items,那么就从begin开始迭代。
它的类型为整数。
②end:
如果指定了items,那么就在items[end]结束迭代;如果没有指定items,那么就在end结束迭代。
它的类型也为整数。
◆注意事项:
forEach还一个属性为step="":
迭代的步长。
3.4url
1)语法