JSP中的內置對象

(1)
爲使Web應用程序開發的方便,在JSP頁面中內置了一些缺省的對象,這些對象不需要預先聲明就可以在腳本代碼和表達式中隨意使用。該內置的對象也稱爲隱含對象(Implicit  Object);隱含對象是被JSP容器自動定義的對象變量。
在不需要顯示地聲明情況下,在每一個JSP頁面中都可用如下的9個隱含對象,因爲在JSP頁面的_jspService()方法中自動地實例化該各種隱含對象。
對象名    對象類型    作用域    描述
application    ServletContext    application    表示JSP頁面駐留的Web應用程序。主要用來儲存在所有的Web應用程序之間共享的對象及對Servlet容器信息的訪問。
config    ServletConfig    page    包含與頁面Servlet有關的配置信息
exception    Exception    page    表示未捕獲到的異常與錯誤
out    JspWriter    page    一個輸出的緩衝流,給瀏覽器的客戶返回內容
page    HttpJspBase    page    表示JSP頁面Servlet的一個實例,相當於java中的this
pageContext    PageContext    page    在執行某一個JSP時,Servlet運行時會爲它初始化pageContext變量,這個變量可以被整個JSP代碼訪問,包括INCLUDE指示符插進來的代碼。
request    HttpServletRequest    request    表示調用JSP頁面的請求
response    HttpServletResponse    page    表示返回給客戶的響應
session    HttpSession    session    表示客戶端正參與的HTTP會話
提示:
    可以通過查看某一個JSP頁面所生成的Servlet代碼,瞭解在_jspService()方法的上述對象的定義。
    JSP中用到的out, request, response, session, config, page, pageContext是線程安全的,而application在整個系統內被使用,所以不是線程安全的。使用時應該採用synchronized (application)進行同步處理。
(2)9 個隱式對象及其功能的簡單描述如下: 
application 是使用範圍最廣的上下文狀態。它允許 JSP 頁面的 servlet 與包括在同一應用程序中的任何 Web 組件共享信息。 
config 允許將初始化數據傳遞給一個 JSP 頁面的 servlet。 
exception含有隻能由指定的 JSP“error pages”訪問的異常數據。 
out 提供對 servlet 的輸出流的訪問。 
page 是JSP頁面的處理當前請求的 servlet 的實例。一般來說,JSP 頁面作者不使用該對象。 
pageContext 是 JSP 頁面本身的上下文。它提供惟一一個 API 來管理具有不同作用域的屬性。這個 API 在實現 JSP 自定義標記處理程序時使用得非常多。 
    request 提供對 HTTP 請求數據的訪問,同時還提供用於加入特定於請求的數據的上下文。 
response 允許直接訪問 HTTPServletResponse 對象,JSP 程序員很少使用該對象。
Session 可能是狀態管理上下文中使用得最多的對象。“會話”的概念是指單個用戶與 Web 應用程序在幾個請求上進行交互。
2、out
(1)作用:向客戶端輸出各種數據類型的內容
(2)常用的方法:
    out.print(類型) 或 out.println(類型):換行輸出指定的字符串或者HTML標籤
程序例:<%   //調用out對象的print方法
out.print("<p><b>Hello World!</b>");
%>
注意:out.println()本意是可以實現換行,但瀏覽器一般會忽略;因此應該採用out.println("<br>")纔可以真正實現換行。
    out.newLine():輸出一個換行符號
    out.flush():輸出緩衝區的數據
    out.close():關閉輸出流,從而可以強制終止當前頁面的剩餘部分向瀏覽器輸出。
    out.clearBuffer():清除緩衝區裏的數據,並把數據寫到客戶端
    out.clear():清除緩衝區裏的數據,但不把數據寫到客戶端
    out.getBufferSize():獲得緩衝區的大小,緩衝區的大小可用<%@page buffer=”size”%>設置
    out.getRemaining():獲得緩衝區沒有使用的空間的大小
    out.isAutoFlush():返回布爾值,若auto flush則返回true,否則返回false。是否auto fush我們可用<% @page  isAutoFlush=”true/false” %>來設置
(3)注意的問題:中文顯示問題,Java使用的是Unicode編碼,而本地系統通常使用ASCII編碼,因此需要經常在原始的8位字節和16位unicode字符之間進行轉換。
    若是直接賦值的中文字符串,在頁面中使用
<%@page contentType="text/html;charset=gb2312"%>就可正常顯示。但不需要進行轉換內碼,否則不能正常輸出顯示中文。
<%@page contentType="text/html;charset=gb2312"%>
<% out.print("中國人民");
%>
或者:
如:String orignalString="JSP編程技術";
String storeString=new String(chineseString.getBytes("ISO8859-1"));
String showString=new String(chineseString.getBytes("ISO8859-1"),"gb2312");
實驗演示:請見JSPExamples教學示例。將ErrorPage.jsp頁中的<%@ page contentType="text/html; charset=GB2312"%>除掉後再運行,進行對比。
    在不同平臺、不同類型的的服務器以及同一種服務器的不同版本中,JSP中文問題的解決方法各不相同,可自行試驗。
3、    request
(1)作用:主要用於接受客戶端通過http協議連接傳輸到服務器端的數據。
(2)常用的方法:
    getCookies():返回客戶端的cookie對象,結果是一個cookie數組
    public HttpSession getSession(boolean create) :取得會話對象,如果還沒有會話實例,則創建新的。
    getHeader(String name):獲得http協議定義的傳送文件頭信息,
如:request.getHeader(“User-Agent”)返回客戶端瀏覽器的版本號、類型
if (request.getHeader(“User-Agent”).indexOf(“MSIE”) != -1)
{   //檢查客戶端的瀏覽器類型是否爲MS IE
}
    getAttribute(String name):返回name指定的屬性值,若不存在指定的屬性,就返回空值(null)。
    getattributeNames():返回request對象所有屬性的名字,結果集是一個Enumeration(枚舉)類的實例
    getHeaderNames():返回所有request header的名字,結果集是一個Enumeration(枚舉)類的實例
    getHeaders(String name):返回指定名字的request header的所有值,結果集是一個Enumeration(枚舉)類的實例
    getMethod():獲得客戶端向服務器端傳送數據的方法有GET、POST、PUT等類型
    getParameter(String name):獲得客戶端傳送給服務器端的參數值,該參數由name指定
    getparameterNames():獲得客戶端傳送給服務器端的所有的參數名,結果集是一個Enumeration(枚舉)類的實例
    getParameterValues(String name):獲得指定參數所有值
    getQueryString()獲得查詢字符串,該串由客戶端以GET方法向服務器端傳送
    getRequestURI():獲得發出請求字符串的客戶端地址
    getServletPath():獲得客戶端所請求的腳本文件的文件路徑
    setAttribute(String name,Java.lang.Object o):設定名字爲name的request參數值,該值由Object類型的o指定
    getServerName():獲得服務器的名字
    getServerPort():獲得服務器的端口號
    getRemoteAddr():獲得客戶端的IP地址
    getRemoteHost():獲得客戶端電腦的名字,若失敗,則返回客戶端電腦的IP地址
    getProtocol():獲取客戶端向服務器端傳送數據所依據的協議名稱,如http/1.1
(3)注意的問題:如果請求中包含有中文,則要注意中文的問題。Java從一個byte流中讀取一個字符串時,將把平臺相關的byte轉變爲平臺無關的Unicode字符串。在輸出時Java將把Unicode字符串轉變爲平臺相關的byte流,如果某個Unicode字符在某個平臺上不存在,將會輸出一個''?''。
    解決的方法一:在該頁面的開始處進行如下設置
request.setCharacterEncoding("gb2312");        //對請求進行統一的編碼
    解決的方法二:對參數進行編碼轉換
String userName = request.getParameter("userName");  //獲得所傳遞來的參數
userName=new String(userName.getBytes("ISO8859-1"),"gb2312");
程序例一:演示request中的各個方法的程序例
 
程序例二:獲得用戶在Form表單中所傳遞來的項目

4、response
(1)作用:向客戶端發送數據,如Cookie、HTTP文件頭信息等。
(2)常用的方法:
    addCookie(Cookie cookie):添加1個Cookie對象,用來保存客戶端的用戶信息。用request的getcookies()方法可獲得這個Cookie
如:<% Cookie mycookie=new Cookie(“uname”,”wsr”);
response.addCookie(mycookie);
Cookie delmycookie=new cookie(“mycookie”,null);
delmycookie .setMaxAge(0);
delmycookie .setPath(/”);
response.addCookie(delmycookie);
%>
    addHeader(String name,String value):添加HTTP文件頭,該header將會傳到客戶端,若同名的header存在,原來的header會被覆蓋
    containsHeader(String name):判斷指定名字的HTTP文件頭是否存在並返回布爾值
    sendError(int sc):向客戶端發送錯誤信息,如:505:服務器內部錯誤;404:網頁找不到錯誤
如:response.sendError(response.SC_NO_CONTENT);
    setHeader(String name,String value):設定指定名字的HTTP文件頭的值,若該值存在,它將會被新值覆蓋
例1:讓網頁每隔5秒刷新一次
<% response.setHeader(“Refresh”,”5”);%>
   the current dateis:<%=new Date()%>
例2:利用response對象設定HTTP頭,以指明所要輸出的數據的類型
<% response.setContentType(“Application/pdf”);
response.setHeader(“content-disposition”,”attachment;filename=/”syntax.pdf/””);
%>
    sendRedirect(“http://www.foo.com/path/error.html”):重定向功能(此時不能已經向客戶輸出信息)
response.sendRedirect("/WebMis/NetShop/bookManageLogin.jsp");
5、application
(1)作用:application變量是對一個Web Application有效的全局變量,在保存一些全局有效的值(如:保存用戶共享的信息)時非常有用。
(2)特點:一旦創建,除非服務器關閉,否則將一直保持下去。
(3)常用的方法:
    getAttribute(String name):返回由name指定名字的application對象屬性的值,這是個Object對象
    getattributeNames():返回所有application對象屬性的名字,結果集是一個Enumeration(枚舉)類的實例
    getInitParameter(String name): 返回application栽個屬性的初始值,此屬性由name指定
    getServerInfo():獲得當前版本Servlet編譯器的信息
    setAttribute(String name,Object object):用Object來初始化某個屬性,該屬性由name指定
(4)編程要點:在引用application 變量時,必須使用同步(因爲有可能多個用戶會同時訪問它)。並且,需要測試一個application屬性是否已經存在。
(5)程序例:參考“利用Applicaton實現的簡單計數器.jsp”
<%@ page contentType="text/html; charset=gb2312" %>
<%  Integer count = null; 
    synchronized (application)        //同步處理
    {  //從內存當中讀取訪問量
    count = (Integer) application.getAttribute("basic.counter"); 
    if (count == null)         //測試一個application屬性是否已經存在。
  count = new Integer(0); 
    count = new Integer(count.intValue() + 1);    
    application.setAttribute("basic.counter", count); //將訪問量保存到內存當中
  }
%>
<html><head><title>簡單計數器</title></head><body> <center><font size=10 color=blue>簡單計數器</font><font size=5 color=blue>您好!您是本站的第 <%= count %> 位客人</font>
</center></body></html>
 
6、session
(1)概述
HTTP是一個無狀態的協議,爲了建立有效的Web應用,必須能識別來自遠程客戶端的衆多請求中哪些是屬於同一個客戶端的。通過session 可以達到該要求,而且在session中可以存儲任何類型的對象。但如果客戶端拒絕接受cookies(當客戶端瀏覽器中禁止 Cookie,Servlet 容器無法從客戶端瀏覽器中取得作爲 Cookie 的 Session ID,也就無法跟蹤客戶狀態。),有些服務器則改用URL重寫來實現session而有些服務器則不能實現。
Java Servlet API 中引用 Session 機制來追蹤客戶的狀態。Servlet API 中定義了 javax.servlet.http.HttpSession 接口,Servlet 容器必須實現這個接口。當一個 Session 開始時,Servlet 容器將創建一個 HttpSession 對象,Servlet 容器爲 HttpSession 分配一個唯一標識符,稱爲 Session ID。Servlet 容器將 Session ID 作爲 Cookie 保存在客戶的瀏覽器中。每次客戶發出 HTTP 請求時,Servlet 容器可以從 HttpRequest 對象中讀取 Session ID,然後根據 Session ID 找到相應的 HttpSession 對象,從而獲取客戶的狀態信息。
讓我們用幾個例子來描述一下cookie和session機制之間的區別與聯繫。筆者曾經常去的一家咖啡店有喝5杯咖啡免費贈一杯咖啡的優惠,然而一次性消費5杯咖啡的機會微乎其微,這時就需要某種方式來紀錄某位顧客的消費數量。想象一下其實也無外乎下面的幾種方案:
    該店的店員很厲害,能記住每位顧客的消費數量,只要顧客一走進咖啡店,店員就知道該怎麼對待了。這種做法就是協議本身支持狀態。
    發給顧客一張卡片,上面記錄着消費的數量,一般還有個有效期限。每次消費時,如果顧客出示這張卡片,則此次消費就會與以前或以後的消費相聯繫起來。這種做法就是在客戶端保持狀態。
    發給顧客一張會員卡,除了卡號之外什麼信息也不紀錄,每次消費時,如果顧客出示該卡片,則店員在店裏的紀錄本上找到這個卡號對應的紀錄添加一些消費信息。這種做法就是在服務器端保持狀態。

(2)作用:利用它可以實現分別保存每一個與Web Server進行會話的用戶的信息。
    session. setAttribute(“name”,val)
session. getAttribute(“name”)
(3)注意的問題:
    session中保存的信息不能是基本的數據類型,而必須是Java的相應的Object對象類型(可序列化的對象變量),所以變量聲明爲int類型時,必須將該int類型的變量轉換爲Integer類型的對象。
    只要在同一個會話期間(瀏覽器未與服務器斷開過即在同一個瀏覽器窗口內訪問各個頁面或者未超出指定的時間段),可以利用session實現將數據從一個頁面傳遞到另一個頁面。
    JSP 中的 session 對象對於那些希望通過多個頁面完成一個事務的應用是非常有用的(請見DataTrans文件夾內的程序)。
    注意setAttribute()和getAttribute()方法中的“name”要保持一致並區分大小寫。
(4)常用的方法:
    getAttribute(String name):獲得指定名字的屬性值,若該屬性不存在,將返回null
    setAttribute(String name,Java.lang.Object value):設定指定名字的屬性值,並將其存儲在session對象中
    removeAttribute(String name):刪除指定的屬性(包括屬性名、屬性值)
    getattributeNames():返回session對象中存儲的第一個屬性對象,結果集是一個Enumeration類的實例
    getCreationTime():返回該session對象創建的時間,以毫秒計,從1970年1月1日起
    getId():每生成一個session對象,服務器都會給其一個不會重複的編號,此方法返回當前session的編號
    getLastAccessedTime():返回當前session對象最後1次被操作的時間,返回自1970年1月1日起至今的毫秒數
    getMaxInactiveInterval():獲得session對象的生存時間(單位:秒)
    setMaxInactiveInterval(int interval) 設置Session的有效時間,時間的單位爲秒
注意:也可以在web.xml文件中採用如下的標籤(單位爲分)
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
程序例一:
<%@ page contentType="text/html; charset=GB2312"%>
<%@ page language="java" %>
<HTML><HEAD><TITLE>存取session數據</TITLE></HEAD>
<BODY>
<%
int Num = 0;     //從session對象取得Num
Object obj = session.getAttribute("Num");
if(obj == null)
{        //設定session對象的Num變量的值
        session.setAttribute("Num", String.valueOf(Num));
}
else
{        //取得session對象中的Num變量
        Num = Integer.parseInt(obj.toString());
        Num += 1;   //將訪客人數加1
        session.setAttribute("Num", String.valueOf(Num));
}       //設定session對象的Num變量的值
%>
session中的Num的值爲:
<%=
  Num
%></BODY></HTML>
 
程序例二:
<%@ page contentType="text/html; charset=GB2312"%>
<%@ page language="java" %>
<HTML><HEAD><TITLE>有效時間的設置與取得</TITLE></HEAD>
<BODY>
<%    //取得session的有效時間
        int tmpTime = session.getMaxInactiveInterval();
%>
    當前機器中的session有效時間爲<Font color = red>
<%=
        tmpTime
%>秒
</Font><BR>
<%    //將session的有效時間設定爲20分鐘
        session.setMaxInactiveInterval(60*20);
        int changeTime = session.getMaxInactiveInterval();
%>
更改後的session有效時間爲<Font color = red>
<%=
        changeTime
%>
</Font></BODY></HTML>
 
程序例三:application 和session的綜合演示
(1)演示session:
    打開瀏覽器並執行該程序,觀察左面的計數器的計數是否爲初始值1,然後再刷新該頁面,由於還在該用戶的會話有效期間,因此計數器的計數應該增加1。
    等一定的時間(具體由在tomcat中的web.xml中的<session-timeout>標誌來決定),然後再刷新該頁面,由於已經不在該用戶的會話有效期間,因此計數器的計數應該初始化爲1。
    再打開另一個瀏覽器,繼續啓動該頁面,由於此時爲另一個用戶的會話有效期間,計數器的計數應該初始化爲1。
(2)演示application:
打開和關閉瀏覽器,觀察右面的計數器的計數是否爲一直處於累加狀態。它與用戶是否有會話無關。

程序例四: 理解會話(瀏覽器未與服務器斷開過),利用Session從而可以實現將數據從一個頁面傳遞到另一個頁面。
程序例五:請見netTest.jsp網上測試程序
程序例六:利用session進行身份識別,請見網上報名中的
http://10.172.0.115:8080/WebMis/wlbm/adminShowAllBMInfo.jsp?currentShowPage=3
7、exception 
(1)作用:處理JSP文件在執行時所有發生的錯誤和異常。有3個內建方法。
(2)注意的問題:
必須在<%@ page isErrorPage=”true”%>的情況下纔可以使用exception對象
    getMessage():返回錯誤信息
    printStackTrace():以標準錯誤的形式輸出一個錯誤和錯誤的堆棧
    toString():以字符串的形式返回1個對異常的描述
程序例一:
(1)主功能部分的程序
<%--字符集設爲"gb2312",使動態頁面支持中文--%>
<%@ page contentType="text/html; charset=GB2312"%>
<!-- 這個實例演示怎樣使用一個在errorPage中定義的錯誤頁面,這個Jsp故意拋出一個異常NullPointerException,然後調用錯誤頁面(ErrorPage.jsp) 
-->
<%--定義錯誤頁面--%>
<%@ page  errorPage="ErrorPage.jsp" %>
<html>
<head></head>
<%! String str = null; %>
<body bgcolor=#ffffff><h2> 調用一個值爲null的String的方法會拋出一個異常...</h2>
<%--故意出錯,拋出異常--%>
字符串的長度爲
<%= str.length() %> 。
</body>
</html>
(2)錯誤處理部分的程序代碼
<%--字符集設爲"gb2312",使動態頁面支持中文--%>
<%@ page contentType="text/html; charset=gb2312"%>
<%@ page isErrorPage="true" %>
<!-- 這個錯誤頁面演示處理ThrowException.jsp頁面拋出的異常 -->
<html>
<head><title>JSP 錯誤頁面</title></head>
<body bgcolor=#ffffff>
<!-- 測試是否有異常的報告出現 --> 
<% 
if (exception != null)
{
 %>
<p> 一個異常被拋出: <b>
<% = exception
%><p> 它所拋出的路徑如下:
<%    //先把異常信息輸出到一個字節流
    ByteArrayOutputStream ostr = new ByteArrayOutputStream();
    exception.printStackTrace(new PrintStream(ostr));//在把字節流輸出到頁面
    out.print(ostr);
%>
<!-- 如果每個異常進行如下操作 --> 
<% 
}
else
{
%>
<p> <font color=#FF0000><b>錯誤頁面錯誤:</b></font>異常爲空的情況下調用此錯誤頁面,這是直接調用此頁面的結果。它應該用來反映其他Jsp頁面拋出異常的情況,而不該被直接調用。
<% 
}
%></body></html>

8、page(指當前jsp頁面本身,屬於java.lang.object類型,相當於Java類中的this指針)

二、錯誤處理方法
在JSP頁面中的錯誤處理方法類同於Java程序中的錯誤處理方法,只是應該將輸出信息發送到瀏覽器中,而不是發送到用戶控制檯。
程序例:
<%@ page contentType="text/html; charset=GB2312" %>
<%@ page language="java" %>
<%@ page import="java.io.*" %>
<HTML><HEAD><TITLE>錯誤檢測</TITLE></HEAD><BODY><CENTER>
    <FONT SIZE = 5 COLOR = blue>錯誤檢測</FONT>
</CENTER><BR><HR><BR><CENTER>
<FONT SIZE=4 COLOR=RED>
    <%
        int a = 10, b = 0, c;
        try
        {
            c = a / b; // 這裏產生除以零的錯誤
        }
        catch(Exception e)
        {    
            out.println(e.toString());
        }
        finally
        {
            out.println("<BR>這裏產生了除以零的錯誤");
        }
    %>
</CENTER></FONT></BODY></HTML>
 程序例:WebMis/wlbm/adminDeleteBMRecord.jsp頁面

 

文一:

內置對象是不需要聲明,直接可以在JSP中使用的對象,JSP有以下幾種內置對象:

1) request request表示HttpServletRequest對象。它包含了有關瀏覽器請求的信息,並且提供了幾個用於獲取cookie, header, 和session數據的有用的方法。
2) response response表示HttpServletResponse對象,並提供了幾個用於設置送回 瀏覽器的響應的方法(如cookies,頭信息等)
3) out out 對象是javax.jsp.JspWriter的一個實例,並提供了幾個方法使你能用於向瀏覽器回送輸出結果。
4) pageContext pageContext表示一個javax.servlet.jsp.PageContext對象。它是用於方便存取各種範圍的名字空間、servlet相關的對象的API,並且包裝了通用的servlet相關功能的方法。
5) session session表示一個請求的javax.servlet.http.HttpSession對象。Session可以存貯用戶的狀態信息
6) application applicaton 表示一個javax.servle.ServletContext對象。這有助於查找有關servlet引擎和servlet環境的信息
7) config config表示一個javax.servlet.ServletConfig對象。該對象用於存取servlet實例的初始化參數。
8) page page表示從該頁面產生的一個servlet實例。

Servlet API中的幾個對象
JSP提供了八個內部對象,而其中的五個內部對象對應於Servlet API中的七個對象,這也就使得我們正常理解並熟練使用Servlet中的這七個對象顯得尤其重要。這五個JSP的內部對象和Servlet API中的對象的對應關係是:
1) request對象對應於:javax.servlet.http.HttpServletRequest和javax.servlet.ServletRequest
2) response對象對應於:javax.servlet.http.HttpServletResponse和javax.servlet.ServletResponse
3) session對象對應於:javax.servlet.http.HttpSession
4) application對象對應於:javax.servlet.ServletContext
5) config對象對應於:javax.servlet.ServletConfig
                                                                         javax.servlet.http.HttpServletRequest這是一個接口,在我們提到接口之前,還是讓我們來複習一下Java中接口的一個初步的解釋:
接口在語法上與類相似,但是接口沒有實例,使用接口,只是指定類必須做什麼而不是如何做。
HttpServletRequest接口用來處理一個對Servlet的HTTP格式的請求信息。

javax.servlet.ServletRequest
這也是一個接口,這個接口定義一個Servlet引擎產生的對象,通過這個對象,Servlet可以獲得客戶端請求的數據。這個對象通過讀取請求體的數據提供包括參數的名稱、值和屬性以及輸入流的所有數據。而javax.servlet.http.HttpServletRequest也只是該接口的一個擴展,也就是說,該接口的所有方法也可以被javax.servlet.http.HttpServletRequest所使用。

javax.servlet.http.HttpServletResponse接口
該接口用來描述一個返回到客戶端的HTTP迴應。

javax.servlet.ServletResponse接口
該接口用來定義一個Servlet引擎產生的對象,通過這個對象,Servlet對客戶端的請求作出響應。這個響應應該是一個MIME實體,可能是一個HTML頁、圖象數據或其他MIME的格式。javax.servlet.http.HttpServletResponse接口是該接口的擴展。

javax.servlet.http.HttpSession接口
該接口用來描述一個session,至於什麼是session我想在這裏就沒必要說了吧。

javax.servlet.ServletContext接口
該接口用來定義了一個Servlet的環境對象。也可是認爲這是多個客戶端共享的信息,它與session的區別在於應用範圍的不同,session只對應於一個用戶。

javax.servlet.ServletConfig接口
該接口定義了一個對象,通過這個對象,Servlet引擎配置一個Servlet。每一個ServletConfig對象對應着一個唯一的Servlet。

javax.servlet.http.Cookie類
這個類描述了一個cookie,cookie的作用其實與session很類似,只是cookie保存在客戶端,session保存在服務器端。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章