JSP

JSP

概述

JSP(全称JavaServer Pages)是由[Sun Microsystems](https://baike.baidu.com/item/Sun Microsystems)公司主导创建的一种动态网页技术标准。JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTMLXML或其他格式文档的Web网页,然后返回给请求者。JSP技术以Java语言作为脚本语言,为用户的HTTP请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求。

JSP将Java代码和特定变动内容嵌入到静态的页面中,实现以静态页面为模板,动态生成其中的部分内容。JSP引入了被称为“JSP动作”的XML标签,用来调用内建功能。另外,可以创建JSP标签库,然后像使用标准HTML或XML标签一样使用它们。标签库能增强功能和服务器性能,而且不受跨平台问题的限制。JSP文件在运行时会被其编译器转换成更原始的Servlet代码。JSP编译器可以把JSP文件编译成用Java代码写的Servlet,然后再由Java编译器来编译成能快速执行的二进制机器码,也可以直接编译成二进制码。

本质

本质上是运行在服务端的一个Servlet,Tomcat等Servlet容器会将jsp文件中的内容通过out.write()、out.print()等方法直接输出给浏览器,浏览器获取到的依然是一个html文档,然后再进行渲染等。

JSP = HTML + Servlet
JSP可以让我们以编写HTML的方式去编写Servlet
JSP就是一个披着HTML外衣的Servlet,酷似HTML,但本质是一个Servlet
JSP是不能脱离服务器(Servlet容器)运行的

JSP本质就是一个Servlet,Servlet可以干的事JSP全都能干,所以有那么一段时间,JSP已经完全替换掉了Servlet,那么会导致我们的项目全都是JSP页面。JSP虽然可以直接编写Java代码,但是当在一个JSP中编写大量的Java代码以后,导致JSP页面非常不好维护。JSP擅长显示一个页面,而不擅长大量的编写Java代码,Servlet擅长编写Java代码,而不擅长显示页面, 所以我们开发中都是通过Servlet去调用Java程序去处理请求,而使用JSP来显示页面。

原理

jsp --翻译–> java --编译–> class

JSP文件翻译为一个.java文件(Servlet容器会将jsp中的内容读取到一个Servlet的输出内容中去),翻译后的文件将会放到服务器的work目录中(jsp页面只有在第一次访问之后才会生成对应的.java文件),在work目录中我们会发现比如index_jsp.java文件,这个类index_jsp 继承了 org.apache.jasper.runtime.HttpJspBase,HttpJspBase又继承HttpServlet,所以该类也间接的实现了Servlet接口.再将java文件编译为class文件(我们在访问JSP时,实际上就是访问的jsp对应的那个class文件)

生命周期

  • 编译阶段:

    的servlet容器编译servlet的源文件,生成的servlet类

    当浏览器请求JSP页面时,JSP引擎会首先去检查是否需要编译这个文件。如果这个文件没有被编译过,或者在上次编译后被更改过,则编译这个JSP文件。

    编译的过程包括三个步骤:

    • 解析JSP文件。
    • 将JSP文件转为servlet的。
    • 编译的servlet。
  • 初始化阶段:

    加载与JSP对应的servlet的类,创建其实例,并调用它的初始化方法

    容器载入JSP文件后,它会在为请求提供任何服务前调用jspInit()方法如果您需要执行自定义的JSP初始化任务,复写jspInit()方法就行了,就像下面这样:

    public void jspInit(){
      //初始化代码
    }
    
  • 执行阶段:

    调用与JSP对应的servlet的实例的服务方法

    这一阶段描述了JSP生命周期中一切与请求相关的交互行为,直到被销毁。

    当JSP网页完成初始化后,JSP引擎将会调用_jspService()方法。

    _jspService()方法需要一个HttpServletRequest的对象和一个HttpServletResponse的对象作为它的参数,

    void _jspService(HttpServletRequest请求,
                     HttpServletResponse响应)
    {
       //服务端处理代码
    }
    
    - _jspService()方法在每个请求中被调用一次并且负责产生与之相对应的响应,并且它还负责产生所有7个HTTP方法的回应,比如GET,POST,DELETE等等。
    
  • 销毁阶段:

    调用与JSP对应的servlet的实例的销毁方法,然后销毁的servlet实例

    调用与JSP对应的servlet的实例的销毁方法,然后销毁的servlet实例

    JSP生命周期的销毁阶段描述了当一个JSP网页从容器中被移除时所发生的一切。

    jspDestroy()方法在JSP中等价于小服务程序中的销毁方法。当您需要执行任何清理工作时复写jspDestroy()方法,比如释放数据库连接或者关闭文件夹等等。

    jspDestroy()方法的格式如下:
    
    public void jspDestroy()
    {
      //清理代码
    }
    

基本语法

基础语法

  • 声明

一个声明语句可以声明一个或多个变量、方法,供后面的Java代码使用。在JSP文件中,您必须先声明这些变量和方法然后才能使用它们。

<%! declaration; [ declaration; ]+ ... %>
或者
<jsp:declaration>
   代码片段
</jsp:declaration>
  • JSP表达式

一个JSP表达式中包含的脚本语言表达式,先被转化成String,然后插入到表达式出现的地方。

由于表达式的值会被转化成String,所以您可以在一个文本行中使用表达式而不用去管它是否是HTML标签。

表达式元素中可以包含任何符合Java语言规范的表达式,但是不能使用分号来结束表达式。

<%= 表达式 %>
  • jsp脚本

脚本片段写在 <% %>中,可以在脚本片段中直接编写Java代码,脚本片段会原封不动的复制到java文件的service方法中的对应位置,在service方法中可以写什么,在脚本片段中就可以写什么,在jsp中可以编写多个脚本片段,但是要求多个脚本片段之间的结构完整

<% java 代码 %>
或者
<jsp:scriptlet>
   代码片段
</jsp:scriptlet>

注释

JSP的注释写在 <%-- --%>中,JSP注释中的内容不会被JSP引擎翻译到java文件中,JSP中可以使用三种注释:
  :HTML注释
  //:Java的注释
  <%-- --%>:JSP注释
注释完整的jsp脚本的时候,必须使用jsp的注释<%-- --%> ,若用其他的注释后台还是会执行被注释了的脚本片段

JSP指令

JSP指令的格式:<%@ 指令名 属性名1=”属性值1” 属性名2=”属性值2” %>,

<%@ page language=“java” contentType=“text/html; charset=UTF-8” pageEncoding=“UTF-8”%>

  1. page指令的属性:
     import:在jsp中导包
     errorPage:当页面出现错误以后,要转发到的错误页面
    isErrorPage:当前页面是否是一个错误页面,默认为false,如果设置为true,则可以在该页面中使用exception对象
     isELIgnored:是否忽略EL表达式,默认值是false,一般不动
     session:JSP中是否会自动创建session,默认值是true,一般不动
    contentType:设置当前JSP内容的类型
     pageEncoding:当前页面使用的编码,jsp引擎会自动根据该编码解析jsp文件
     language:JSP页面将会被翻译为的语言,默认值是java,可选值只有一个java
     autoFlush:是否自动刷新流中内容,默认是true,一般不动
     buffer:流使用的缓存大小,默认是8kb,一般不动
     extends:当前JSP对应的java文件需要继承的父类,一般不动
     info:设置jsp的信息

2. include指令:静态包含,将一个页面包含进另一个页面

​ 特点:只会将包含后的文件进行翻译得到一个对应的java文件,而不会翻译被包含的文件,相当于将被包含文件中的内容原封不动的复制到指定文件中,这样可以省去很多重复的html代码

​ 3. taglib指令

​ 引入标签库

JSP动作标签

JSP行为标签使用XML语法结构来控制servlet引擎。它能够动态插入一个文件,重用JavaBean组件,引导用户去另一个页面,为Java插件产生相关的HTML等等。

隐含对象

隐含对象也叫内置对象,这些对象可以在JSP中直接使用,这是因为在JSP对应的java文件的service方法中已经声明了这些对象并且都赋了值。

  • pageContext PageContext

    代表当前页面的上下文,通过它可以获取到jsp中的其他隐含对象,1个顶9个

    ageContext 对象的作用是取得任何范围的参数,通过它可以获取 JSP页面的out、request、reponse、session、application 等对象。pageContext对象的创建和初始化都是由容器来完成的,在JSP页面中可以直接使用 pageContext对象。

  • request HttpServletRequest

  • session HttpSession

    1.什么是session:从一个客户打开浏览器并连接到服务器开始,到客户关闭浏览器离开这个服务器结束,被称为一个会话。当一个客户访问一个服务器时,可能会在这个服务器的几个页面之间反复连接,反复刷新一个页面,服务器应当通过某种办法知道这是同一个客户,这就需要session对象。

    2.session对象的ID:当一个客户首次访问服务器上的一个JSP页面时,JSP引擎产生一个session对象,同时分配一个String类型的ID号,JSP引擎同时将这个ID号发送到客户端,存放在Cookie中,这样session对象和客户之间就建立了一一对应的关系。当客户再访问连接该服务器的其他页面时,不再分配给客户新的session对象,直到客户关闭浏览器后,服务器端该客户的session对象才取消,并且和客户的会话对应关系消失。当客户重新打开浏览器再连接到该服务器时,服务器为该客户再创建一个新的session对象。

    3.session对象存在一定时间过期问题,所以存在session中的名值对会在一定时间后失去,可以通过更改session有效时间来避免这种情况。同时编程时尽量避免将大量有效信息存储在session中,request是一个不错的替代对象。

  • application ServletContext

  • page JspContext

    在jsp对应的java文件中有如下代码:Object page = this;因此page代表当前对象,即对应的Servlet,用的不多

  • out JspWriter

    和Servlet的PrintWriter类似,都是用来向浏览器输出一个内容

    out 对象用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。在使用 out 对象输出数据时,可以对数据缓冲区进行操作,及时清除缓冲区中的残余数据,为其他的输出让出缓冲空间。待数据输出完毕后,要及时关闭输出流。

  • response HttpServletResponse

    和Servlet中response一样,但是在jsp中很少使用

  • config ServletConfig

    可以用来获取JSP的初始化参数,不常用

    config 对象的主要作用是取得服务器的配置信息。通过 pageContext对象的 getServletConfig() 方法可以获取一个config对象。当一个Servlet 初始化时,容器把某些信息通过 config对象传递给这个 Servlet。 开发者可以在web.xml 文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数

  • exception Throwable

    java.lang.Throwable 的实例,该实例代表其他页面中的异常和错误。只有当页面是错误处理页面,即编译指令page 的isErrorPage 属性为true 时,该对象才可以使用。常用的方法有getMessage()和printStackTrace()等。

JSP中一共有9大隐含对象

域对象

  • pageContext PageContext

    最小的域对象,可以在当前页面中共享数据,一旦切换页面,则域中的属性就会丢失,该对象主要用来向标签中传递数据

  • request HttpServletRequest

    request对象可以在一次请求中共享数据,一旦发送多次请求,则域中的属性就会丢失。主要用于在转发时共享数据(request域中属性在转发时有效,重定向时无效)

  • session HttpSession

    session对象可以在一次会话中共享数据,一旦会话结束则域中的属性丢失。会话:就是一次打开关闭浏览器的过程

  • application ServletContext

    application是最大的域对象,作用范围是整个项目,只要不关闭服务器则application域中的属性一直有效

常用类

JspPage

public interface JspPage extends Servlet

  • 概述

    JspPage接口描述了JSP页面实现类必须满足的通用交互;使用HTTP协议的页面由HttpJspPage接口描述。

    接口定义了一个有3个方法的协议;其中只有两个:jspInit()和jspDestroy()是这个接口的一部分,作为第三个方法的签名:_jspService()依赖于所使用的特定协议,在Java中不能以通用方式表示。
    实现这个接口的类负责根据相应的基于servlet的方法调用在适当的时候调用上述方法。

    jspInit()和jspDestroy()方法可以由JSP作者定义,但是_jspService()方法是由JSP处理器根据内容自动定义的

  • 常用方法

    voidjspDestroy ()
    当JSP页面即将被销毁时,将调用jspDestroy()方法。

    voidjspInit ()
    jspInit()方法在初始化JSP页面时被调用。

HttpJspPage

public interface HttpJspPage extends JspPage

  • 概述

    HttpJspPage接口描述了使用HTTP协议时JSP页面实现类必须满足的交互。
    除了_jspService方法的签名之外,该行为与JspPage的行为相同,该方法现在在Java类型系统中是可表达的,并显式地包含在接口中。

  • 常用方法

    void _jspService(HttpServletRequest request, HttpServletResponse response)

    _jspService()方法对应于JSP页面的主体。

PageContext

public abstract class PageContext extends JspContext

  • 概述

    PageContext扩展了JspContext,为JSP技术在Servlet环境中使用时提供有用的上下文信息。PageContext实例提供了对与JSP页面关联的所有名称空间的访问,提供了对几个页面属性的访问,以及对实现细节之上的一层的访问。隐式对象会自动添加到pageContext中。

    PageContext类是一个抽象类,被设计为通过一致的JSP引擎运行时环境扩展以提供依赖于实现的实现。PageContext实例由JSP实现类通过调用JspFactory.getPageContext()方法获得,并通过调用JspFactory.releasePageContext()释放。

  • 常用方法

以下方法方便访问隐式对象

:getException()、getPage()、getRequest()、getResponse()、getSession()、getServletConfig()和getServletContext()。以下方法提供了对转发、包含和错误处理的支持:forward()、include()和handlePageException()。

JspContext

public abstract class JspContext extends Object

  • 概述

    JspContext作为PageContext类的基类,并抽象出不特定于servlet的所有信息。这允许在请求/响应Servlet的上下文之外使用简单的标记扩展。

  • 常用方法

    用于JSP作者的方法
    有些方法提供对表示作用域的不同对象的统一访问。实现必须使用与该作用域对应的底层机制,这样信息就可以在底层环境(例如servlet)和JSP页面之间来回传递。方法有:setAttribute(), getAttribute(), findAttribute(), removeAttribute(), getAttributesScope()和getAttributeNamesInScope()。

    下面的方法提供了对隐式对象的方便访问:
    下面的方法提供了对表达式语言的编程访问

JspFactory

public abstract class JspFactory extends Object

JspFactory是一个抽象类,它定义了许多在运行时JSP页面可用的工厂方法,用于创建用于支持JSP实现的各种接口和类的实例。
一致的JSP引擎实现将在初始化期间实例化这个类的实现依赖的子类,并通过注册通过静态setDefaultFactory()方法与该类一起创建的实例,使其可被JSP实现类全局使用。

JspWriter

public abstract class JspWriter extends Writer

JSP页面中的操作和模板数据是使用JspWriter对象编写的,该对象由隐式变量out引用,该变量是使用PageContext对象中的方法自动初始化的。
这个抽象类模拟java.io中的一些功能。BufferedWriter和io。PrintWriter类,但它的区别在于它抛出java.io。而PrintWriter则没有。

初始的JspWriter对象与ServletResponse的PrintWriter对象关联的方式取决于页面是否被缓存。如果页面没有被缓存,那么写入到这个JspWriter对象的输出将被直接写入到PrintWriter,必要时将通过调用响应对象上的getWriter()方法来创建PrintWriter。但是如果页面被缓冲,PrintWriter对象将不会被创建,直到缓冲区被刷新并且像setContentType()这样的操作是合法的。由于这种灵活性极大地简化了编程,因此缓冲是JSP页面的默认配置。缓冲引发了一个问题,即当缓冲区被超过时该怎么办。可以采取两种方法:超过缓冲区不是致命错误;当缓冲区溢出时,只需刷新输出。超过缓冲区是致命错误;当超出缓冲区时,引发异常。这两种方法都是有效的,因此JSP技术都支持这两种方法。页面的行为由自动刷新属性(默认为true)控制。通常,需要确保已将正确和完整的数据发送给客户机的JSP页面可能希望将自动刷新设置为false,典型的情况是客户机本身就是应用程序。另一方面,发送有意义数据的JSP页面(即使在部分构造时也是如此)可能希望将自动刷新设置为true;例如,当数据通过浏览器发送以立即显示时。每个应用程序都需要考虑它们的特定需求。考虑的另一种选择是使缓冲区大小无限制;但是,这有一个缺点,即失控的计算将消耗无限量的资源。JSP实现类的“out”隐式变量就是这种类型的。如果page指令选择autoflush=“true”,那么如果当前操作在没有flush的情况下执行会导致溢出条件,那么该类上的所有I/O操作都将自动刷新缓冲区的内容。如果autoflush=“false”,那么如果执行当前操作会导致缓冲区溢出,那么该类上的所有I/O操作都将抛出一个IOException。

EL

EL 全名为Expression Language

概述

	1. Expression Language语言,一种用于JSP文件中的数据访问的语言。

2. 能够简化JSP文件中该数据访问的代码,可用来替代传统的基于<%= %>和部分<% %>的程序片段。
  3. EL表达式使得JSP文件的创建人员能够用更加简单的语法来访问数据。
  4. 基本形式为: ${var}

表达式语言(Expression Language)简称EL,它是JSP2.0中引入的一个新内容。通过EL可以简化在JSP开发中对对象的引用,从而规范页面代码,增加程序的可读性及可维护性。EL为不熟悉Java语言页面开发的人员提供了一个开发Java Web应用的新途径。

特点

获取数据
使用EL表达式获取数据语法:"**${标识符}**"

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

<% 
13         request.setAttribute("name","孤傲苍狼");
14     %>
15         <%--${name}等同于pageContext.findAttribute("name") --%>
16         使用EL表达式获取数据:${name}  
17     <hr>
18     <!-- 在jsp页面中,使用el表达式可以获取bean的属性 -->
19     <% 
20         Person p = new Person();
21         p.setAge(12);
22         request.setAttribute("person",p);
23     %>
24         使用el表达式可以获取bean的属性:${person.age}
25     <hr>
26     <!-- 在jsp页面中,使用el表达式可以获取bean中的。。。。。。。。。的属性 -->
27     <% 
28         Person person = new Person();
29         Address address = new Address();
30         person.setAddress(address);
31         
32         request.setAttribute("person",person);
33     %>
34        ${person.address.name}
35      <hr>
36     <!-- 在jsp页面中,使用el表达式获取list集合中指定位置的数据 -->
37     <% 
38         Person p1 = new Person();
39         p1.setName("孤傲苍狼");
40         
41         Person p2 = new Person();
42         p2.setName("白虎神皇");
43         
44         List<Person> list = new ArrayList<Person>();
45         list.add(p1);
46         list.add(p2);
47         
48         request.setAttribute("list",list);
49     %>
50     
51     <!-- 取list指定位置的数据 -->
52     ${list[1].name} 
53     
58     <hr>
59     <!-- 在jsp页面中,使用el表达式获取map集合的数据 -->
60     <% 
61         Map<String,String> map = new LinkedHashMap<String,String>();
62         map.put("a","aaaaxxx");
63         map.put("b","bbbb");
64         map.put("c","cccc");
65         map.put("1","aaaa1111");
66         request.setAttribute("map",map);
67     %>
68     
69     <!-- 根据关键字取map集合的数据 -->
70       ${map.c}  
71       ${map["1"]}
72       <hr>
77     <hr>
执行运算

语法:${运算表达式},EL表达式支持如下运算符

  • ​ 关系运算符
    关系运算符 说 明 示 例 结 果
    ==(或 eq) 等于 13 = = 2 或 {13==2}或 13==2{13 eq 2} false
    !=(或 ne) 不等于 13 ! = 2 或 {13!=2}或 13!=2{13 ne 2} true
    <(或 lt) 小于 13 < 2 或 {13<2}或 13<2{13 lt 2} false
    >(或gt) 大于 13 > 2 或 {13>2}或 13>2{13 gt 2} true
    <=(或le) 小于等于 13 < = 2 或 {13<=2}或 13<=2{13 le 2} false
    >=(或ge) 大于等于 13 > = 2 或 {13>=2}或 13>=2{13 ge 2} true

  • 逻辑运算符
    逻辑运算符 说 明 示 例 结 果
    &&(或and) 逻辑与 如果 A 为 true,B 为 false,则 A && B(或 A and B) false
    ||(或 or) 逻辑或 如果 A 为 true,B 为 false,则 A||B(或 A or B) true
    !(或 not) 逻辑非 如果 A 为 true,则 !A(或 not A) false

  • 算术运算符
    算术运算符 说 明 示 例 结 果

    • 加 ${13+2} 15
    • 减 ${13-2} 11
    • 乘 ${13*2} 26
      /(或div) 除 13 / 2 或 {13/2}或 13/2{13 div 2} 6.5
      %(或mod) 取模(求余) KaTeX parse error: Expected '}', got 'EOF' at end of input: {13%2}或{13 mod2} 1
  • empty运算符:检查对象是否为null(空)

  • 三元表达式:${user!=null?user.name :""}

  • [ ] 和 . 号运算符

<h3>el表达式进行四则运算:</h3>
12         加法运算:${365+24}<br/>
13         减法运算:${365-24}<br/>
14         乘法运算:${365*24}<br/>
15         除法运算:${365/24}<br/>
16         
17     <h3>el表达式进行关系运算:</h3>
18     <%--${user == null}和 ${user eq null}两种写法等价--%>
19         ${user == null}<br/>
20         ${user eq null}<br/>
21         
22         <h3>el表达式使用empty运算符检查对象是否为null()</h3>
    ${empty 变量}

<h3>EL表达式中使用二元表达式</h3>
48     <% 
49         session.setAttribute("user",new User("孤傲苍狼"));
50     %>
51     ${user==null? "对不起,您没有登陆 " : user.username}
隐式对象

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

序号隐含对象名称描 述
1pageContext对应于JSP页面中的pageContext对象(注意:取的是pageContext对象。)
2pageScope代表page域中用于保存属性的Map对象
3requestScope代表request域中用于保存属性的Map对象
4sessionScope代表session域中用于保存属性的Map对象
5applicationScope代表application域中用于保存属性的Map对象
6param表示一个保存了所有请求参数的Map对象
7paramValues表示一个保存了所有请求参数的Map对象,它对于某个请求参数,返回的是一个string[]
8header表示一个保存了所有http请求头字段的Map对象,注意:如果头里面有“-” ,例Accept-Encoding,则要header[“Accept-Encoding”]
9headerValues表示一个保存了所有http请求头字段的Map对象,它对于某个请求参数,返回的是一个string[]数组。注意:如果头里面有“-” ,例Accept-Encoding,则要headerValues[“Accept-Encoding”]
10cookie表示一个保存了所有cookie的Map对象
11initParam表示一个保存了所有web应用初始化参数的map对象
<body>
 9    <br/>---------------1、pageContext对象:获取JSP页面中的pageContext对象------------------------<br/>
10         ${pageContext}
11     <br/>---------------2、pageScope对象:从page域(pageScope)中查找数据------------------------<br/>
12     <% 
13         pageContext.setAttribute("name","孤傲苍狼");  //map
14     %>
15         ${pageScope.name}
16        <br/>---------------3、requestScope对象:从request域(requestScope)中获取数据------------------------<br/>
17        <% 
18            request.setAttribute("name","白虎神皇");  //map
19        %>
20            ${requestScope.name}
21        <br/>---------------4、sessionScope对象:从session域(sessionScope)中获取数据------------------------<br/>
22        <% 
23            session.setAttribute("user","xdp");  //map
24        %>
25            ${sessionScope.user}
26        <br/>---------------5、applicationScope对象:从application域(applicationScope)中获取数据------------------------<br/>
27        <% 
28            application.setAttribute("user","gacl");  //map
29        %>
30            ${applicationScope.user}
31        <br/>--------------6、param对象:获得用于保存请求参数map,并从map中获取数据------------------------<br/>
32        <!-- http://localhost:8080/JavaWeb_EL_Study_20140826/ELDemo03.jsp?name=aaa  -->
33            ${param.name}  
34        <!-- 此表达式会经常用在数据回显上 -->
35        <form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post">
36            <input type="text" name="username" value="${param.username}">
37            <input type="submit" value="注册">
38        </form>
39        <br/>--------------7、paramValues对象:paramValues获得请求参数 //map{"",String[]}------------------------<br/>
40        <!-- http://localhost:8080/JavaWeb_EL_Study_20140826/ELDemo03.jsp?like=aaa&like=bbb -->
41            ${paramValues.like[0]}  
42            ${paramValues.like[1]} 
43        <br/>--------------8、header对象:header获得请求头------------------------<br/>
44            ${header.Accept}<br/>
45            <%--${header.Accept-Encoding} 这样写会报错
46                 测试headerValues时,如果头里面有“-” ,例Accept-Encoding,则要headerValues[“Accept-Encoding”]
47            --%>
48            ${header["Accept-Encoding"]}
49        <br/>--------------9、headerValues对象:headerValues获得请求头的值------------------------<br/>
50            <%--headerValues表示一个保存了所有http请求头字段的Map对象,它对于某个请求参数,返回的是一个string[]数组 
51            例如:headerValues.Accept返回的是一个string[]数组 ,headerValues.Accept[0]取出数组中的第一个值
52            --%>
53            ${headerValues.Accept[0]}<br/>
54            <%--${headerValues.Accept-Encoding} 这样写会报错
55                 测试headerValues时,如果头里面有“-” ,例Accept-Encoding,则要headerValues[“Accept-Encoding”]
56                 headerValues["Accept-Encoding"]返回的是一个string[]数组,headerValues["Accept-Encoding"][0]取出数组中的第一个值
57            --%>
58            ${headerValues["Accept-Encoding"][0]}
59        <br/>--------------10、cookie对象:cookie对象获取客户机提交的cookie------------------------<br/>
60        <!-- 从cookie隐式对象中根据名称获取到的是cookie对象,要想获取值,还需要.value -->
61            ${cookie.JSESSIONID.value}  //保存所有cookie的map
62        <br/>--------------11、initParam对象:initParam对象获取在web.xml文件中配置的初始化参数------------------------<br/>
63        <%--
64         <!-- web.xml文件中配置初始化参数 -->
65       <context-param>
66           <param-name>xxx</param-name>
67           <param-value>yyyy</param-value>
68       </context-param>
69       <context-param>
70           <param-name>root</param-name>
71           <param-value>/JavaWeb_EL_Study_20140826</param-value>
72       </context-param>
73         --%>
74        <%--获取servletContext中用于保存初始化参数的map --%>
75            ${initParam.xxx}<br/>
76            ${initParam.root}
77   </body>
    
 看到这里,大家应该很明确EL表达式只能通过内置对象取值,也就是只读操作,如果想进行写操作的话就让后台代码去完成,毕竟EL表达式仅仅是视图上的输出标签罢了。

注意:
测试header和headerValues时,如果头里面有“-” ,例Accept-Encoding,则要header[“Accept-Encoding”]、headerValues[“Accept-Encoding”]
测试cookie时,例 c o o k i e . k e y 取 的 是 c o o k i e 对 象 , 如 访 问 c o o k i e 的 名 称 和 值 , 须 {cookie.key}取的是cookie对象,如访问cookie的名称和值,须 cookie.keycookie访cookie{cookie.key.name}或${cookie.key.value}

调用Java方法

​ EL表达式语法允许开发人员开发自定义函数,以调用Java类的方法。语法:${prefix:method(params)}
  在EL表达式中调用的只能是Java类的静态方法,这个Java类的静态方法需要在TLD文件中描述,才可以被EL表 达式调用。
  EL自定义函数用于扩展EL表达式的功能,可以让EL表达式完成普通Java程序代码所能完成的功能。

编写html转义处理工具类,工具类中添加对html标签进行转义的静态处理方法,如下:
package me.gacl.util;
 2 
 3 /**
 4 * @ClassName: HtmlFilter
 5 * @Description: html转义处理工具类
 6 * @author: 孤傲苍狼
 7 * @date: 2014-8-27 上午12:09:15
 8 *
 9 */ 
10 public class HtmlFilter {
11 
12     /**
13     * @Method: filter
14     * @Description: 静态方法,html标签转义处理
15     * @Anthor:孤傲苍狼
16     *
17     * @param message 要转义的内容
18     * @return 转义后的内容
19     */ 
20     public static String filter(String message) {
21 
22         if (message == null)
23             return (null);
24 
25         char content[] = new char[message.length()];
26         message.getChars(0, message.length(), content, 0);
27         StringBuffer result = new StringBuffer(content.length + 50);
28         for (int i = 0; i < content.length; i++) {
29             switch (content[i]) {
30             case '<':
31                 result.append("&lt;");
32                 break;
33             case '>':
34                 result.append("&gt;");
35                 break;
36             case '&':
37                 result.append("&amp;");
38                 break;
39             case '"':
40                 result.append("&quot;");
41                 break;
42             default:
43                 result.append(content[i]);
44             }
45         }
46         return (result.toString());
47     }
48 }


在WEB-INF目录下编写标签库描述符(tld)文件,在tld文件中描述自定义函数
 <?xml version="1.0" encoding="UTF-8"?>
 2 <taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"
 3  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">
 4  <tlib-version>1.0</tlib-version>
 5  <short-name>EL Function</short-name>
 6  <!-- 
 7      自定义EL函数库的引用URI,
 8      在JSP页面中可以这样引用:<%@taglib uri="/ELFunction" prefix="fn" %> 
 9  -->
10  <uri>/ELFunction</uri>
11  
12  <!--<function>元素用于描述一个EL自定义函数 -->
13   <function>
14         <description>html标签转义处理方法</description>
15         <!--<name>子元素用于指定EL自定义函数的名称-->
16         <name>filter</name>
17         <!--<function-class>子元素用于指定完整的Java类名-->
18         <function-class>me.gacl.util.HtmlFilter</function-class>
19         <!--<function-signature>子元素用于指定Java类中的静态方法的签名,
20             方法签名必须指明方法的返回值类型及各个参数的类型,各个参数之间用逗号分隔。-->
21         <function-signature>java.lang.String filter(java.lang.String)</function-signature>
22     </function>
23  
24 </taglib>
    
在JSP页面中导入和使用自定义函数    
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%--引入EL自定义函数库 --%>
 3 <%@taglib uri="/ELFunction" prefix="fn" %>
 4 <!DOCTYPE HTML>
 5 <html>
 6   <head>
 7     <title>使用EL调用Java方法</title>
 8   </head>
 9   
10   <body>
11       <%--使用EL调用filter方法--%>
12       ${fn:filter("<a href=''>点点</a>")}
13   </body>
14 </html>
    

EL注意事项

EL表达式是JSP 2.0规范中的一门技术 。因此,若想正确解析EL表达式,需使用支持Servlet2.4/JSP2.0技术的WEB服务器。
注意:有些Tomcat服务器如不能使用EL表达式
(1)升级成tomcat6
(2)在JSP中加入<%@ page isELIgnored=“false” %>

JSTL

概述

STL全称为 JSP Standard Tag Library ,即JSP标准标签库。JSTL作为最基本的标签库,提供了一系列的JSP标签,实现了基本的功能:集合的遍历、数据的输出、字符串的处理、数据的格式化等等!

1、EL表达式不够完美,需要JSTL的支持!在JSP中,我们前面已经用到了EL表达式,体会到了EL表达式的强大功能:使用EL表达式可以很方便地引用一些JavaBean以及其属性,不会抛出NullPointerException之类的错误!但是,EL表达式非常有限,它不能遍历集合,做逻辑的控制。这时,就需要JSTL的支持了!
2、Scriptlet的可读性,维护性,重用性都十分差!JSTL与HTML代码十分类似,遵循着XML标签语法,使用JSTL让JSP页面显得整洁,可读性非常好,重用性非常高,可以完成复杂的功能!
3、在JSP中不推荐使用scriptlet(即JSP脚本中的<% Java代码 %>)输出,推荐使用JSP标签。

JSTL一共包含四大标签库

1、core:核心标签库,我们学习的重点;

2、fmt:格式化标签库,只需要学习两个标签即可;

3、sql:数据库标签库,不需要学习了,它过时了;

4、xml:xml标签库,不需要学习了,它过时了。

使用

core

core标签库是JSTL的核心标签库,实现了最基本的功能流程控制、迭代输出等操作!core标签库的前缀一般是c,是最常用的JSTL标签。

<c:set>

<c:if>

标签计算表达式,只有当表达式的值为true,则显示其主体内容。

同程序中的if作用相同,用来实现分支条件控制。 text属性用于存放判断的条件,一般使用EL表达式来编写; var属性是指定名称用来存放判断的结果类型为true或false; scope属性是用来存放var属性存放的范围。

<c:choose>

标签没有else的功能,如果需要类似于Java中的if else流程就需要使用choose标签。when标签的test为true时,会执行这个when的内容。当所有when标签的test都为false时,才会执行otherwise标签的内容。

通常这三个标签被放在一起使用。<c:choose>标签嵌套在<c:when>标签和<c:otherwise>标签的外面作为他们的父标签来使用;其中<c:choose>标签和<c:when>标签也可以单独一起组合使用。

 <c:choose>
           <c:when test="${param.score>=90&&param.score<=100}">
                  <c:out value="优秀" />
           </c:when>
           <c:when test="${param.score>=80&&param.score<90}">
                  <c:out value="良好" />
           </c:when>
           <c:when test="${param.score>=70&&param.score<80}">
                  <c:out value="中等" />
           </c:when>
           <c:when test="${param.score>=60&&param.score<70}">
                  <c:out value="及格" />
           </c:when>
           <c:when test="${param.score>=0&&param.score<60}">
                  <c:out value="不及格" />
           </c:when>
           <c:otherwise>
                  <c:out value="你的输入有问题!" />
           </c:otherwise>
     </c:choose>

<c:forEach>

根据循环条件遍历集合(Collection)中的元素。
var属性是设定变量名用于存储从集合中取出元素(必须无默认值);
items属性是指定要遍历的几个(必须无默认值);
begin属性和end属性是用于指定遍历的起始位置和终止位置(有默认);
step属性指定循环的步长(有默认);
varStatus属性通过index、count、first和last几个状态值,描述begin和end子集中的元素的状态。

<!--部分遍历-->
<c:set var="sum" value="0" /> 
<c:forEach var="i" begin="1" end="10"> 
	<c:set var="sum" value="${sum + i}" /> 
</c:forEach>
<c:out value="sum = ${sum }"/>

<!--部分遍历并且指定步长-->
<c:set var="sum" value="0" />
<c:forEach var="i" begin="1" end="10" step ="2">
	<c:set var="sum" value="${sum + i}" />
</c:forEach>
<c:out value="sum = ${sum }"/>

    
  <%
String[] names = {"zhangSan", "liSi", "wangWu", "zhaoLiu"};
pageContext.setAttribute("ns", names);
%>
<c:forEach var="item" items="${ns }">
	<c:out value="name: ${item }"/><br/>
</c:forEach>

    <%
	List<String> names = new ArrayList<String>();
	names.add("zhangSan");
	names.add("liSi");
	names.add("wangWu");
	names.add("zhaoLiu");
	pageContext.setAttribute("ns", names);
%>
<c:forEach var="item" items="${ns }">
	<c:out value="name: ${item }"/><br/>
</c:forEach>

    
    <%
	Map<String,String> stu = new LinkedHashMap<String,String>();
	stu.put("number", "N_1001");
	stu.put("name", "zhangSan");
	stu.put("age", "23");
	stu.put("sex", "male");
	pageContext.setAttribute("stu", stu);
%>
<c:forEach var="item" items="${stu }">
	<c:out value="${item.key }: ${item.value }"/><br/>
</c:forEach>

forEach标签还有一个属性:varStatus,这个属性用来指定接收“循环状态”的变量名,例如:<forEach varStatus=”vs” …/>,这时就可以使用vs这个变量来获取循环的状态了。

<c:forEach var="item" items="${ns }" varStatus="vs">
	<c:if test="${vs.first }">第一行:</c:if>
	<c:if test="${vs.last }">最后一行:</c:if>
	<c:out value="第${vs.count }行: "/>
	<c:out value="[${vs.index }]: "/>
	<c:out value="name: ${vs.current }"/><br/>
</c:forEach>
    
count:int类型,当前以遍历元素的个数;
index:int类型,当前元素的下标;
first:boolean类型,是否为第一个元素;
last:boolean类型,是否为最后一个元素;
current:Object类型,表示当前项目。

<c:forTokens>

该标签类似于String类的split()和for循环的一种集合。

它与forEach标签非常相似,都有begin、end、step、items、var、varStatus属性,不同的是forTokens标签的items属性里面是字符串,这个字符串会被delims属性的内容分割成多个字符串!

<c:forTokens items="zhongfucheng,ouzicheng,xiaoming,xiaohong" var="name" delims="," > 
    ${name}
</c:forTokens>

<c:import>

<c:import>标签提供jsp:include动作标签的所有的功能动作,但也可以包含绝对URL。例如,允许使用导入标签包含的内容从一个不同的Web站点或FTP服务器。

同jsp:include标签的区别:只能包含同一个Web应用中的文件,而<c:import>标签可以包含其他Web应用中的文件,甚至是网络上的资源。

可以把其他静态或动态文件包含到本JSP页面。

url属性指的是被导入资源的URL路径;

context属性指的是相同服务器下其他Web工程,必须以"/"开头;

var属性指的是以String类型存入被包含文件的内容;

scope属性指的是var变量的JSP范围;

charEncoding属性指的是被导入文件的编码格式 ;

varReade属性指的是以Reader类型存储被包含文件内容;

context属性引入的内容是webapps下的其他的Web project。

<h1>JSTL标签的使用</h1>
     <hr>
     <!-- import标签的用法 -->
     <!-- 导入网络上的绝对路径 -->
     <c:catch var="error09">
            <c:import url="https://www.baidu.com" charEncoding="UTF-8"  />
     </c:catch>
     <c:out value="${error09}" /><br/>
     <!-- 导入相对路径文件 -->
     <c:catch var="error08">
            <c:import url="test.txt" charEncoding="UTF-8" />
     </c:catch>
     <c:out value="${error08}" /><br/>
     <!-- var和scope属性的用法 -->
     <c:catch var="error07">
            <c:import url="test.txt" var="test" scope="session" charEncoding="UTF-8" />
     </c:catch>
     <c:out value="${error07}" />
     <c:out value="import标签存储的test字符串变量值为:${sessionScope.test}" /><br/>
     <!-- content属性的用法 -->
     <c:catch var="error06">
            <c:import url="/date.jsp" context="/FirstWebApp" charEncoding="UTF-8" />
     </c:catch>
     <c:out value="${error06}" />   
fmt
  • 概述

    使用JSTL格式标签来格式化和显示文本,日期,时间和数字的,国际化的网站。

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
......
<%
	Date date = new Date();
	pageContext.setAttribute("d", date);
%>
<fmt:formatDate value="${d }" pattern="yyyy-MM-dd HH:mm:ss"/>

  <%
	double d1 = 3.5;
	double d2 = 4.4; 
	pageContext.setAttribute("d1", d1);
	pageContext.setAttribute("d2", d2);
%>
<fmt:formatNumber value="${d1 }" pattern="0.00"/><br/>
<fmt:formatNumber value="${d2 }" pattern="#.##"/>

其他库暂不介绍(基本不用)
/>


<c:catch var=“error06”>
<c:import url="/date.jsp" context="/FirstWebApp" charEncoding=“UTF-8” />
</c:catch>
<c:out value="${error06}" />




#### fmt

- 概述

   使用JSTL格式标签来格式化和显示文本,日期,时间和数字的,国际化的网站。 

![](https://i-blog.csdnimg.cn/blog_migrate/916b55ff2b9b5e9ea2b80d4d67b39024.jpeg)



```java
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
......
<%
	Date date = new Date();
	pageContext.setAttribute("d", date);
%>
<fmt:formatDate value="${d }" pattern="yyyy-MM-dd HH:mm:ss"/>

  <%
	double d1 = 3.5;
	double d2 = 4.4; 
	pageContext.setAttribute("d1", d1);
	pageContext.setAttribute("d2", d2);
%>
<fmt:formatNumber value="${d1 }" pattern="0.00"/><br/>
<fmt:formatNumber value="${d2 }" pattern="#.##"/>

其他库暂不介绍(基本不用)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值