JSP-Basic

from:JSP


[toc]
#概述

* jsp全称是java server pages,它和servlet技术一样,都是sun公司定义的一种用于开发动态web资源的技术

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

* jsp的源代码可以分为:模板代码+元素(元素是jsp中的java部分:jsp的指令和标签等)

#原理

* jsp会被翻译成servlet,在tocamt的work\Catalina\localhost看到

* 不管是jsp还是servlet,在长期的软件实践中,人们逐渐把servlet作为web应用的控制器组件来使用,而把jsp技术作为数据显示模板来使用

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

* 让jsp即用java代码产生动态数据,又做美化会导致页面难以维护

* 让servlet即产生数据,以在里面嵌套html代码美化数据,同样也会导致程序可读性差,难以维护

* 因此最好的办法就是根据这两门技术的特点,让他们各自负责,servlet只负责响应请求产生数据,并把数据通过转发技术带给jsp,数据的显示jsp来做

#基础语法

* 模板元素

    * jsp中的html标记(负责页面的布局和美化,一般由美工负责)

* 表达式

    * <%=   %>: 用于输出内容

    注意:jsp中少用out.print()来输出

* 基本片段

    * <%  %>:可以定义局部变量和语句等,是在jsp的serlet源代码的service函数中

    * jsp的工作原理

    ```

    <%

        int age = 12;

        String name = "haoren";

        out.print(name + "有" + age + "岁");

    %>

    ```

    * <%!  %>:可以定义类、方法和全局变量,没有在service函数中

* 注释

    * 显示注释:<!--  -->(客户端可见:不是直接可以在页面上看到,而是检查代码元素时可以看到)

    * 隐式注释://,/* */,<%--   --%>(jsp注释)

* 循环

```

<%

    for (int i=0; i<10; i++){

%>

<font color="red">中国</font>

<%

    }

%>

```

#指令

* 概念

    * jsp指令是为jsp引擎而设计的,他们并不直接产生任何可见输出,而只是告诉引擎如何处理jsp页面中的其余部分,在jsp2.0规范中共定义了三个指令:Page、Include、Taglib

* Page指令

补充:一个import属性可以导入多个包,用逗号分隔

buffer:指示jsp用的输出流的缓存大小,默认是8kb

errorPage:指示当前页面出错后转向(转发)的页面,目标页面如果以"/"(当前应用)就是绝对路径

配置全局错误提示页面:

```

    web.xml

    <error-page>

    <exception-type>java.lang.Exception</exception-type>

    <location>/error.jsp</location>

    </error-page>

    <error-page>

    <error-code>404</error-code>

    <location>/404</location>

    </error-page>

```

    errorPage属性的设置值唯一路径(相对或绝对),如果"/"开头,表示相对于当前WEB应用程序的根目录(注意不是站点根目录),否则,表示相对当前页面

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

pageEncodiong和contentType区别:


    * pageEncodion设置由jsp到servlet的转码

    * contentType设置由servlet到页面的转码



* Include指令

    * Include指令就是包含重复的头部或者尾部页面,不用每个页面都重复写头部

    * 静态包含:先包含在执行,只会形成一个servlet文件,使用的是指令

    ```

    <%@ include  file="/head.jsp"%>

    内容

    <%@ include  file="/foot.jsp"%>

    ```

    * 动态包含:先执行再包含,会形成多个servlet文件,使用的是标签

    ```

    <jsp:include  page="/head.jsp">

        <jsp:param  value="haoren"  name="name" />

    </jsp:include>

    只能在被包含页面中取值(head.jsp):

    <%=request.getParameter("name")%>

    ```

    注意:静态包含效率比动态包含快(因此开发中多数使用静态包含),但是动态包含可以传参(注意名称和值位置是相反的)

* Taglib指令

    * 用于引入外部标签

    * 语法:<%@ taglib  uri="标签名称空间"  prefix="前缀"%>

    ```

    <%@ taglib  uri="http://java.sun.xom/jsp/jstl/core"  prefix="c"%> 

    ```

            "c"的作用相当前面动态包含中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大对象的引用

* 九个对象

    * Request:HttpServletRequest

    * Response:HttpServletResponse

    * Session:HttpSession(有开关:page指令的session属性的取值)

    * Application:servletContext(应用作用域)

    * Config:servletConfig

    * Page:this(当前servlet对象)

    * Exception:java.lang.Throwable(有开关:page指令的isErrorPage属性改为true)

    * Out:jspWriter

    * pageContext:javax.servlet.jsp.PageContext(最重要,可以通过它获取其它八个对象)

    作用域大小排行:Application>Session>Request>pageContext

* Session

    * Session是一次会话默认存活时间为30分钟或者关闭浏览器,其作用主要是保证一些界面必须要用户登陆后才能访问

    ```

    //在servlet中设置session会话,name是用于后面匹配,value是Session会话名(比如用户名)

    HttpSession hs = request.getSession();

    hs.setAttribute(name,value);

    //在另一个servlet中可以判断会话是否存在,存在表示用户登陆,不存在表示用户没登陆

    if(request.getSession().getAttribute(name)!=null)

        语句1;

    else

        语句2;

    ```

            removeAttribute(name);清除会话

* Out

    * 概念

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

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

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

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

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

            * out对象的缓冲区已满

            * 整个JSP页面结束

    * 工作原理图


    * 注意

        * 同时使用out和response.getWriter()输出数据,就会出现后者先输出,因为out会先将内容存入缓冲区,在没有关闭缓存以及缓冲已满的情况下只有页面结束时才会输出;jsp中少用字节流默认使用的是字符流,不要出现字节流和字符流混用

* pageContext

    * 概念

        * PageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其它8大隐式对象的引用,它自身还是一个域对象,可以用来保存数据。并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等

    * 三大作用

        * 本身是一个域对象,同时还能操作其他三个域对象(PageContext  ServletRequest  HttpSession  ServletContext)

        * 获取其他8个隐式对象

        * 提供了转发和包含的方便方法

        ```

        RequestDispatcher rd = request.getRequestDispatcher("/url")

        rd.forward(request,response);


        pageContext.forward("url");

        pageContext.include("url");

        ```

    * 获取其他对象

        * getException方法返回exception隐式对象

        * getPage方法返回page隐式对象

        * getRequest方法返回request隐式对象

        * getResponse方法返回response隐式对象

        * getServletConfig方法返回config隐式对象

        * getServletContext方法返回application隐式对象

        * getSession方法返回session隐式对象

        * getOut方法返回out隐式对象

    * 重点方法:findAttribute方法

       * 当四个域同时设置使用了setAttribute时,使用此方法查找属性会依据作用域从小往大匹配

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

#JSP标签

* 概念

    * jsp标签也称之为Jsp Action(JSP动作)元素,它用于在JSP页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护

* forward标签:用于把请求转发给另外一个资源

```

语法:<jsp:forward page = "url | <%=expression%>" />

```

    page属性用于指定请求转发到资源的相对路径,它可以通过执行一个表达式来获得

* include标签:用于包含需要重复使用的jsp页面

    * 前面include指令时已经介绍include标签

* param标签:用于传递参数

    ```

    <jsp:include page="url | <%=expression%>">

        <jsp:param value="Value | <%=expression%>" name="" />

   </jsp:include>

    <jsp:forward page="url | <%=expression%>">

        <jsp:param value="Value | <%=expression%>" name="" />

    </jsp:forward>

    ```

    * 当使用include和forward标签引入或将请求转发给其它资源时,可以使用param标签向这个资源传递参数

    * 在include和forward标签中可以使用多个param标签来传递多个参数

* 查错

    * jsp页面中的jsp语法格式有问题,导致其不能被翻译成servlet源文件,jsp引擎将提示这类错误发生在jsp页面中的位置(行和列)以及相关信息

    * jsp页面中的jsp语法格式没有问题,但被翻译成的servlet源文件中出现了java语法问题,导致jsp页面翻译成的servlet源文件不能通过编译,jsp引擎也将提示这类错误发生在jsp页面中的位置(行和列)以及相关信息

    * jsp页面翻译成的servlet程序在运行时出现异常,这与普通java程序的运行时错误完全一样,java虚拟机将提示错误发生在servlet源文件中的位置(行和列)以及相关信息

* JSP最佳实践

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

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

        * 让jsp既用java代码产生动态数据,又做美化会导致页面难以维护

        * 让servlet既产生数据,又在里面嵌套html代码美化数据,同样也会导致程序可读性差,难以维护

        * 因此最好的办法就是根据这两门技术的特点,让他们各自负责,servlet只负责响应请求产生数据,并把数据通过转发技术带给jsp,数据的显示jsp来做

* 四大域对象

    * 作用域大小排行:Application>Session>Request>pageContext

    * ServletContext(application):作用范围整个app(当前工程)

    * session:作用范围一次会话,浏览器打开到关闭为一次会话

    * request:作用范围一次请求,客户端与服务端一次交互

    * pageContext:作用范围当前页面

    * 注意:在够用的前提下,作用范围尽可能小

* JavaBean

    * JavaBean就是一个遵循特殊写法的普通类

    * JavaBean的要求

        * 必须有默认的构造方法

        * 所有字段定为私有的

        * 提供公有的get或set方法、方法

        * 一般实现java.io.Serializable(方便存储和网络传输)

        * 注意:在企业级开发中,JavaBean是用来传递数据

    * 三个动作元素

        * useBean:用于在jsp页面中查找或实例化一个javaBean组件

        * setProperty:用于在jsp页面中设置一个javaBean组件的属性

        * getProperty:用于在jsp页面中获取一个javaBean组件的属性

    * useBean:用于在指定域范围内查找指定名称的javaBean对象,找到了就直接使用,没有找到就创建一个,并放到指定的域范围内

        * 属性

            * id:必须,javaBean的名称

            * class:javaBean的完整类名(全限定名)

            * scope:域范围,默认是page。可选值:page、request、session、application

            * type:.:javaBean声明类型,class相当于具体类,type相当于抽象类、接口等

        * 注意:如果该标签有主体内容,只在创建新对象时才会执行(例如:将javaBean放在session中就只有第一次访问会执行方法体);type相当于是声明类型,它可以是接口,可以是类,可以是抽象类;class是对象类型,它必须是具体类;如果只有type那么bean必须存在,如果只有class那么它不能为抽象类且必须有一个公共无参构造函数,type与class必须要有继承或实现关系

    * setProperty

        * name属性用于指定javaBean对象的名称

        * property属性用于指定javaBean实例对象的属性名

        * value属性用于指定javaBean对象的某个属性值,value的值可以是字符串,也可以是表达式(日期用表达式就比较好),为字符串时,该值会自动转化为javaBean属性相应的类型,如果value的值是一个表达式,那么该表达式的计算结果必须与所要设置的javaBean属性的类型一致

        * param属性用于将javaBean实例对象的某个属性值设置为一个请求参数值,该属性值同样会自动转换成要设置的javaBean属性的类型

    * getProperty:用于读取javaBean对象的属性,也就是调用javaBean对象的get方法,然后将读取的属性值转换成字符串后插入进输出的响应正文中

        * name属性用于指定javaBean实例对象的名称,其值应与useBean标签的id属性值相匹配

        * property属性用于指定javaBean实例对象的属性名

        * 如果一个javaBean实例对象某个属性值为null,那么输出该属性的结果将是null

    ```

    第一种:(通过参数名和属性名自动匹配)

    <jsp:useBean id="person" class="com.java.Person" scope="page">

    </jsp:useBean>

    <jsp:setProperty property="*" name="person" />

    <%=person.getName() %>

    <%=person.getAge() %>

    第二种:(通过指定属性名)

    <jsp:setProperty property="name" name="person" />

    第三种:(设置表单属性)

    <jsp:setProperty property="name" name="person" param="age" />(age代表表单文本框名字)

    第四种:直接赋值

    <jsp:setProperty name="person" property="name" value="haoren">

    <jsp:useBean id="person" class="com.java.Person" scope="request">

    </jsp:useBean>

    <jsp:getProperty property="count" name="person" />

    <!--移除javaBean-->

    <%request.removeAttribute("person"); %>

    ```

                setProperty可以放在useBean里面,放在里面只有当useBean没有找到javaBean对象自动创建时才会执行,在外面会覆盖javaBean对象相同属性值

#EL表达式

* 开发原则:jsp页面中不能出现一行java脚本<%%>和java表达式<%=%>

    * java脚本:替代方案,自定义标签

    * java表达式:替代方案,EL表达式,Struts2框架:OGNL表达式(学好Struts重点学好OGNL)

* 好处:如果取得的值是空,则返回""而不是null

```

<%pageContext.setAttribute("name","page") %>

${pageScope.name}

```

* 访问四大域

```

<%

pageContext.setAttribute("name","page");

request.setAttribute("name","request");
session.setAttribute("name","session");

application.setAttribute("name","application");

%>

${name}   <!--会在四大域中从小到大的查询,找到第一个就终止查询-->

${pageScope.name}

${requestScope.name}

${sessionScope.name}

${applicationScope.name}

```

* 接受请求参数

    * ${param.name}(接受表单提交的数据)

* 接受一组参数

```

<form action="" method="">

    <input type="checkbox" name="enjoy" value="打架" checked="checked">打架

    <input type="checkbox" name="enjoy" value="打人">打人

    <input type="checkbox" name="enjoy" value="打球">打球

    <input type="submit" value="提交" />

</form>

<%request.setCharacterEncoding("utf-8")>

${paramValues.enjoy[0]}

${paramValues.enjoy[1]}

${paramValues.enjoy[2]}

```

* 集合操作

    * List集合

    ```

    List list = new ArrayList();

    list.add("中国1");

    list.add("中国2");

    list.add("中国3");

    request.setAttribute("list",list);  //通过转发到jsp

    ${list[0]}

    ${list[1]}

    ${list[2]}

    ```

    * Map集合

    ```

    Map map = new HashMap();

    map.put("name","haoren");

    map.put("gender","M");

    request.setAttribute("map",map);  //通过转发到jsp

    ${map.name}

    ${map["gender"]}

    ```

            注意:在一些特殊(取不符合java命名规范、数组、集合等)的情况下只能用"[]",而不能用"."运算,例如:${header["accept-encoding"]}查询头部信息,java命名中不能有"-"

    ```

    //[]中加引号与不加的区别

    Map map = new Map();

    map.put("user","haoren");

    request.setAttribute("map",map);

    request.setAttribute("map1","user");

    ${map[map1]}   //haoren,没有引号会计算,由于有一个"map1"的请求,其值为"user",而且"user"是map的一个键

    ${map["map1"]}  //没有值,加了引号就不会计算,因为map没有名为"map1"的键,容器会认为其是map的一个键

    ```

    * 访问对象的属性

    ```

    Person p = new Person();

    p.setName("haoren");

    p.setAge("23");

    request.setAttribute("person",p);  //通过转发到jsp

    ${person.name}

    ${person.age}

    ```

    * 集合里装对象

    ```

    Map<Person> map = new HashMap<Person>();

    map.put("p1",new Person("haoren"));

    map.put("p2",new Person("huairen"));

    request.setAttribute("map",map);  //通过转发到jsp

    ${map.p1.name}

    ${map.p2.name}

    ```

    * 对象属性是集合的情况

    ```

    List<Student> list1 = new ArrayList<Student>();

    list1.add(new Student("haoren1"));

    list1.add(new Student("haoren2"));

    List<Teacher> list2 = new ArrayList<Teacher>();

    list2.add(new Teacher("huairen1",list1));

    list2.add(new Teacher("huairen2",list1));

    School school = new School();

    school.setName("ren");

    School.setList(list2);

    request.setAttribute("school",school);  //通过转发到jsp

    ${school.name}   //查询school对象的name

    ${school.list[0].name}  //查询school中list[0]对象的name

    ${school.list[0].list[1].name} //查询school中list[0]中list[1]对象的name

    ```

            注意:集合查询实际就是一层层的查询,从父级一级一级的往下查;一个实体类中包含了另一个类的集合就可以表示"1对n"的关系,一个实体类中掌握另一个类的分类属性例如部门编号就可以表示"n对1"的关系

* 算术

    * el表达式可以进行算术,关系运算和逻辑运算

        * ${1+2}

        * ${2<3&&1>2}

    * el表达式不支持字符串连接操作

    * empty运算符:判断对象是null或者空字符串就会返回true,对于集合即使集合对象本身不是null且没有任何元素也会返回true

    ```

    <jsp:useBean id="p" class="com.test.Person"></jsp:useBean>

    ${empty p}  //返回true

    ${empty ""}  //返回true

    <%session.setAttribute("user","haoren")%>

    ${empty user?"请登录":"欢迎"}${user}

    <%pageContext.setAttribute("gender","0")%>

    ${gender=="0"?"女":"男"}

    ```

* 11大EL内置对象

    * pageContext

    * pageScope

    * requestScope

    * sessionScope

    * applicationScope

    * param

    * paramValues

    * Header

    * headerValues

    * cookie

    * initParam

* EL常用函数

    * 首先要引用function标签库

    ```

    <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> 

    ```

    * contains函数:用于判断在源字符串中是否包含目标字符串,返回布尔类型,区分大小写

    ```

    ${fn:contains("Tomcat","cat")}  //true

    ```

    * containsIgnoreCase函数:用于判断是否包含目标字符串,不区分大小写

    ```

    ${fn:containsIgnoreCase("Tomact","CAT")}  //true

    ```

    * startsWith函数:用于判断源字符串是否以指定目标字符串开头,返回布尔类型

    ```

    ${startsWith("Tomcat","Tom")}  //true

    ```

    * endsWith函数:判断源字符串是否以指定目标字符串结尾,返回布尔类型

    ```

    ${endsWith("Tomcat","cat")}  //true

    ```

    * indexOf函数:在源字符串中查找目标字符串,并返回源字符串中最先与目标字符串匹配的第一个字符索引,如果没有找到目标就返回-1,索引以0开头,返回整型

    ```

    ${fn:indexOf("Tomcat","cat")}   //3

    ```

    * replace函数:把源字符串中的一部分替换为目标字符串,并返回替换后的字符串

    ```

    ${fn:replace("2012/02/02","/","-")}  //2012-02-02

    ```

    * substring函数:获取源字符串中的特点子字符串,含头不含尾,返回字符串

    ```

    ${fn:substring("Tomcate",0,3)}  //Tom

    ```

    * substringBefore函数:获取源字符串指定子字符串之前的子字符串,返回字符串

    ```

    ${fn:substringBefore("Tomacat","cat")}  //Toma

    ```

    * substringAfter函数:获取源字符串中指定子字符串之后的子字符串,返回字符串

    ```

    ${fn:substringAfter("Tomcat","Tom")}  //cat

    ```

    * split函数:将源字符串拆分为一个字符串数组,若不存在拆分目标就返回源字符串,返回字符串数组

    ```

    //引用了core核心标签库,set是创建变量,value表示值,var表示变量

    <c:set value='${fn:split("www.baidu.com",".")}' var="strs" />

    //遍历数组

    <c:forEach var="token" items="${strs}">

        ${token}

    </c:forEach>   //www      baidu       com

    ${strs[0]}   //www

    ```

    * join函数:将源字符串数组中的所有字符串连接为一个字符串,必须要有分隔符,若不想要也要用空串代替,返回字符串

    ```

    <%String[] s = {"www","baidu","com"}%>

    <c:set value="<%=s%>" var="s" />

    ${fn:join(s,".")}  //www.baidu.com    

    ${fn:join(s,"")}    //wwwbaiducom

    ```

    * toLowerCase函数:将源字符串中的所有字符改为小写,返回字符串

    ```

    ${fn:toLowerCase("TomCat")}  //tomcat

    ```

    * toUpperCase函数:将源字符串中的所有字符改为大写,返回字符串

    ```

    ${fn:toUpperCase("TomCat")}  //TOMCAT

    ```

    * trim函数:将源字符串中的开头和结尾的空格删除,返回字符串

    ```

    ${fn:trim("   tomcat   ")}  //tomcat

    ```

    * escapeXml函数(重点):将源字符串中的字符"<"、">"、"""、"&"等转换为转义字符,其与<c:out>标签中excapeXml属性为true时的效果是相同的,也就是让脚本失效,返回字符串

    ```

    <c:out value="<b>粗体字</b>" excapeXml="true"></c:out>  //<b>粗体字</b>

    ${fn:excapeXml("<b>粗体字</b>")}  //<b>粗体字</b>

    <b>粗体字</b>  //粗体字(字体已经加粗)

    ```

    * length函数:返回字符串中的字符个数、集合、数组元素个数,没有返回0,返回整型

    ```

    <%

        List list = new ArrayList();

        list.add("hao");

        list.add("hao");

        String[] s = {"f","d","s"};

    %>

    <c:set value="<%=s%>" var="s" />

    <c:set value="<%=list%>" var="list" />

    ${fn:length(s)}  //3

    ${fn:length(list)}  //2

    ${fn:length("Tomcat")}  //6

    ```

    * EL自定义函数

        * 编写一个普通的java类,提供一个静态方法(必须是静态)

        ```

        //编写方法

        public class FunctionTest{

            public static String ChangeDate(Date date,String format){

                SimpleDateFormat sdf = new SimpleDateFormat(format);

                return sdf.Format(date);

            }

        }

        ```

        * 在JavaWeb应用的WEB-INF目录下建立一个扩展名为"tld(taglib definition)"的file文件,参考Tomcat中的示例

        ```

        <?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">

            <description>A tag library exercising SimpleTag handlers.</description>

            <tlib-version>1.0</tlib-version>

            <short-name>SimpleTagLibrary</short-name>

            <uri>http://tomcat.apache.org/java/MyFunctions</uri>

            <function>

            
<name>Function</name>

            
<function-class>com.test.function.MyFunction</function-class>

            
<function-signature>java.lang.String Function( java.util.Date,java.lang.String )</function-signature>

            </function>

        </taglib>

        ```

                uri内的网址是自定义的,name是方法名,function-class是类的全限定名,function-signature内外面是返回值的全限定名+空格+方法名(参数的全限定名)

        * 调用方法

        ```

        <%@ taglib uri="http://tomcat.apache.org/java/MyFunctions" prefix="myfun" %>

    <% Date date = new Date(); pageContext.setAttribute("date", date); %>

    ${myfun:Function(date,"yyyy-MM-dd") }

        ```

    * EL保留关键字

    

        * 所谓保留字的意思是指变量在命名时,应该避开上述的名字,以免程序编译时发生错误

* JSTL

    * 引入标签

    ```

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 

    ```

    * out:输出

    ```

    <c:out value="haoren" default="" escapeXML="true/false">

    ```

            value表示值;default表示默认值,在value没有找到的情况下启用;escapeXML表示是否转换特殊字符,默认为true

    * set:创建变量或者实例化javaBean对象

    ```

    <c:set var="aa" value="ddd" scope="request" />

    <jsp:useBean id="person" class="com.java.Person" scope="request" />

    <c:set value="haoren" property="name" target="${person}">

    ${person.name}

    ${aa}

    ```    

            var表示变量名,value表示值,scope表示作用域,target表示javaBean对象(只能是javaBean对象或者java.util.Map对象),property表示对象属性名(与target一同出现)

    * remove:删除

    ```

    <c:remove var="name" scope="request">

    ```

            var表示变量名,scope表示作用域;如果将一个变量删除后就输出的其默认default值

    * catch:异常

    ```

    <c:catch var="e">

        <%

            int a = 2 / 0;

        %>

    </c:catch>

    ${e}

    ```

    * if

    ```

    <c:if test="${1<2}" var="aa" scope="request">

        1小于2

    </c:if>

    ${aa}

    ```

            test相当于括号的作用,var保存的是逻辑值,为真就执行里面的代码

    * choose:相当于switch,但是比其更好用,chosse可以区间匹配,switch只能单值匹配

    ```

    <%request.setAttribute("score","99")%>

    <c:choose>

        <c:when test="${score>90}">优秀</c:when>

        <c:otherwise>不及格</c:otherwise>

    </c:choose>

    ```

            when相当与cath,otherwise设置默认值,当没有匹配值时执行,EL表达式中整数相除若为浮点型会自动转换

    * forEach:遍历

    ```

    <% int[] a = {1,2,3,4,5,6}; request.setAttribute("a",a);%>

    <c:forEach items="${a}" var="a" step="2" begin="1" end="4">

        ${a}

    </c:forEach>

    ```

            step表示个数按2的倍数输出(中间跳过一个),begin表示从此下标位开始,end表示到此下标结束,下标从0开始,含头也含尾

    * 集合输出

    ```

    <%

    Map map = new HashMap();

    map.put("name","haoren");

    map.put("gender","M");

    request.setAttribute("map",map);

    %>

    <c:forEach items="${map}" var="map">

        ${map.key}:${map.value}

    </c:forEach>

    ```

    * forTokens:可以快速切字符串

    ```

    <%

    String city = "成都,上海,天津,广州";

    request.setAttribute("city",city);

    %>

    <select>

    <c:forTokens items="${city}" delims="," var="city">

        <option value="${city}">${city}</option>

    </c:forTokens>

    </select>

    ```

            delims表示设置切割符,这么做的好处可以将后台取来的数据快速整理

    * import:相当于包含

    ```

    <c:import url="index.jsp">

        <c:param name="name" value="haoren" />

    </c:import>

    <!-- index.jsp中 -->

    ${param.name}

    ```

            url表示路径定位器,import相比包含多了连接外网的能力

    * redirect:跳转

    ```

    <c:redirect url="index.jsp">

        <c:param name="name" value="haoren" />

    </c:redirect>

   <!-- index.jsp中 -->

    ${param.name}

    ```

            redirect相当于跳转中的重定向,地址会发生变化

    * 自定义标签

        * 定义标签类继承TagSupport类

        ```

        public class MyCore extends TagSupport{

            public int doStartTag() throws JspException{

                JspWrite out = this.pageContext.getOut();

                try{

                
out.print("haoren");


                }
catch(IOException e){

                
throw new RuntimeException(e);


                }

                return TagSupprot.SKIP_BODY;

            }

        }

        ```

        * 注册标签

        ```

        <?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">

            <description>A tag library exercising SimpleTag handlers.</description>

            <tlib-version>1.0</tlib-version>

            <short-name>SimpleTag</short-name>

            <uri>http://tomcat.apache.org/java/MyCore</uri>

            <tag>

            
<name>Function</name>

            
<function-class>com.test.function.MyFunction</function-class>

            
<function-signature>java.lang.String Function( java.util.Date,java.lang.String )</function-signature>

            </function>

        </taglib>

        ```