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));
    l ist2.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 >
          ```
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值