zoukankan      html  css  js  c++  java
  • 12JSP进阶

    1.EL表达式

    1.1 简介

    EL表达式替代jsp表达式。因为开发jsp页面的时候遵守原则:在jsp页面中尽量少些甚至不写java代码。

    EL表达式作用:向浏览器输出域对象中的变量或表达式计算的结果

    基本语法: ${变量或表达式}    代替<%=变量或表达式%>

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    
    <title>EL基础语法</title>
    
    </head>
    
    <body>
    
        <%
            String name = "eric";
            //把变量放入域对象中
            //pageContext.setAttribute("name", name);
            pageContext.setAttribute("name", name, PageContext.REQUEST_SCOPE);
        %>
        <%=name%>
        <br /> EL表达式:${name}
        <%--
          1)EL从四个域中自动搜素
              ${name} 等价于:  <%=pageContext.findAttribute("name")%>
           --%>
    
        <%--
           2)EL从指定域中获取
                   pageScope: page域
                   requestScope: request域
                   sessionScope: session域
                   applicationScope: application域
            --%>
        指定域获取的EL: ${pageScope.name }
    
    </body>
    </html>

    1.2 EL获取不同类型的数据

    普通字符串

    普通的对象

    数组或List集合

    Map集合

    <%@ page language="java" import="java.util.*,cn.jxufe.entity.*"
        pageEncoding="UTF-8"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    
    <title>EL获取不同类型的数据</title>
    
    </head>
    
    <body>
    
        <%--
        1)普通的字符串
         --%>
        <%
            String email = "zhangsan@qq.com";
            //一定要把数据放入域中
            pageContext.setAttribute("email", email);
        %>
        普通字符串: ${email }
        <hr />
    
        2)普通的对象 EL表达式的属性表示调用对象的getXX方法.例如 student.name 调用了Stduent对象的getName()方法
        --%>
        <%
            Student student = new Student("eric", "123456");
            pageContext.setAttribute("student", student);
        %>
        <br /> 普通的对象: ${student}
        <br /> 对象的属性: ${student.name1 } - ${student.password }
        <hr />
        <%--
           3)数组或List集合
            --%>
        <%
            //数组
            Student[] stus = new Student[3];
            stus[0] = new Student("jacky", "123456");
            stus[1] = new Student("rose", "123456");
            stus[2] = new Student("lucy", "123456");
            pageContext.setAttribute("stus", stus);
            //List
            List<Student> list = new ArrayList<Student>();
            list.add(new Student("eric", "123456"));
            list.add(new Student("lily", "123456"));
            list.add(new Student("maxwell", "123456"));
            pageContext.setAttribute("list", list);
        %>
        <br /> 数组:
        <br /> ${stus[0].name1 } - ${stus[0].password }
        <br /> ${stus[1].name1 } - ${stus[1].password }
        <br /> ${stus[2].name1 } - ${stus[2].password }
        <br />
        <br /> List集合
        <br /> ${list[0].name1 } - ${list[0].password }
        <br /> ${list[1].name1 } - ${list[1].password }
        <br /> ${list[2].name1 } - ${list[2].password }
        <hr />
        4) Map集合 --%>
        <%
            Map<String, Student> map = new HashMap<String, Student>();
            map.put("001", new Student("eric", "123456"));
            map.put("002", new Student("jacky", "123456"));
            map.put("003", new Student("rose", "123456"));
            pageContext.setAttribute("map", map);
        %>
        Map集合:
        <br /> ${map['001'].name1 } - ${map['001'].password }
        <br /> ${map['002'].name1 } - ${map['002'].password }
        <br /> ${map['003'].name1 } - ${map['003'].password }
        <br />
    </body>
    </html>

    1.3 EL执行表达式

    算术表达式

    比较表达式

    逻辑表达式

    判空表达式

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    
    <title>EL执行表达式</title>
    
    </head>
    
    <body>
        <%--
        1)算术表达式: + - * /
        
         --%>
        <%
            int a = 10;
            int b = 5;
            pageContext.setAttribute("a", a);
            pageContext.setAttribute("b", b);
        %>
        ${a+b }
        <br /> ${a-b }
        <br /> ${a*b }
        <br /> ${a/b }
        <hr />
    
        <%--
          2)比较表达式: >  < >= <= ==
           --%>
        ${a>b }
        <br /> ${a==b }
        <br />
    
        <hr />
        <%--
          3)逻辑表达式:  && (与)   || (或)   !(非)
           --%>
        ${true&&true }
        <br /> ${true||false }
        <br /> ${!true }
        <br /> ${!(a>b) }
    
        <hr />
        <%--
           4)判空表达式      empty
                   null==null
                   空字符串: ==""
            --%>
        <%
            //String name1 = null;
            String name1 = "";
            pageContext.setAttribute("name1", name1);
        %>
        null: ${name1==null }
        <br /> 空字符串: ${name1=="" }
        <br /> null或空字符串: ${name1==null || name1=="" }
        <br /> null或空字符串:${empty name1}
    
    </body>
    </html>

    1.4 EL的11个内置对象

    pageContext

    pageScope

    requestScope

    sessionScope

    applicatinoScope

    param

    paramValues

    header

    headerValues

    cookie

    initParam

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    
    <title>EL的11个内置对象</title>
    
    </head>
    
    <body>
        <%--
        1)pageContext  等价于  jsp的pageContext内置对象
         --%>
        <%--获取上下文路径 --%>
        ${pageContext.request.contextPath }
        <hr />
        <%--
         pageScope
        requestScope
        sessionScope
        applicatinoScope
        从指定的域中获取数据 
          --%>
    
        <%--
          2)param: 获取参数
            注意: param返回所有参数Map集合
           --%>
        <%=request.getParameter("name")%><br />
        <br /> ${param['name']}
        <%=request.getParameterValues("name")[1]%>
        <br /> ${paramValues['name'][0] }-${paramValues['name'][1] }
        <hr />
        <%--
           3) header :获取请求头
              headerValues
            --%>
        <%=request.getHeader("host")%><br />
        <%=request.getHeaders("host").nextElement()%><br /> ${header['host'] }
        <br /> ${headerValues['host'][0] }
        <%--
               4)cookie: 获取cookie
           
            --%>
        <hr />
        <%=request.getCookies()[0].getValue()%><br />
        ${cookie['JSESSIONID'].name } - ${cookie['JSESSIONID'].value }
        <hr />
        <%--
            5)  initParam: 获取全局参数
             --%>
        <%=application.getInitParameter("AAA")%><br /> ${initParam['AAA'] }
    
    </body>
    </html>

    2.Jsp标签

    2.1 简介

    EL表达式可以替换jsp表达式,但是EL表达式局限:

    不能条件判断,不能赋值,不能迭代。

    jsp标签替代jsp脚本,完成条件判断,赋值,迭代等等功能。

    2.2 Jsp标签分类

    1)jsp内置标签(动作标签): 使用的时候不需要导入标签库

    2)jstl标签(标准标签): 使用的时候都需要导入标签库

    3)自定义标签:使用的时候都需要导入标签库

    2.3 动作标签

    <jsp:forward/>   转发标签

    <jsp:param/>    参数标签

    <jsp:include/>    包含标签

    注意:

    包含标签的原理是包含与被包含的页面单独翻译成不同的java文件,然后再运行时合并在一起。                                                        (先翻译再合并,动态包含)

    静态包含 vs  动态包含

    静态包含: 先合并再翻译。不能携带参数

    动态包含: 先翻译再合并。携带参数

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    
    <title>动作标签</title>
    
    </head>
    
    <body>
    
        <%--
        1)<jsp:foward/>  转发
         --%>
        <%
            //request.getRequestDispatcher("/01el3.jsp").forward(request, response);
        %>
        <%-- <jsp:forward page="/01el3.jsp"></jsp:forward> --%>
    
        <%--注意: 一定要使用jsp注释来注释标签
         <jsp:forward page="/02action2.jsp">
            <jsp:param value="eric" name="name" />
            <jsp:param value="jacky" name="name" />
        </jsp:forward>
        --%>
        <%--
           3<jsp:include/> 动态包含。可以携带参数给被包含的页面,但是静态包含不能携带参数给被包含的页面
            --%>
        <jsp:include page="/common/header.jsp">
            <jsp:param value="eric" name="name" />
        </jsp:include>
        主页内容
    
    
    
    </body>
    </html>
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    
    <title>My JSP 'header.jsp' starting page</title>
    
    </head>
    
    <body>
    
        通用的头部页面<br/> 接收参数: ${param['name'] }
        <hr />
    
    </body>
    </html>
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    
    <title>动作标签</title>
    
    </head>
    
     <body>
           接收参数 :  ${paramValues['name'][0] } -${paramValues['name'][1] } 
     </body>
    </html>

    2.4 JSTL标签

    jstl标签,java standard tag libarary java标准标签库。

    特点: 在使用jstl标签时需要导入标签库

    jstl标签库分类:

    核心标签库(重要)

    国际化标签库(fmt)

    EL函数库(fn)

    SQL标签库(sql)

    XML标签库(x)

    2.5 使用JSTL标签

    1)导入jstl的支持jar包,在java5.0之后jstl已经是属于5.0的支持包里面。

    2)使用jsp页面,需要在jsp的顶部使用taglib指令导入需要的标签库

    3)使用标签:

    <c:set/>

    2.6 核心标签库的标签

    保存数据:

    <c:set></c:set>

    获取数据:

    <c:out value=""></c:out>

    单条件判断

    <c:if test=""></c:if>

    多条件判断

    <c:choose></c:choose>

    <c:when test=""></c:when>

    <c:otherwise></c:otherwise>

    用于迭代(循环)

    <c:forEach></c:forEach>

    <c:forTokens items="" delims=""></c:forTokens>

    重定向

    <c:redirect></c:redirect>

     

    <%@ page language="java" import="java.util.*,cn.jxufe.entity.*"
        pageEncoding="UTF-8"%>
    <%--导入核心标签库 --%>
    <%--
        uri: 表示需要导入的标签库的uri名称。每个标签库都会有一个tld后缀名的标签声明文件,在tld文件中都有唯一的uri的名称。这个uri的名称就是当前标签库的名称。
        prefix: 使用标签库的前缀,通用和tld文件的short-name名称相同
     --%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    
    <title>核心标签库</title>
    
    </head>
    
    <body>
    
        <%-- 1) <c:set/> 给域对象赋值 --%>
        <%
            //String name = "eric";
            //pageContext.setAttribute("name",name);
        %>
        <%--
              var: 数据的名称
              value: 保存的数据值
              scope: 保存到哪个域。
                  page-》page域
                  requset->request域
                  session->session域
                  application->application域
           --%>
        <c:set var="name" value="jacky" scope="request" />
        ${name}
        <hr />
        <%--
          2) <c:out/>   获取域对象的数据
           --%>
    
        <%--
              value: 代表获取域中的某个名称内容。如果数据在域中,必须使用EL语法去获取
              default: 默认值。当前需要获取的内容为null,那么使用默认值代替
              escapeXml: 默认情况下为true,out标签会把输入的内容进行转义。如果不需要转义,则为false既可!
           --%>
        <c:out value="${name}" default="<h3>标题3</h3>" escapeXml="false"></c:out>
        <hr />
        <%--
            3) <c:if/> 单条件判断
             --%>
        <%--
             test: 条件表达式。返回true的时候,就会执行if标签体内容,否则,不执行。
              --%>
        <c:if test="${10>8}">
            <input type="submit" value="提交" />
        </c:if>
        <hr />
        <%--
                4) <c:choose/>+<c:when/>+<c:otherwise/>  多条件判断
                
                登录之后,一定会把数据存放到session域,user名称
                    session.setAttribute("user",user);
             --%>
        <%--模拟登录 --%>
        <c:set var="user" value="eric" scope="session"></c:set>
    
        <c:choose>
            <c:when test="${!empty sessionScope.user}">
                     欢迎回来,你的用户名是 :eric,<a href="">【退出登录】</a>
            </c:when>
            <c:otherwise>
                     请先<a href="">注册</a><a href="">登录</a>
            </c:otherwise>
        </c:choose>
    
        <hr />
        <%--
            5) <c:forEach/>   用于迭代或循环
             --%>
        <%
            //List
            List<Student> list = new ArrayList<Student>();
            list.add(new Student("eric", "123456"));
            list.add(new Student("lily", "123456"));
            list.add(new Student("maxwell", "123456"));
            pageContext.setAttribute("list", list);
        %>
        <hr />
        <%--
             begin: 从哪个元素开始遍历,从0开始
             end: 到哪个元素位置
             step: 增加步长。默认step为 1
             items: 需要遍历的数据。(数组|List集合|Map集合) 如果是获取域数据,那么使用EL表达式获取
             var: 每个元素名称
             varStatus: 当前状态对象。该对象封装当前元素状态信息。  例如 count属性: 表示当前遍历的是哪个元素,从1开始
              --%>
        List集合:
        <br />
        <c:forEach items="${list}" var="student" varStatus="varSta">
                序号:${varSta.count }   姓名:${student.name1 } - 密码: ${student.password }<br />
        </c:forEach>
        <c:forEach begin="0" end="3" step="2" items="${list}" var="student"
            varStatus="varSta">
        序号:${varSta.count } 姓名:${student.name1 } 密码:${student.password }<br />
        </c:forEach>
    
        <hr />
    
        <%
            Map<String, Student> map = new HashMap<String, Student>();
            map.put("001", new Student("eric", "123456"));
            map.put("002", new Student("jacky", "123456"));
            map.put("003", new Student("rose", "123456"));
            pageContext.setAttribute("map", map);
        %>
    
        Map集合:
        <br />
        <%--
                 注意: forEach标签遍历Map集合时,把每个Map的对象使用Entry封装,
                     Entry封装键对象和值对象,通过getKey()获取键对象,通过getValue()获取值对象
              --%>
        <c:forEach items="${map}" var="entry">
                  编号: ${entry.key } - 姓名:${entry.value.name1 } - 密码: ${entry.value.password }<br />
        </c:forEach>
    
        <hr />
        <%--
             6)  <c:forToekens/>   遍历特殊字符串
              --%>
        <c:set var="str" value="java-net-php-平面设计"></c:set>
        <%
            String str = (String) pageContext.getAttribute("str");
            String[] strs = str.split("-");
            for (int i = 0; i < strs.length; i++) {
                out.write(strs[i] + ",");
            }
        %>
        <br />
        <%--
              items: 需要遍历的字符串
              delims: 指定分割符号
              var: 每个内容的名称
               --%>
        <c:forTokens items="${str}" delims="-" var="s">
                      ${s },
        </c:forTokens>
        <hr />
    
        <%--
              7) <c:rediect/>  重定向标签
               --%>
        <%
            //response.sendRedirect(request.getContextPath()+"/03.el3.jsp");
        %>
        <%-- <c:redirect url="/01el3.jsp"></c:redirect> --%>
    </body>
    </html>

    2.7 自定义标签

    当现有的标签无法满足需求的时候,就需要开发者自行开发标签。

     

    需求: 获取客户端的IP地址

    开发步骤:

    1)开发标签处理程序,是一个普通的java类,继承SimpleTagSupport类,覆盖doTag方法

    package cn.jxufe.a_tag;
    
    import java.io.IOException;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.jsp.JspContext;
    import javax.servlet.jsp.JspException;
    import javax.servlet.jsp.JspWriter;
    import javax.servlet.jsp.PageContext;
    import javax.servlet.jsp.tagext.SimpleTagSupport;
    
    /*
     *  自定义标签的标签处理程序
     */
    public class ShowIpTag extends SimpleTagSupport {
    
        /*    private JspContext jspContext;
        
            // 用于设置PageContext对象
            // JspContext是PageContext的父类,实际传入的是PageContext对象
            @Override
            public void setJspContext(JspContext pc) {
                this.jspContext = pc;
            }
        */
        @Override
        public void doTag() throws JspException, IOException {
            // TODO Auto-generated method stub
            // 1)获取客户端ip
            PageContext pageContext = (PageContext) this.getJspContext();
            // 2)通过PageContext获取到其他8个内置对象
            HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
            String ip = request.getRemoteHost();
    
            // 3)把ip输入给浏览器
            JspWriter out = pageContext.getOut();
            out.write("当前客户端的IP为:" + ip);
        }
    }

    2)在项目的WEB-INF目录下建立一个tld文件,例如jxufe.tld,内容可以参考核心标签库的c.tld内容

    <?xml version="1.0" encoding="UTF-8" ?>
    
    <taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
        version="2.1">
    
        <!-- 标签的版本号 -->
        <tlib-version>1.1</tlib-version>
        <!-- 简单名称,用于使用标签库的前缀 -->
        <short-name>jxufe</short-name>
        <!-- 是标签库的唯一名称 -->
        <uri>http://jxufe.cn</uri>
    
        <!-- 定义一个标签 -->
        <tag>
            <!-- 标签名称 -->
            <name>showIp</name>
            <!-- 标签处理程序的全名: 包名+类名 -->
            <tag-class>cn.jxufe.a_tag.ShowIpTag</tag-class>
            <!-- 标签体内容输出格式 -->
            <body-content>scriptless</body-content>
        </tag>
    
        <tag>
            <!-- 标签名称 -->
            <name>parent</name>
            <!-- 标签处理程序的全名: 包名+类名 -->
            <tag-class>cn.jxufe.a_tag.ShowIpTag</tag-class>
            <!-- 标签体内容输出格式 -->
            <body-content>scriptless</body-content>
        </tag>
    
    </taglib>

    3)在jsp页面顶部导入自定义标签库

    4)使用标签库中的标签

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%--导入自定义标签库 --%>
    <%@ taglib uri="http://jxufe.cn" prefix="jxufe"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    
    <title>自定义标签</title>
    
    </head>
    
    <body>
        <%--
            向浏览器输出当前访问客户的IP地址
         --%>
        <%
            //1)获取客户端IP地址
            //String ip = request.getRemoteHost();
            //2)向浏览器输入内容
            //out.write("当前客户的IP为:" + ip);
        %>
        <%--使用自定义标签代替以上脚本 --%>
        <%--
          showIp标签: 作用可以显示客户端的IP地址
           --%>
        <jxufe:showIp></jxufe:showIp>
    
    </body>
    </html>

    2.8 自定义标签的执行过程

    访问:http://localhost:8080/day12/04tag.jsp

     

    前提: tomcat启动的时候,会读取day12JSP项目下的WEB-INF的文件。包括web.xml和tld文件。

    1)翻译成java文件-》 编译成class文件-> 构造方法- 》 调用_jspService()方法

    2)在内存tld文件中,查询是否存在一个uri名称为http://gz.itcast.cn的tld文件

    3)得到对应的tld文件内容。

    4)读到<itcst:showIp>内容时,截取showIp名称(就是标签),到tld文件中查询是否存在name为showIp的tag标签。

    5)取出<tag>标签的内容<tag-class>字符串: gz.itcast.a_tag.ShowIpTag

    2.9 自定义标签的生命周期

    由tocmat服务器调用的

    1)构造方法: 构造标签器对象

    2)void setJspContext(JspContext pc)                传入PageContext对象。JspContext是PageContext的父类。可以使用getJspContext()方法获取PageContext对象。

    3)void setParent(JspTag parent)                       传入父标签对象。如果没有父标签,则不调用次方法。使用getParent()方法获取父标签

    4)void setJspBody(JspFragment jspBody)        传入标签体内容。如果没有标签体,则不调用次方法。使用getJspBody()获取标签体内容。标签体内容封装到JspFragment中

    5)void doTag()                                                   调用标签时执行方法。我们的业务逻辑就写在这个方法中。可以调用getJspContext(),getParent(),getJspBody();

     

     

  • 相关阅读:
    查看full gc频率怎么样
    【LeetCode每天一题】Linked List Cycle II(循环链表II)
    【LeetCode每天一题】Word Break()
    【LeetCode每天一题】Candy(分糖果)
    【LeetCode每天一题】Single Number II(数组中单个数字II)
    【LeetCode每天一题】Gas Station(汽油站)
    【LeetCode每天一题】Single Number(数组中单独的数字)
    【LeetCode每天一题】Sum Root to Leaf Numbers(二叉树所有根到叶节点之和)
    【LeetCode每天一题】Longest Consecutive Sequence(最长的连续序列
    【LeetCode每天一题】 Word Ladder(单词阶梯)
  • 原文地址:https://www.cnblogs.com/xinmomoyan/p/11212162.html
Copyright © 2011-2022 走看看