2014-07-09 Java Web的学习(6)-----JSP和EL

1.什么是JSP

JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。JSP/Servlet规范。JSP实际上就是Servlet。

JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据。

2.JSP调用和运行原理

1.当你访问web服务器中的JavaWeb应用时,如果访问的不是一个Servlet,那么都会访问一个默认的Servlet,由这个默认的S  ervlet来定位资源。当服务器发现你请求是一个JSP时,web容器会把 jsp 翻译成一个 Servlet,然后运行这个Servlet,  再将结果返回给客户端。
2.翻译 jsp 的过程是由Tomcat来完成的,生成的 Servlet源文件会保存在 Tomcat服务器的 work 文件夹中。
3.查看翻译后的Servlet的源码就会发现,这个类的父类继承了HttpServlet
4.对于请求的处理,查看翻译后的Servlet源码(service方法)就会发现,在service方法中,输出了我们定义的html代码,  并且Java代码也在这里运行。
5.在运行 service 方法时,该方法内部定义了很多局部变量,根据生成 Java 代码的位置就可以得知,这些变量和对象,可以直接在 Java 代码中使用,无需去创建。

3.JSP和Servlet两者适用场景

  • 首先从本质来讲,JSP和Servlet都是Servlet Java类.从运行原理上来看.

  • 不管是JSP还是Servlet,虽然都可以用于开发动态web资源。但由于这2门技术各自的特点,在长期的软件实践中,人们逐渐把servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用。

  • 其原因为,程序的数据通常要美化后再输出

1.让jsp既用java代码产生动态数据,又做美化会导致页面难以维护.
2.让servlet既产生数据,又在里面嵌套html代码美化数据,同样也会导致程序可读性差,难以维护
3.因此最好的办法就是根据这两门技术的特点,让它们各自负责各的,servlet只负责响应请求产生数据,并把数据通过转发  技术带给jsp,数据的显示jsp来做

4.JSP语法

  • JSP模版元素

    • JSP页面中的HTML内容称之为JSP模版元素

    • JSP模版元素定义了网页的基本骨架,即定义了页面的结构和外观

  • JSP表达式

    • JSP脚本表达式(expression)用于将程序数据输出到客户端,语法:<%= 变量或表达式 %>,举例:当前时间:<%= new java.util.Date() %>

    • JSP引擎在翻译脚本表达式时,会将程序数据转成字符串,然后在相应位置用out.print(…) 将数据输给客户端,所以在JSP表达式中不能使用 “;“。

  • JSP脚本片段

    • JSP脚本片断(scriptlet)用于在JSP页面中编写多行Java代码。语法:<% java代码 %>

    • 注意:JSP脚本片断中只能出现java代码,不能出现其它模板元素, JSP引擎在翻译JSP页面中,会将JSP脚本片断中的Java代码将被原封不动地放到Servlet的_jspService方法中

    • JSP脚本片断中的Java代码必须严格遵循Java语法

    • 在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素

    • 多个脚本片断中的代码可以相互访问,犹如将所有的代码放在一对<% %>之中的情况

    • 单个脚本片断中的Java语句可以是不完整的,但是,多个脚本片断组合后的结果必须是完整的Java语句(比如,循环处理模版元素)

  • JSP声明

    • JSP页面中编写的所有代码,默认会翻译到servlet的service方法中, 而Jsp声明中的java代码被翻译到_jspService方法的外面(类成员),语法:<%! java 代码 %>

    • JSP声明可用于定义JSP页面转换成的Servlet程序的静态代码块、成员变量和方法

    • 多个静态代码块、变量和方法可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中

    • JSP隐式对象的作用范围仅限于Servlet的_jspService方法,所以在JSP声明中不能使用这些隐式对象

    • JSP声明中,可以覆盖翻译Servlet中的方法(知道就行)

  • JSP注释

    • JSP注释的格式:<%-- 注释信息 --%>

    • JSP引擎在将JSP页面翻译成Servlet程序时,忽略JSP页面中被注释的内容(与html注释的区别)

  • JSP指令

    • include指令用于引入其它JSP页面,如果使用include指令引入了其它JSP页面,那么JSP引擎将把这两个JSP翻译成一个servlet。所以include指令引入通常也称之为静态引入(编译时包含,编译时引入)

    • 语法:<%@ include file="relativeURL"%>,其中的file属性用于指定被引入文件的路径。路径以“/”开头,表示代表当前web应用

    • 被引入的文件必须遵循JSP语法

    • 被引入的文件可以使用任意的扩展名,即使其扩展名是html,JSP引擎也会按照处理jsp页面的方式处理它里面的内容,为了见明知意,JSP规范建议使用.jspf(JSP fragments)作为静态引入文件的扩展名

    • 由于使用include指令将会涉及到2个JSP页面,并会把2个JSP翻译成一个servlet,所以这2个JSP页面的指令不能冲突(除了pageEncoding和导包除外)

    • page指令用于定义JSP页面的各种属性,无论page指令出现在JSP页面中的什么地方,它作用的都是整个JSP页面,为了保持程序的可读性和遵循良好的编程习惯,page指令最好是放在整个JSP页面的起始位置

    • JSP 2.0规范中定义的page指令的完整语法:

    • 使用page指令解决JSP中文乱码

    • errorPage属性的设置必须使用相对路径,如果以“/”开头,表示相对于当前WEB应用程序的根目录(不是站点根目录),否则,表示相对于当前页面。

    • 有时候错误提示页面不一定会显示,原因是错误信息量太小,没有达到缓冲区输出的值(1024字节)。可以设置浏览器(不可取),也可以增加信息量

    • 可以在web.xml文件中使用<error-page>元素为整个WEB应用程序设置错误处理页面,其中<exception-type>子元素指定异常类的完全限定名,<location>元素指定以”/“开头的错误处理页面的路径

    • 使用<error-page>配置时,还可以根据错误代码数字来配置<error-code>,配置404,500等

    • JSP中的属性配置,优先级大于web.xml的配置

    • language = "java",指定页面所嵌用的语言是Java

    • extends = "package.class ",指定翻译后的Servlet的父类(不要修改)

    • import = "{ package.class | pageckage.* }, ...",在java代码中需要使用的包或类(自动导入的包:java.lang. ; javax.servlet. ; javax.servlet.jsp. ; javax.servlet.http. ;)

      可以在一条page指令的import属性中引入多个类或包,其中的每个包或类之间使用逗号分隔。 
      也可以分开写多条,每条导入一个包或类。

    • session="true/false",指定翻译后的Servlet是否默认创建Session对象,默认值是true

    • buffer="none | 8KB | sizeKB",指定JSP的缓冲大小,默认8kb。(在使用out对象写数据的时候,不是直接写给客户端的,而是写入缓冲区,缓冲区满了才会写到客户端)

    • autoFlush = "true | false ",缓冲区满了,是否自动刷新。默认为true

    • isThreadSafe = "true | false ",指定JSP是否线程安全的。true表示非线程安全,false表示线程安全

    • errorPage = "relative_url",指定JSP的错误处理页面

    • isErrorPage = "true | false",指定JSP是否错误处理页面,默认false。如果是错误处理页面,在翻译成Servlet时,就可以获取封装好的异常对象

    • contentType = "mimeType [ ; charset = characterSet]" 如: " text/html ; charset = "UTF-8",告诉jsp引擎,该jsp的类型以及编码

    • pageEncoding = "characterSet",指定整个jsp的编码

    • isELIgnored = "true | false",指定该JSP是否忽略EL表达式,默认false。

    • JSP的乱码在Tomcat6.0以后已经得到很好的解决,再加上Eclipse工具,基本不会有乱码,会根据pageEcoding来自动更改文件编码

    • 以前的乱码主要是操作系统默认保存文件的编码与Tomcat的默认编码不一致造成的

    • pageEncoding = "characterSet",通知JSP引擎用什么编码来翻译JSP文件

    • contentType,通知翻译后的Servlet用什么类型和编码来设置response,好让浏览器正常显示(如果设置了pageEncoding,这个设置可以不写,但是如果使用记事本编写JSP,就需要再次设置)

    • page指令

    • include指令

    • taglib指令

    • JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分。在JSP 2.0规范中共定义了三个指令

    • JSP指令的基本语法格式:<%@ 指令 属性名="值" %>,举例:<%@ page contentType="text/html;charset=utf-8"%>

    • 如果一个指令有多个属性,这多个属性可以写在一个指令中,也可以分开写

    • Page指令

    • include指令

5.JSP运行原理

  • 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理。JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ,然后按照servlet的调用方式进行调用

  • 由于JSP第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响

  • JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用。JSP技术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用.

6.JSP九大隐式对象

  • request

  • response

  • config

  • application

  • exception

  • session

  • page

  • out

  • pageContext

JSP九大隐式对象,其中七个已经在Servlet中讲解过了,主要学习outpageContext.

out

  • out隐式对象用于向客户端发送文本数据

  • out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似

  • JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存

  • 只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:

    <body><%out.write("hehe");response.getWriter().write("gaga");%></body>

    • 设置page指令的buffer属性关闭了out对象的缓存功能

    • out对象的缓冲区已满

    • 整个JSP页面结束

      2014-07-09 Java Web的学习(6)-----JSP和EL_第1张图片

      2014-07-09 Java Web的学习(6)-----JSP和EL_第2张图片

  • 上面的代码运行后,会首先输出gaga,然后再输出hehe。这是因为,隐式对象的缓冲区的内容不会直接回写到客户端,而且会跟Response的缓冲区合并在一起(添加到后面),一次回写到客户端。

  • 在实际开发中,如果在JSP中需要显示数据,使用隐式对象,不要使用Response输出(JSP模版也存在这个问题)。

  • 同时使用out和response.getWriter()输出数据

  • demo:使用JSP实现文件的下载

pageContext

pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境

这个对象不仅封装了对其它8大隐式对象的引用,它自身还是一个域对象,可以用来保存数据,并且还可以通过pageContext操作其它三个域

1.使用pageContext可以访问别的三个域以及8大隐式对象,这种用法主要在自定义标签技术中使用
2.通过pageContext对象,可以直接将数据添加到别的三个域中,也可以直接从三个域中获取
3.使用 findAttribute方法,直接查找各个域中是否有该属性(EL表达式)

使用pageContext可以访问别的三个域以及8大隐式对象,这种用法主要在自定义标签技术中使用

通过pageContext对象,可以直接将数据添加到别的三个域中,也可以直接从三个域中获取

使用 findAttribute方法,直接查找各个域中是否有该属性(EL表达式)

这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源

pageContext类中定义了forward方法和include方法来分别简化和替代RequestDispatcher.forward方法和include方法
方法接收的资源如果以“/”开头, “/”代表当前web应用

    • pageContext类中定义了forward方法和include方法来分别简化和替代RequestDispatcher.forward方法和include方法

    • 方法接收的资源如果以“/”开头, “/”代表当前web应用

7.JSP标签(JSP标准动作)

2014-07-09 Java Web的学习(6)-----JSP和EL_第3张图片

2014-07-09 Java Web的学习(6)-----JSP和EL_第4张图片

2014-07-09 Java Web的学习(6)-----JSP和EL_第5张图片

2014-07-09 Java Web的学习(6)-----JSP和EL_第6张图片

2014-07-09 Java Web的学习(6)-----JSP和EL_第7张图片

2014-07-09 Java Web的学习(6)-----JSP和EL_第8张图片

8.EL表达式

EL 全名为Expression Language。EL主要作用:

获取数据:

EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象、获取数据。(某个web域 中的对象,访问javabean的属性、访问list集合、访问map集合、访问数组).

使用EL表达式获取数据语法:"${标识符}"
EL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从page、request、session、application四个域中查找相应的对象,找到则返回相应对象,找不到则返回”” (注意,不是null,而是空字符串)
示例:${user}

EL表达式也可以很轻松获取JavaBean的属性,或获取数组、Collection、Map类型集合的数据,例如:
${user.address.city}
${user.list[0]}:访问有序集合某个位置的元素
${map.key}  : 获得map集合中指定key的值
结合JSTL的foreach标签,使用EL表达式也可以很轻松迭代各种类型的数组或集合.

执行运算:

利用EL表达式可以在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,以在JSP页面中完成一些简单的逻辑运算。${user==null}.

2014-07-09 Java Web的学习(6)-----JSP和EL_第9张图片

获取web开发常用对象

EL 表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松获得对web常用对象的引用,从而获得这些对象中的数据。

EL表达式语言中定义了11个隐含对象,使用这些隐含对象可以很方便地获取web开发中的一些常见对象,并读取这些对象的数据。
语法:${隐式对象名称}  :获得对象的引用

2014-07-09 Java Web的学习(6)-----JSP和EL_第10张图片

调用Java方法

EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。

2014-07-09 Java Web的学习(6)-----JSP和EL_第11张图片

EL Function开发步骤

一般来说, EL自定义函数开发与应用包括以下三个步骤:

  • 编写一个Java类的静态方法

  • 编写标签库描述符(tld)文件,在tld文件中描述自定义函数。

  • 在JSP页面中导入和使用自定义函数

<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
	version="2.0">
	<tlib-version>1.0</tlib-version>
	<short-name>myfn</short-name>
	<uri>http://www.itheima.com/myfunctions</uri>
	<function>
		<name>toUpperCase</name>
		<function-class>com.itheima.myfunction.MyFunctions</function-class>
		<function-signature>java.lang.String toUpperCase( java.lang.String )</function-signature>
	</function>
</taglib>

开发EL Function注意事项

2014-07-09 Java Web的学习(6)-----JSP和EL_第12张图片

9.SUN公司的函数库

2014-07-09 Java Web的学习(6)-----JSP和EL_第13张图片










你可能感兴趣的:(2014-07-09 Java Web的学习(6)-----JSP和EL)