Servlet笔记(六)JSP EL

来源:互联网 发布:还珠格格五阿哥和知画 编辑:程序博客网 时间:2024/06/10 05:21
〇、常用动作元素
    <jsp:include/>:动态包含
     <%@include file="2.jsp%>
    <jsp:forward/>:转发
    <jsp:forward page="2.jsp"></jsp:forward>
 
 
一、JSP九大隐式对象(记住):在JSP的java脚本或表达式中直接可以使用的对象。比如out
    1、原理:就是JSP对应的Servlet的service方法中的局部变量。
            注意,九大隐式对象是对象,不是范围
    2、九大隐式对象
        ----------------------------------
        引用变量名        |      类型
        ----------------------------------
        request             |        HttpServletRequest
        response          |        HttpServletResponse
        session             |        HttpSession   (不一定有 @page session="true")
        application      |        ServletContext
        config               |        ServletConfig
        page                 |        this
        exception        |        java.lang.Throwable (不一定有 @page isErrorPage="true")
        ---------------------------------------------
        out                    |        javax.servlet.jsp.JspWriter (作用和response.getWriter返回的PrintWriter功能一样)
        pageContext  |        javax.servlet.jsp.PageContext
 
一般不要用自己new一个PrintWriter,然后调用writer()方法写入字符,否则会先刷PrintWriter中的缓存区字符,再关闭jsp的时候,发现jsp中的缓存中有数据,然后再刷jsp的缓存区数据到PrintWriter缓存中数据的后面
 out.write("a");
 response.getWriter().write("b");
会打印ba.
要想打印ab,有以下两个办法
1,刷新,把数据刷出来.
2,把缓存设置为0
 
二、out和pageContext
    因为字符输出流out和字节输出流InputStream不能同时存在
    所以在jsp中要进行下载,可以把所有不需要的字符都删掉.就不报错了
    要是有输出的字符,虽然仍然会下载成功,但是会报错.
    (记住)Tips:在JSP中尽量只输出字符,且尽量使用out内置对象。
    (灰常重要)javax.servlet.jsp.PageContext
    功能分为三部分:
    1、它本身(PageContext)是一个域对象且能操作其他(ServletRequest HttpSession ServletContext)域对象中的内容
        操作本身域对象数据:(PageContext的存活范围是当前页面,最小的范围)
            java.lang.Object getAttribute(java.lang.String name)
            void removeAttribute(java.lang.String name) 
            void setAttribute(java.lang.String name, java.lang.Object value) 
        操作其他:
            java.lang.Object getAttribute(java.lang.String name, int scope)
            void removeAttribute(java.lang.String name, int scope) 
            void setAttribute(java.lang.String name, java.lang.Object value, int scope) 
 
        java.lang.Object findAttribute(java.lang.String name)
  <%
  pageContext.setAttribute( "p" ,  "pp" );//设置页面域范围属性
  pageContext.setAttribute( "p" ,  "RP" ,pageContext. REQUEST_SCOPE );//request域范围
  pageContext.setAttribute( "p" ,  "sp" ,pageContext. SESSION_SCOPE );//session域范围
  pageContext.setAttribute( "p" ,  "cp" ,pageContext. APPLICATION_SCOPE );//应用域范围
  Object obj = pageContext.findAttribute( "p" ); //  从page request session application范围依次搜索,找到为止。
    %>
 
    2、获取JSP中其它八个隐式对象
        java.lang.Exception getException() 
        java.lang.Object getPage() 
        javax.servlet.ServletRequest getRequest() 
        javax.servlet.ServletResponse getResponse() 
        javax.servlet.ServletConfig getServletConfig() 
        javax.servlet.ServletContext getServletContext() 
        javax.servlet.http.HttpSession getSession()
        JspWriter getOut()
    3、提供了转发和包含功能的方便的方法
        void forward(java.lang.String relativeUrlPath)
        void include(java.lang.String relativeUrlPath)
 
三、四大域对象(灰常重要)
    1、页面范围域对象pageContext(javax.servlet.jsp.PageContext):
            存放到此处的数据,只能当前页面使用。(使用很少)
    2、请求范围域对象request(javax.servlet.ServletRequest):显示完就没有了
            存放在此处的数据,只有转发才能传递给别人。(很高)
            应用场景:用在一些数据显示给用户后就没有用了。
    3、会话范围域对象session(javax.servlet.http.HttpSession):整个会话
            存放在此处的数据,只要是同一次就能取到。(很高)
            应用场景:一次请求产生了一些数据,当前用户日后可能还要用。典型的就是,登陆信息和购物车。
    4、应用范围域对象application(javax.servlet.ServletContext):整个应用
            存放在此处的数据,只要是同一个应用取到,不管是哪个客户端。(很少)。
            应用场景:存放全局数据。一定要做好同步处理
 
 
四、如何调试JSP的错误
1,看英文提示
2,如果第一次OK,后面修改错误,服务器有时候会报错,有时候会正常
    因为服务器如果发现无法编译,会取最近一次编译正确的来使用
 
五、JavaBean概念:POJO VO DO ENTITY domain
    1、什么才是一个JavaBean
        a、必须是public的
        b、必须有默认的构造方法。
        c、字段都是私有的。符合java命名规范。private boolean name;
        d、提供public的getter或setter方法。getName(isName只对boolean字段有效) setName(String name)  属性
        e、一般需要实现java.io.Serializable
    2、在企业开发中JavaBean充当什么角色?封装数据
    3、JSP中操作JavaBean的动作元素
        <jsp:useBean>:
            作用:按照指定的范围(scope)查找名称为id指定的对象。
                找到就找到了
                没有找到:调用默认构造方法创建对象(class),然后以id的名字放到socpe指定的域范围中
            属性:
                id:名称为id的对象
                class:调用默认方法创建对象(class)
                scope:默认值是page(页面范围)。可选值:page request(请求) session(会话) application(应用)
        <jsp:getProperty>
            作用:获取JavaBean中的属性值
            属性:
                name:那个JavaBean。该标签之前必须使用useBean.
                property:属性名称。切记:它对应的是getter方法,与字段名称无关。
                        name===getName()
            以下表示获取age的值
<jsp:getProperty property="age" name="p"/>
        <jsp:setProperty>
            作用:设置JavaBean中的属性值
            属性:
                name:那个JavaBean。该标签之前必须使用useBean.
                property:属性名称。切记:它对应的是setter方法,与字段名称无关。
                        name===setName(String name)
                value:设置的值
         以下表示设置p对象的name,设置的值为name的值
<jsp:setProperty property="name" name="p" param="name"/>
    Tips:标签可以替换Java脚本。
 
六、JavaWeb开发模型
    模型1:JSP+JavaBean
    模型2:MVC+三层架构
        M:Model   JavaBean
        V:View    JSP
        C:Controller Servlet
 
 
七、EL表达式(有难度): El表达式不支持字符串的连接
<%=java表达式%> 统称表达式。EL表达式就是替换Java表达式的(EL表达式不是一种语言,只是属于JSP的一种表达式而已)
    EL的功能:主要功能是输出数据到页面上,只适合显示数据(EL表达式永远没有空指针)
    EL表达式的基本形式: ${EL表达式}, EL只能从域对象中取数据,没有找到就什么都不输出。
        ${pp.address.city} == ${pp['address']["city"]}
          当参数名中间有-号非法字符时,应用[]来取,否则应为有-而报错
<jsp:useBean id="p" class="com.itheima.domain.Person" scope="page"></jsp:useBean>
<%=p.getName() %><br/>
${p.name}
<%--
${p.name}执行原理
Person p = (Person)pageContext.findAttribute("p");
if(p!=null){
    out.write(p.getName());
}
--%><hr/>
<%
Person pp = new Person();
pp.setName("李宗瑞");//没有放到域中
session.setAttribute("pp", pp);//放到了session中    
%>
${pp.name }<hr/>
${pp }<hr/>
<!-- ppp为空,什么都不输出 -->
${ppp.name }<hr/>
<!-- 必须先初始化,address,才能输出济南 -->
${pp.address.city }<hr/>
    1、获取数据
        List:按照索引取
        Map:按照key取绑定的对象。
    <!-- 获取Map中的数据 -->
    <%
    Map<String,Person> map = new HashMap<String,Person>();
    map.put("p1"new Person("刘艳伟"));
    map.put("p2"new Person("宋旭东"));
    map.put("p3"new Person("李梅"));
    pageContext.setAttribute("mm", map);
    %>
    <!-- 获取map中的数据,先获取键,再name -->
    ${mm.p3.name }<hr/>
 
2, 执行运算 (数学和逻辑|&!)
    .运算符:调用.之前的getter方法.只要有get方法,  .  就能调
   []运算符:.能做的,它都能做;  .不能做的,它也能做.                
    empty运算符:判断一个对象是否是null或者"",如果是,返回true;
                                如果对象是一个集合,即使对象本身不是null,没有元素也返回true.
 <body>
    <%  pageContext.setAttribute("p"null);   %>
    <!-- empty判断是否为空,为空打印true -->
    ${empty p }<br/>
    <%
    List list = new ArrayList();
    list.add("p");
    pageContext.setAttribute("list", list);
     %>
    ${empty list }<hr/>   
    ${empty cart }<br/>
     <!-- empty进行 3元运算 -->
    ${1!=1?"等于":"不等于" }<br/>
    ${empty list?"您没有购买任何商品":"您买了以下商品" }<br/>
    <%
    session.setAttribute("user"new Person("向阳"));
     %>
     ${empty user?"您没有登录":"欢迎访问" }
    <%
    pageContext.setAttribute("gender""0");
     %>
    <input type="radio" name="gender" value="1" ${gender=='1'?'checked="checked"':''}/>
    <input type="radio" name="gender" value="1" ${gender=='0'?'checked="checked"':''}/>
    </body>
 
 
 
    3、11个EL隐式对象:请不要与JSP内置对象混淆
        一个是表示对象本身,其余表示的都是Map
        ----------------------------------------------------------------------------
        EL内置对象名称        表示的类型                                            说明
        pageContext            javax.servlet.jsp.PageContext        与JSP内置对象一样
        pageScope               java.util.Map                     表示的是页面范围域中的数据。
        requestScope          java.util.Map                     表示的是请求范围域中的数据。
        sessionScope           java.util.Map                     表示的是会话范围域中的数据。
        applicationScope    java.util.Map                     表示的是应用范围域中的数据。
 
        param                        java.util.Map                     表示的是单一请求参数。key请求参数名,value是请求参数值
        paramValues            java.util.Map                     表示的是求参数。key请求参数名,value是请求参数值数组
 
        header                       java.util.Map                     表示的是单一请求消息头。key请求头名,value是消息头值
        headerValues           java.util.Map                     表示的是请求消息头。key请求头名,value是消息头值数组
 
        cookie                       java.util.Map                      表示的就是客户端带来的Cookie。
                                                                                        key:cookie对象的name,value是Cookie对象本身。(特殊)
        initParam                  java.util.Map                       表示的web.xml中的context-param(全局参数)
  <body>
  <!-- 获取相对路径 -->
  ${pageContext.request.contextPath}<br/>
    <%
    pageContext.setAttribute("p""pp");
    request.setAttribute("p""rp");
    session.setAttribute("p""sp");
    application.setAttribute("p""ap");
    %>
       <!-- 打印p -->
    ${p }<br/>
       <!-- 打印sp -->
    ${sessionScope.p }<br/>
     <!-- http://localhost:8080/my_exercise_day07/7.jsp?name=aaa -->
      <!-- aaa -->
    ${param.name}<br/>
     <!-- http://localhost:8080/my_exercise_day07/7.jsp?name=888&name=999 -->
     <!-- 888 999 -->
      ${paramValues.name[0]}
    ${paramValues.name[1]}<br/>
    <!-- gzip,deflate -->
    ${headerValues['Accept-Encoding'][0]}<br/>
    <hr/>
    <!-- JSESSIONID -->
    ${cookie.JSESSIONID.name}<br/><!-- 您能做对吗 -->
    <!-- 打印session的id -->
    ${pageContext.session.id}
    </body>
 
    4、调用普通类的静态方法(EL函数):JSTL剩余标签时讲。
 
八、JSTL中的core核心标签
    JSTL:java standard tag libary外部标签库(JSP2.0之后都支持)
    1、使用前提:拷贝jar包
        standard.jar
        jstl.jar
    2、引入外部的标签,使用taglib指令。
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 
    c:if
        作用:如果test返回true,则该标签的主体内容会显示到界面上。
        test:必须的。支持表达式,必须返回的是布尔值。
    <c:if test="{1==1}">没错</c:if>
    <%
    session.setAttribute("user"new Person("李梅"));
     %>
    <c:if test="${session.user==null}">
        <a href="#">没有登录</a>
        <a href="#">沒有账号</a>
    </c:if><br/>
    <%
    List cart = new ArrayList();
    cart.add("p");
    session.setAttribute("cart", cart);
     %>
    <c:if test="${empty sessionScope.cart }">
              对不起!您没有购买任何商品
    </c:if>
    <c:if test="${!empty sessionScope.cart }">
              您购买的商品如下
    </c:if>
 
    c:forEach
        循环遍历:数组、List、Set、Map等。重复执行主体内容
        items:要遍历的对象
        var:一个变量名,转向当前遍历的元素
        begin:开始索引
        end:结束索引
        step:步长。默认1
        varStatus:指向了一个对象,该对象维护当前遍历的元素的一些信息
            boolean isFirst()
            boolean isLast()
            int getIndex():索引,从0开始
            int getCount():计数,从1开始
      <%
      String s[] = {"a","b","c","d","e","f","g"};
      pageContext.setAttribute("s",s);
      %>
      ${s[2] }<!-- 打印c --><hr/>
      <c:forEach items="${s }" var="v">
          ${v }<br/><!-- 遍历s数组 -->
      </c:forEach><hr/>
      <c:forEach items="${s }" var="v" begin="1" end="6" step="2">
          ${v }<br/><!-- 打印b d f -->
      </c:forEach><hr/>
      <c:forEach begin="2" end="100" step="2" var="v">
          ${v }<!-- 打印2到100的偶数 -->
      </c:forEach><hr/>
      <%
    List list = new ArrayList();
    list.add("aa");
    list.add("bb");
    list.add("cc");
    pageContext.setAttribute("list",list);
    %><!-- 必须设定到域中 -->
    <c:forEach items="${list}" var="v">
        ${v }
    </c:forEach><hr/>
    <%
    Map map = new HashMap();
    map.put("a""aa");
    map.put("b""bb");
    map.put("c""cc");
    pageContext.setAttribute("map",map);
    %>
    <!-- me引用的是一个Map.Entry对象 -->
    <c:forEach items="${map }" var="v">
        ${v.key }=${v.value }
    </c:forEach>
    <%
    List ps = new ArrayList();
    ps.add(new Person("徐若瑄"));
    ps.add(new Person("苍井空"));
    ps.add(new Person("小西悠"));
    ps.add(new Person("佐佐木希"));
    pageContext.setAttribute("ps",ps);
    %>
    <table border="1">
        <c:forEach items="${ps }" var="v" varStatus="vs">
            <tr bgcolor="${vs.count%2==0?'red':'blue' }">
                <td>${vs.count }</td>
                <td>${vs.index }</td>
                <td>${vs.first }</td>
                <td>${vs.last }</td>
                <td>${v.name }</td>
            </tr>            
        </c:forEach>
    </table>

0 0