今天学习的内容主要有三个部分,jsp、el和jstl。
都说今天不卖萌(.=^・ェ・^=)了的说~~
目录
JSP板块
简介
JSP全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计,它 [1] 是由Sun Microsystems公司倡导、许多公司参与一起建立的一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML(标准通用标记语言的子集)文件(*.htm,*.html)中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件,后缀名为(*.jsp)。 用JSP开发的Web应用是跨平台的,既能在Linux下运行,也能在其他操作系统上运行。
它实现了Html语法中的java扩展(以 <%, %>形式)。JSP与Servlet一样,是在服务器端执行的。通常返回给客户端的就是一个HTML文本,因此客户端只要有浏览器就能浏览。
JSP技术使用Java编程语言编写类XML的tags和scriptlets,来封装产生动态网页的处理逻辑。网页还能通过tags和scriptlets访问存在于服务端的资源的应用逻辑。JSP将网页逻辑与网页设计的显示分离,支持可重用的基于组件的设计,使基于Web的应用程序的开发变得迅速和容易。 JSP(JavaServer Pages)是一种动态页面技术,它的主要目的是将表示逻辑从Servlet中分离出来。
Java Servlet是JSP的技术基础,而且大型的Web应用程序的开发需要Java Servlet和JSP配合才能完成。JSP具备了Java技术的简单易用,完全的面向对象,具有平台无关性且安全可靠,主要面向因特网的所有特点。
特点
跨平台:由于JSP是基于Java语言的,它可以使用 Java API,所以它也是跨平台的,可应用于不同的系统中,如 Windows、 Linux等。当从一个平台移植到另一个平台时,JSP和JavaBean的代码并不需要重新编译,这是因为Java的字节码是与平台无关的,这也应验了Java语言“一次编译,到处运行”的特点。
业务代码相分离:在使用JSP技术开发Wcb应用时,可以将界面的开发与应用程序的开发分离开。开发人员使用HTML来设计界面,使用JSP标签和脚本来动态生成页面上的内容。在服务器端,JSP引擎(或容器,本书中指 tomcat)负责解析JSP标签和脚本程序,生成所请求的内容,并将执行结果以HTML页面的形式返回到测览器。
组件重用:JSP中可以使用 JavaBean编写业务组件,也就是使用一个 Javabean类封装业务处理代码或者作为一个数据存储模型,在JSP页面中,甚至在整个项目中,都可以重复使用这个 JavaBean,同时,JavaBean也可以应用到其他Java应用程序中。
预编译:预编译就是在用户第一次通过测览器访问JSP页面时,服务器将对JSP页面代码进行编译,并且仅执行一次编译。编译好的代码将被保存,在用户下一次访问时,会直接执行编译好的代码。这样不仅节约了服务器的CPU资源,还大大的提升了客户端的访问速度。
脚本
书写jsp脚本的方法有三种:
- <%java代码%> ----- 内部的java代码翻译到service方法的内部
- <%=java变量或表达式> ----- 会被翻译成service方法内部out.print()
- <%!java代码%> ---- 会被翻译成servlet的成员的内容
注释
不同的注释可见范围不同
- Html注释:<!--注释内容--> ---可见范围:jsp源码、翻译后的servlet、页面显示html源码
- java注释://单行注释 /*多行注释*/ --可见范围:jsp源码、翻译后的servlet
- jsp注释:<%--注释内容--%> ----- 可见范围:仅jsp源码可见
运行原理
jsp本质就是servlet,在第一次被访问时会被Web容器翻译成servlet。
执行过程:
第一次访问---->helloServlet.jsp---->helloServlet_jsp.java---->编译运行
PS:被翻译后的servlet在Tomcat的work目录中可以找到
常用指令
jsp的指令是指导jsp翻译和运行的命令,jsp包括三大指令:
1.page指令 --- 属性最多的指令(实际开发中page指令默认)
page指令是属性最多的一个指令,根据不同的属性,指导整个页面特性
格式:<%@ page 属性名1= "属性值1" 属性名2= "属性值2" ...%>
常用属性如下:
language:jsp脚本中可以嵌入的语言种类
pageEncoding:当前jsp文件的本身编码---内部可以包含contentType
contentType:response.setContentType(text/html;charset=UTF-8)
session:是否jsp在翻译时自动创建session
import:导入java的包
errorPage:当前页面出错后跳转到哪个页面
isErrorPage:当前页面是否是一个处理错误的页面
2.include指令
页面包含(静态包含)指令,可以将一个jsp页面包含到另一个jsp页面中
格式:<%@ include file="被包含的文件地址"%>
3.taglib指令
在jsp页面中引入标签库(jstl标签库、struts2标签库)
格式:<%@ taglib uri="标签库地址" prefix="前缀"%>
内置/隐式对象
jsp被翻译成servlet之后,service方法中有9个对象定义并初始化完毕,我们在jsp 脚本中可以直接使用这9个对象。
名称 | 类型 | 描述 |
out | javax.servlet.jsp.JspWriter | 用于页面输出 |
request | javax.servlet.http.HttpServletRequest | 得到用户请求信息, |
response | javax.servlet.http.HttpServletResponse | 服务器向客户端的回应信息 |
config | javax.servlet.ServletConfig | 服务器配置,可以取得初始化参数 |
session | javax.servlet.http.HttpSession | 用来保存用户的信息 |
application | javax.servlet.ServletContext | 所有用户的共享信息 |
page | java.lang.Object | 指当前页面转换后的Servlet类的实例 |
pageContext | javax.servlet.jsp.PageContext | JSP的页面容器 |
exception | java.lang.Throwable | 表示JSP页面所发生的异常,在错误页中才起作用 |
1.out对象
out的类型:JspWriter
out作用就是向客户端输出内容----out.write()
out缓冲区默认8kb,可以设置成0,代表关闭out缓冲区,内容直接写到response缓冲器中。
2.pageContext对象
jsp页面的上下文对象,作用如下:
page对象与pageContext对象不是一回事
1)pageContext是一个域对象
setAttribute(String name,Object obj)
getAttribute(String name)
removeAttrbute(String name)
2)pageContext可以向指定的其他域中存取数据
setAttribute(String name,Object obj,int scope)
getAttribute(String name,int scope)
removeAttrbute(String name,int scope)
findAttribute(String name)---依次从pageContext域,request域,session域,application域中获 取属性,在某个域中获取后将不在向后寻找
3)可以获得其他8大隐式对象
例如: pageContext.getRequest()
pageContext.getSession()
四大作用域的总结:
page域:当前jsp页面范围
request域:一次请求
session域:一次会话
application域:整个web应用
标签
- 页面包含(动态包含):<jsp:include page="被包含的页面"/>
- 请求转发:<jsp:forward page="要转发的资源" />
静态包含与动态包含的区别?
<%@ include file="/header.jsp" %>
<%@ include file="/content.jsp" %>
<%@ include file="/footer.jsp" %>
静态包含
运行结果:
编译结果:
<
jsp:include
page="/header.jsp"></
jsp:include
>
<
jsp:include
page="/content.jsp"></
jsp:include
>
<
jsp:include
page="/footer.jsp"></
jsp:include
>
动态包含
运行结果:
编译结果:
我们可以看到,使用静态包含和动态包含最终的执行结果相同,但是实现过程不同,很明显编译成的java文件数目不同。
静态和动态包含的区别与联系
注:下文将包含有其它文件的jsp文件称为主体文件,比如上文中的index.jsp文件。将被包含的文件称为包含文件,比如前面的header.jsp文件。
1.<%@ include file=” ”%>是指令元素。<jsp:include page=” ”/>是行为元素
2.最终编译成java文件的数目不同。(从上面的例子可以看出)
· 静态包含在转换成为java文件的时候将包含文件的内容“复制”到主体文件,然后作为一个整体编译。最终编译为一个java文件。
· 动态包含是各个jsp文件分别转换,分别编译。最终编程成多个java文件。
3.执行时间不同
静态包含发生在:JSP---->java文件阶段。
动态包含发生在:执行class文件阶段。动态加入。
4.静态包含在两个文件中不能有相同的变量,动态包含允许。
由于静态包含相当于将包含文件内容直接复制到主体文件中,如果出现相同的变量,就会出现覆盖等问题,导致文件出错。而动态包含相当于调用不同的jsp,变量所在的空间不同,自然不会出现覆盖等现象。
5.无论是动态包含还是静态包含,其request对象都是相同的。也就是同一个request对象。
静态包含最终编译成一个java文件,有一个request对象很好理解。而动态包含最终编译成多个jsp文件,为何会使用一个request对象呢?其实这些jsp组合的过程是一个请求转发的过程,自然也使用同一个request对象了。
EL板块
简介
EL(Express Lanuage)表达式可以嵌入在jsp页面内部,减少jsp脚本的编写,EL 出现的目的是要替代jsp页面中脚本的编写。
语法
${expression}
使用
jsp脚本:<%=request.getAttribute(name)%>
EL表达式替代上面的脚本:${requestScope.name},即,命名方式为:对象Scope.要获得的属性,对于类似于数组的属性,可以使用[],如name[1]。当要存取的属性名称中包含一些特殊字符,如 . 或 - 等并非字母或数字的符号,就一定要使用“[ ]“。如果要动态取值时,就可以用“[ ]“来做,而“.“无法做到动态取值。
EL最主要的作用是获得四大域中的数据,格式${EL表达式}
EL获得pageContext域中的值:${pageScope.key};
EL获得request域中的值:${requestScope.key};
EL获得session域中的值:${sessionScope.key};
EL获得application域中的值:${applicationScope.key};
EL从四个域中获得某个值${key};
---同样是依次从pageContext域,request域,session域,application域中获取属性,在某个域中获取后将不在向后寻找。
内置对象
pageScope, requestScope, sessionScope, applicationScope ---- 获取JSP中域中的数据
param, paramValues ---- 接收参数,相当于request.getParameter() request.getParameterValues()
header, headerValues ---- 获取请求头信息,相当于request.getHeader(name)
initParam ---- 获取全局初始化参数,相当于this.getServletContext().getInitParameter(name)
cookie ---- WEB开发中cookie,相当于request.getCookies()---cookie.getName()---cookie.getValue()
pageContext ---- WEB开发中的pageContext。通过pageContext可以获得其他八大对象,如:
${pageContext.request.contextPath} 获得WEB应用的名称
相当于
<%=pageContext.getRequest().getContextPath%> (这句代码不能实现!!!)
直接执行表达式
${1+1} -----> 2
${empty ""} -----> true
${""==null?true:false} -----> true
JSTL板块
简介
JSTL(JSP Standard Tag Library),JSP标准标签库,可以嵌入在jsp页面中使用标签的形式完成业务逻辑等功能。jstl出现的目的同el一样也是要代替jsp页面中的脚本代码。JSTL标准标准标签库有5个子库,但随着发展,目前常使用的是他的核心库:
标签库 | 标签库的URI | 前缀 |
Core | http://java.sun.com/jsp/jstl/core | c |
I18N | http://java.sun.com/jsp/jstl/fmt | fmt |
SQL | http://java.sun.com/jsp/jstl/sql | sql |
XML | http://java.sun.com/jsp/jstl/xml | x |
Functions | http://java.sun.com/jsp/jstl/functions | fn |
下载与导入
1.从Apache的网站下载JSTL的JAR包。进入 “http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/”网址下载 JSTL的安装包。jakarta-taglibs-standard-1.1.2.zip,然后将下载好的JSTL安装包 进行解压,此时,在lib目录下可以看到两个JAR文件,分别为jstl.jar和standard.jar。 其中,jstl.jar文件包含JSTL规范中定义的接口和相关类,standard.jar文件包含用于 实现JSTL的.class文件以及JSTL中5个标签库描述符文件(TLD)。
2.将两个jar包导入我们工程的lib中。
3.使用jsp的taglib指令导入核心标签库。如:<%@ tarlib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
常用标签
1.<c:if test=””>标签
其中test是返回boolean的条件
2.<c:forEach>标签
// 方式一:迭代包含多个对象的集合
<c:forEach [var="varName"] items="collection" [varStatus="varStatusName"] [begin="begin"] [end="end"] [step="step"]>
body content
</c:forEach>
// 方式二:迭代指定范围内的集合
<c:forEach [var="varName"] [varStatus="varStatusName"] begin="begin" end="end" [step="step"]>
body content
</c:forEach>
在上述语法格式中,可以看到<c: foreach>标签有多个属性。接下来针对这些属性进行讲解,具体如下:
· var属性用于指将当前迭代到的元素保存到page域中的名称
· Items属性用于指定将要迭代的集合对象
· varstatus用于指定当前迭代状态信息的对象保存到page域中的名称;begin属性用于指定从集合中第几个元素开始进行迭代, begin的素引值从0开始,如果没有指定 Items属性,就从 begin指定的值开始迭代,直到迭代结束为止
· step属性用于指定迭代的步长,即迭代因子的增量
<c: foreach>标签在程序开发中经常会被用到,因此熟练掌握<c: foreach>标签是很有必要的。
javaEE的开发模式
什么是模式
模式在开发过程中总结出的“套路”,总结出的一套约定俗成的设计模式
javaEE经历的模式
model1模式
JSP Model1是 Javaweb早期的模型,它适合小型Web项目,开发成本低! Model1第一代时期服务器端只有JSP页面,所有的操作都在JSP页面中,连访问数据库的API也在JSP页面中完成。也就是说,所有的东西都耦合在一起,对后期的维护和扩展极为不利。(高内聚低耦合)
JSP Model1第二代有所改进,把业务逻辑的内容放到了Java Bean中,而JSP页面负责显示以及请求调度的工作。虽然第二代比第一代好了些,但还让JSP做了过多的工作,JSP中把视图工作和请求调度(控制器)的工作耦合在一起了。
技术组成:jsp+javaBean
model1的弊端:随着业务复杂性的增加,会导致jsp页面比较混乱
model2模式
技术组成:jsp+servlet+javaBean
model2的优点:开发中能够充分使用各个技术擅长的方面
servlet:擅长处理java业务代码
jsp:擅长页面的现实
MVC ---- web开发的设计模式
M:Model----模型 javaBean:封装数据
V:View----视图 jsp:单纯进行页面的显示
C:Controller----控制器 Servlet:获取数据--->对数据进行封装--->传递数据---> 指派显示的jsp页面
MVC可对程序的后期维护和扩展提供了方便,并且使程序某些部分的重用提供了方便。而且MVC也使程序简化,更加直观。
注意,MVC不是Java的特有的,几乎现在所有B/S结构的软件都采用了MVC设计模式。
javaEE的三层架构
服务器开发时分为三层:
web层:与客户端交互
service层:复杂业务处理
dao层:与数据库进行交互
开发实践时,三层架构通过包结构体现。
总结
EL表达式
从域中取出数据 ${域中存储的数据的name}
${pageContext.request.contextPath}
JSTL标签(核心库)
<%@ taglib uri=”” prefix=”c”%>
<c:if test=””>
<c:forEach items=”数组或集合” var=”数组或集合中的每一个元素”>
javaEE三层架构+MVC
web层:收集页面数据,封装数据,传递数据,指定响应jsp页面
service层:逻辑业务代码的编写
dao层:数据库的访问代码的编写
今天的复习就到这里,我是小昶,我们下次再见(′,,•ω•,,‘)