2016年4月10日 星期日

JSP 的指令元素 (page) (JSP 2.x 二)

參考JSP2.3的spec的JSP.1.10,上一篇有提供連結,語法如下
<%@ directive { attr=”value” }* %>

directive 有三種:page、tablib、include



※page

屬性有15種
{ language=”scriptingLanguage”}
{ extends=”className”}
{ import=”importList”}
{ session=”true|false”  }
{ buffer=”none|sizekb” }
{ autoFlush=”true|false”  }
{ isThreadSafe=”true|false”  }
{ info=”info_text” }
{ errorPage=”error_url” }
{ isErrorPage=”true|false” }
{ contentType=”ctinfo”}
{ pageEncoding=”peinfo”}
{ isELIgnored=”true|false” }

2.1(含)後又增加這兩個
{ deferredSyntaxAllowedAsLiteral=”true|false”}
{ trimDirectiveWhitespaces=”true|false”}


※除了import以外,<%@ page %>可以寫很多行,但屬性名不能重覆,否則會出「Page directive must not have multiple occurrences of pageencoding」的錯

※以下用2.3版測試


※contentType、pageEncoding

<%@ page language="java" contentType="application/msword; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Insert title here</title>
    </head>
    <body>
        <%
            response.setHeader("Content-Disposition", "Attachment; filename=xxx.doc");
        %>
        <table border="1">
            <tr><td>ascii</td></tr>
            <tr><td>氣气気</td></tr>
        </table>
    </body>
</html>

※contentType="text/html; charset=UTF-8"
在tomcat資料夾下的webapps\examples\WEB-INF\web.xml可以複製

※MIME預設就是text/html

※MIME是text/plain就會變成純文字檔,所以一點顏色都沒有,亂打會出現下載視窗

※MIME是application/msword,我用IE11會出錯,但用chrome是ok的,一樣會出現下載視窗,檔名依瀏覽器不同會不一樣,內容編碼吃的是meta的編碼

※如果要控制下載的檔名,可用response那一行,參考這裡

※charset 參考Servlet第二篇



※errorPage、isErrorPage

※test.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page errorPage="error.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Insert title here</title>
    </head>
    <body>
        <% int a = 1 / 0;%>
    </body>
</html>

※指定errorPage後,如果此網頁有錯,就會跳轉,且網址不變



※error.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page isErrorPage="true"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Insert title here</title>
    </head>
    <body>
        <h1>我錯了</h1>
        <%
            response.setStatus(200);
        %>
        <%=exception.getMessage()%>
    </body>
</html>

※isErrorPage是true,才能使用隱函物件exception

※網頁錯誤後,就會跳轉到error.jsp,多按幾次重整會發現有時候成功,有時候500,所以增加response那一行,200代表ok,都沒問題


還有一種方法是用web.xml的設定方式,在Servlet六的錯誤頁面有寫,但要注意IE有可能會有問題(我用IE11預設不行),將下面的勾取消即可


它預設有勾,它勾起來我反而不易懂好不好
上面還有「如果IE不是預設的網頁瀏覽器,請告訴我」,不想用的可取消


※language

文件寫的好長,我懶的看,反正寫java就對了


※extends

※xxx.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page extends="pkg.JSPDad"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <%System.out.println("name=" + getName()); %>
        <%System.out.println("name2=" + getName2()); %>
        <h1>我跳</h1>
    </body>
</html>

※extends的類別,一定要繼承HttpServlet,不然會出「Unable to compile class for JSP」的錯

※沒加extends那一行時,getName()和getName2()當然不能用,「我跳」當然也有在畫面上
我一加extends那一行,就會跳到JSPDad的doGet方法,所以「我跳」沒看到很合理,但getName()和getName2()在控制台也沒有看到,不知道為什麼?


※JSPDad.java

public class JSPDad extends HttpServlet {
    private String name = "xxx";
    public static String name2 = "ooo";
    // setter/getter...
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get");
        // resp.getWriter().println("<html><head></head><body><h1>Yeah!</h1></body></html>");
        // req.getRequestDispatcher("/first.jsp").include(req, resp);
        resp.sendRedirect(req.getContextPath() + "/first.jsp");
    }
}

※父類別一定要覆寫doGet方法,覆寫doPost沒用,沒覆寫就會405

※first.jsp自己隨便寫,是可以跳轉的

※如果跳轉又寫xxx.jsp會變成無限迴圈


※import

和java的import一樣,可以寫很多行或者寫一行,用「,」隔開,重覆import也是可以的


※session

可不可以使用session,預設是true
上一篇有說9種隱含物件,它就是其中一種,如果這個選項設false,那這一頁就不能使用session了


※buffer、autoFlush

buffer為設定buffer大小,預設是8kb
autoFlush為buffer滿時,是否自動強制輸出,預設是true

如果超出buffer大小
autoFlush設false,會出「IOException: Error: JSP Buffer overflow」
autoFlush設true,還是可以正常輸出,內容也不會變少

buffer設定成0kb或none
autoFlush設false,會出「jsp.error.page.badCombo」
autoFlush設true,還是可以正常輸出,內容也不會變少


※isThreadSafe

在Servlet2.4已過時了,tomcat5.5、Servlet就是2.4,而JSP是2.0,看tomcat連結
預設是true,表示此jsp是安全的,一次允許多個request
如果是false,則一次只允許一個request

※info

設定訊息,可以透過getServletInfo()取得
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" info="xxx"%>
<html>
    <head></head>
    <body><%=getServletInfo()%></body>
</html>


※isELIgnored

要不要忽略EL,就是長「${}」的東東,以後會講



※以下兩個屬性是2.1(含)才有的

※deferredSyntaxAllowedAsLiteral

是否允許在頁面上有「#{}」,預設不允許,所以一打會出現編譯錯誤(Spring的EL就長這樣)

※官方文件有寫說page的作者說,在web.xml寫如下的設定可以覆蓋
<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <deferred-syntax-allowed-as-literal>false</deferred-syntax-allowed-as-literal>
    </jsp-property-group>
</jsp-config>

※我試的結果根本沒覆蓋


※trimDirectiveWhitespaces

※jsp頁面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="false" isELIgnored="false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
</head>
    
<body>
    <% String s = "s"; %>
    <b>hey man!</b>
    ${user}
    <%=s%>
</body>

※這個要在網頁按右鍵,檢視-->原始檔才看得出來,如下:

※上面的圖是設成false或沒設時,下面的圖是true

※官方文件有寫說page的作者說,在web.xml寫如下的設定可以覆蓋
<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <trim-directive-whitespaces>true</trim-directive-whitespaces>
    </jsp-property-group>
</jsp-config>

※我在web.xml全不寫當然是ok的,但奇怪的是我把這裡改成false,我試的結果還是run的好好的,根本就沒覆蓋啊!

沒有留言:

張貼留言