顯示具有 JSP 標籤的文章。 顯示所有文章
顯示具有 JSP 標籤的文章。 顯示所有文章

2012年3月11日 星期日

JSP 生命週期

xxxx.jsp
     ↓
xxxx_jsp.java
     ↓
xxxx_jsp.class
     ↓
載入容器
     ↓
實例化
     ↓
_jspInit()
     ↓
_jspService()
     ↓
_jspDestory()


(以下圖截自 http://web.math.isu.edu.tw/yeh/2010Spring/java/week13/CH08%20%E4%BD%BF%E7%94%A8JSP.pdf )








2011年11月9日 星期三

JSTL 標籤

<c:out> 標籤
  <b>Hello, <c:out value="${user}" default="guest"/>.</b>
  可指定default值,避免 EL 表示式 user 之值為 null

  <b>Hello, <%=user%>.</b>
  <b>Hello, ${user}.</b>
  若 user 為 null 以上兩種方式,則 output 為 Hello, ______.

<c:forEach> 標籤
  以下兩個寫法結果都一樣,但使用 <c:forEach> 標籤卻精簡多了
  1.
  <table>
    <%
    String[] items = (String[]) request.getAttribute("movieList");
    String var = null;
    for (int i = 0; i < items.length; i++) {
      var = items[i];
    }
    %>
    <tr>
      <td><%= var %></td>
    </tr>
  </table>

  2.
  <table>
    <c:forEach var="movie" items="${movieList}">
      <tr>
        <td>${movie}</td>
      </tr>
    </c:forEach>
  </table>

  可用巢狀迴圈,範例如下:
  Servlet 程式碼
    String[] ary1 = {"a", "b", "c", "d"};
    String[] ary1 = {"e", "f", "g", "h"};
    java.util.List arrayList = new java.util.ArrayList();
    arrayList.add(ary1);
    arrayList.add(ary2);
    request.setAttribute("arrays", arrayList);

  JSP 程式碼
    <table>
      <c:forEach var="arrayEl" items="arrays">
        <c:forEach var="item" items="arrayEl">
          <tr>
            <td>${item}</td>
          </tr>
        </c:forEach>
      </c:forEach>
    </table>

<c:if> 標籤
  <c:if test="${user == 'admin'}">
    <jsp:include page="test.jsp">
  </c:if>
  上面的敘述代表若 user 變數值為 "admin"
  則 include test.jsp 頁面到網頁中
  但此標籤無法做到 else 的敘述,下一組標籤可以做到此需求

<c:choose>, <c:when>, and <c:otherwise> 標籤
  用法範例如下
    <c:choose>
        <c:when test="${a == 'test1'}">
            output string1
        </c:when>
       
        <c:when test="${a == 'test2'}">
            output string2
        </c:when>
       
        <c:otherwise>
            output string2
        </c:otherwise>
    </c:choose>

  以上被 <c:choose> 包住的判斷,包括<c:otherwise>,只會有一個被執行

2011年10月30日 星期日

JSP Include

要在 JSP 裡插入固定頁面有兩種方式
1. JSP 指令
    <%@ include file=”Header.jsp”%>
2. JSP 標準動作
    <jsp:include page=”Header.jsp” />


很多時候這兩種方式的結果是完全相同的,但是內部 Container 的處理方式是有點不一樣的。


「指令」處理 include 頁面的時機是第一次被讀取到的時候(Translation Time)


「標準動作」處理 include 頁面的時機是每次被讀取到的時候(Run Time)


此外,被 include 之 JSP 檔案中必須注意不可有 <html> 或 <body>,否則會造成母頁面重覆出現 <html> 及 <body> 導致網頁讀取不正確。

2011年10月24日 星期一

EL 隱含物件

對應各種作用域屬性之 Map
    pageScope
    requestScope
    sessionScope
    applicationScope

對應於屬性請球參數之 Map
    param
    paramValues (參數有多個值時可利用陣列方式存取)
       ${paramValues.food[0]}
       ${paramValues.food[1]}

對應於請求標頭 Map
    header
    headerValues (參數有多個值時可利用陣列方式存取)

cookie 請求
    cookie

Context 之初始參數 Map
    initParam

指向 pageContext 之實際參考
    pageContext

2011年10月23日 星期日

當 Form 之 action 指向 JSP 而不是 Servlet


<html>
<body>
<form action="Test.jsp">
  name: <input type="text" name="userName">
  ID#: <input type="text" name="userID">
  <input type="submit">
</form>
</body>
</html>

Test.jsp 以標準動作接收之方式為:
<jsp:useBean name="person" type="foo.Person" class="foo.Employee">
    <jsp:setProperty name="person" property="name" param="userName" />
</jsp:useBean>

此外,若 html 指定之 name 與 bean 之屬性同名,則可以不用指定 param 參數
<jsp:useBean name="person" type="foo.Person" class="foo.Employee">
    <jsp:setProperty name="person" property="name" />
</jsp:useBean>

若所有的特性皆與 bean 之屬性相同,則可用 * 代替
<jsp:useBean name="person" type="foo.Person" class="foo.Employee">

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

</jsp:useBean>

若要展示的屬性不是基本資料型別或 String 時,如 Pearson 中的 Dog 屬性之 name 屬性,假設
  Person class 具有 String 型態之 "name" attribute
  Person class 具有 Dog 型態之 "dog" attribute
  Dog class 具有 String 型態之 "name" attribute


不使用標準動作 : (可正常運作)
<%= ((foo.Person) request.getAttribute("person")).getDog().getName%>

使用標準動作 : (會印出dog類別之toString()回傳值)
<jsp:useBean id="person" class="foo.Person" scope="request" />
Dog name is : <jsp:getProperty name="person" property="dog" />

但若要符合不使用 scripting 原則又要能正確印出結果,可利用 EL 完成 :
Dog name is : ${person.dog.name}

2011年10月18日 星期二

EL & Scripting 評算整理表格

EL 表示式評算
DD組態
<el-ignored>
page指令
isELIgnored
評算 忽略
未指定 未指定
false 未指定
true 未指定
false false
false true
true false

Scripting 元素評算
DD組態
<scripting-invalid>
評算 錯誤
未指定
true
false

JSP 元素種類

1. Scriptlet : <% .... %>
     <% 與 %> 之間可以插入一般的 Java 程式碼
     例如
     <%
          int a = 100; // 區域變數
          for (int i = 0; i < a; i++) {
                .........
          }
     %>

2. Directive : <%@ ... %>
    共分為三種
    <%@ page ....%>
      例如
        <%@ page import = "foo.*" %>

    <%@ taglib ....%>
      定義 JSP 使用的標籤函式庫
      例如
      <%@ taglib tagdir="/WEB-INF/rags/cool" prefix="cool" %>

    <%@ include ....%>
      可在 JSP 頁面固定載入一段文字或程式碼,建立一個可重複使用的區塊
      例如
      <%@ include file="xxxxxx.html" %>
   
3. Expression : <%= ... %>
    一般運算式,結尾不加分號
    例如
    <%=Math.random()%>
    <%=count%>
    <%= 27 %>
    <%= "27"%>

4. Declaration : <%! ... %>
    宣告 JSP 轉換出來的 Servlet 類別中的成員,成員即包括變數及方法。
    與 scriptlet 中宣告的區域變數不同。
    例如
    <%!
        int a = 0; //類別變數
    %>
    <!%
        int test(int a) {
             int b = a + 1;
             return b;
        }
    %>

5. Action : <xxx: ... >
    ● Standard Action
      <jsp:include page="test.jsp" />
      <jsp:useBean id="person" class="foo.Employee" scope="request"/>
      <jsp:getProperty name="person" property="name">
      <jsp:setProperty name="person" property="name" value="Fred">

    ● Others
      <c:set var="rate" value="32" />

JSP : 利用 PageContext 存取其他作用域屬性

類別圖
JspContext
getAttribute(String name)
getAttribute(String name, int scope)
getAttributeNamesInScope(int scope)
findAttribute(String name)

//更多方法
                                             ↑
PageContext
APPLICATION_SCOPE
PAGE_SCOPE
REQUEST_SCOPE
SESSION_SCOPE

//更多欄位
getRequest()
getServletConfig()
getServletContext()
getSession()

//更多方法

屬性存取範例
  ● Page 作用域
    <% pageContext.setAttribute("foo", one); %>
    <% pageContext.getAttribute("foo"); %>

  ● Session 作用域
    <% pageContext.setAttribute("foo", one, PageContext.SESSION_SCOPE); %>
    <% pageContext.getAttribute("foo", PageContext.SESSION_SCOPE); %>
    (等同於<% session.getAttribute("foo"); %>)

  ● Application 作用域
    <% pageContext.setAttribute("foo", one, PageContext.APPLICATION_SCOPE); %>
    <% pageContext.getAttribute("foo", PageContext.APPLICATION_SCOPE); %>
    (等同於<% application.getAttribute("foo"); %>)

不知道屬性所屬作用域,可利用 pageContext
  <% pageContext.findAttribute("foo") %>
  搜尋順序為 Request → Session → Application。先找到先贏。



2011年10月17日 星期一

JSP 註解及作用域

1. 註解
    <!-- HTML 註解 -->
    <%-- JSP 註解 --%>
    HTML 註解可在網頁原始碼中看到,JSP 註解不行

2. 作用域
    Application
      getServletContext().setAttribute("value", value); //Servlet
      application.setAttribute("value", value); //JSP

    Request
      request.setAttribute("value", value); //Servlet & JSP 相同

    Session
      request.getSission().setAttribute("value", value); //Servlet
      session.setAttribute("value", value); //JSP

    Page (Servlet 無此作用域)
      pageContext.setAttribute("value", value); //JSP

2011年10月13日 星期四

Session 相關之 Listener

有需要就實作下列 Listener 並針對對應 Listener 之 method 進行實作,當事件發生時容器就會自動找到對應的 method 執行


1. HttpSessionListener (Interface)
● 使用時機
  追蹤目前線上正在活動的 session。


● 實作方法
  sessionCreated(HttpSessionEvent se)
  sessionDestroyed(HttpSessionEvent se)


2. HttpSessionActivationListener (Interface)
● 使用時機
  追蹤 session 何時由一個 VM 轉換到另一個 VM。


● 實作方法
  sessionDidActivate(HttpSessionEvent se)
  sessionWillPassivate(HttpSessionEvent se)
   
    這裡必須注意的是這兩個方法接受的 event 型態為 HttpSessionEvent
  而不是 HttpSessionActivationEvent(沒有這種 event)


3. HttpSessionBindingListener (Interface)
● 使用時機
  追蹤是否有 attribute 被繫結到 session 中。


● 實作方法
  valueBound(HttpSessionBindingEvent event)
  valueUnbound(HttpSessionBindingEvent event)

4. HttpSessionAttributeListener (Interface)
● 使用時機
  追蹤 session 中何時有 attribute 被新增、移除及置換。


● 實作方法
  attributeAdded(HttpSessionBindingEvent se)
  attributeRemoved(HttpSessionBindingEvent se)
  attributeReplaced(HttpSessionBindingEvent se)

    與 HttpSessionActivationListener 類似
    這裡必須注意的是這兩個方法接受的 event 型態為 HttpSessionBindingEvent
    而不是 HttpSessionAttributeEvent(沒有這種 event)

2011年10月12日 星期三

Session & Cookie 控制

Session 建立 :
    HttpSession session = request.getSession();

    //回傳已存在的 session,不存在時回傳 null
    HttpSession session = request.getSession(false);

    //與 session.getSession() 相同
    //若存在就回傳已存在的 session,若不存在時就建立一個新的
    HttpSession session = request.getSession(true);

Session 是否為新建立 :
    session.isNew();

Session 失效 :
1.web.xml中設定(單位為分鐘)
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

2.呼叫 invalidate() 方法
    session.invalidate();

3.程式中設定(單位為秒)
    session.setMaxInactiveInterval(20*60);

Cookie 控制 :
1. 建立新的 Cookie
    Cookie cookie = new Cookie("userName", name);

2. 設定 Cookie 存活時間
    cookie.setMaxAge(30*60);

3. 在 response 回傳 Cookie 給 client
    response.addCookie(cookie);

4. 取得 client 之 Cookie
    Cookie[] cookieArray = request.getCookies();
    if (cookieArray != null) {
        for (int i = 0; i < cookieArray.length; i++) {
            Cookie cookieEl = cookieArray[i];
            if (cookieEl.getName().equals("userName")) {
                String userName = cookieEl.getValue();
                out.print("Hello, " + userName);
                break;
            }
        }
    }