2015年9月28日 星期一

流程 (客製化JSP Tag 三)

 <<interface IterationTag>>
public static final int EVAL_BODY_AGAIN = 2;

<<interface Tag>>
public static final int SKIP_BODY = 0;
public static final int EVAL_BODY_INCLUDE = 1;
public static final int SKIP_PAGE = 5;
public static final int EVAL_PAGE = 6;

0、1給doStartTag()回傳
回傳0就調用doEndTag()
回傳1就調用doAfterBody()

0、2給doAfterBody()回傳
回傳0就調用doEndTag()
回傳2就調用自己,一直到回傳0為止

5、6給doEndTag()回傳
回傳5表示立即停止,忽略之後的頁面,但會將目前的輸出回傳到瀏覽器
回傳6表示正常結束


release():將資源全部釋放,修改後不重啟瀏覽器,過一下子就會直接調用


※SKIP_BODY、EVAL_BODY_INCLUDE

※AttrTag.java

public class AttrTag extends TagSupport {
    private String scope;
    private String content;
    // 這兩個屬性都給setter即可
    
@Override
public int doStartTag() throws JspException {
    System.out.println("doStartTag");
    Object value = null;
    if ("P".equals(scope)) {
        value = pageContext.getAttribute(content, PageContext.PAGE_SCOPE);
    }
    if ("R".equals(this.scope)) {
        value = pageContext.getAttribute(content, PageContext.REQUEST_SCOPE);
    }
    if ("S".equals(this.scope)) {
        value = pageContext.getAttribute(content, PageContext.SESSION_SCOPE);
    }
    if ("A".equals(this.scope)) {
        value = pageContext.getAttribute(content, PageContext.APPLICATION_SCOPE);
    }
    
    if (value == null) {
        return SKIP_BODY;
    } else {
        return EVAL_BODY_INCLUDE;
    }
    
}

※attr.tld

<tag>
    <name>displayScope</name>
    <tag-class>attr.AttrTag</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <name>scope</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <name>content</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
</tag>

body content變成JSP


※attr.jsp

<%
    String scope = "P";
    if ("P".equals(scope)) {
        pageContext.setAttribute("ooo", scope);
    } else if ("R".equals(scope)) {
        request.setAttribute("ooo", scope);
    } else if ("S".equals(scope)) {
        session.setAttribute("ooo", scope);
    } else if ("A".equals(scope)) {
        application.setAttribute("ooo", scope);
    }
%>
    
<bruce:displayScope scope="<%=scope%>" content="ooo">
    <h1>範圍:<%=scope%></h1>
    <h1>pageScope內容是${pageScope.ooo}</h1>
    <h2>requestScope內容是${requestScope.ooo}</h2>
    <h3>sessionScope內容是${sessionScope.ooo}</h3>
    <h4>applicationScope內容是${applicationScope.ooo}</h4>
</bruce:displayScope>

※如果scope不輸入PRSA其中一個,就會調用SKIP_BODY



※SKIP_BODY、EVAL_BODY_AGAIN


※jsp

<%
    List<String> list = new ArrayList<String>();
    list.add("A1");
    list.add("B2");
    list.add("C3");
    request.setAttribute("ooo", list);
%>
    
<bruce:iterate content="ooo" id="abc">
    ${abc}<br/>
</bruce:iterate>




※tld

<tag>
    <name>iterate</name>
    <tag-class>attr.AttrHaveContent2</tag-class>
    <body-content>JSP</body-content>
    <attribute>
        <name>content</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
        <name>id</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
    </attribute>
</tag>




※java

public class AttrHaveContent extends TagSupport {
    private String content;
    private Iterator<?> it;
    
    public void setContent(String content) {
        this.content = content;
    }
    
    @Override
    public int doStartTag() throws JspException {
        System.out.println("doStartTag");
        Object value = pageContext.getAttribute(content, PageContext.REQUEST_SCOPE);
    
        System.out.println("value=" + value);
        if (value == null) {
            return SKIP_BODY;
        } else {
            List<?> x = ((List<?>) value);
            // Set<String> x = ((Map<String, Object>) value).keySet();
            // Collection<Object> x = ((Map<String, Object>) value).values();
            it = x.iterator();
    
            if (it.hasNext()) {
                pageContext.setAttribute(id, it.next());
                return EVAL_BODY_INCLUDE;
            }
            return SKIP_BODY;
        }
    }
    
    @Override
    public int doEndTag() throws JspException {
        System.out.println("doEndTag");
        return SKIP_PAGE;
    }
    
    @Override
    public int doAfterBody() throws JspException {
        System.out.println("doAfterBody");
    
        if (it.hasNext()) {
            pageContext.setAttribute(id, it.next());
            return EVAL_BODY_AGAIN;
        } else {
            return SKIP_BODY;
        }
    }
}

※TagSupport.java裡有個屬性是id,是protected,所以可以不用宣告id,但要用時還是要在tld裡定義



※setValue、getValues

List<?> x = ((List<?>) value);
for (int i = 0; i < x.size(); i++) {
    String s = (String) x.get(i);
    setValue(s.substring(1), "x");
}
    
enu = getValues();
if (enu.hasMoreElements()) {
    pageContext.setAttribute(id, enu.nextElement());
    return EVAL_BODY_INCLUDE;
}

※TagSupport還有個Hashtable叫values,但它是private,但有setValue和getValues可以塞進去,getValues回傳值是Enumeration,和Iterator很像

※doAfterBody也改成Enumeration就可以取到值了,取到的是setValue的Key值



※SKIP_PAGE、EVAL_PAGE

※jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="attrHaveContent" prefix="bruce"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head></head>
    <body>
        <bruce:endTagTest />
        ooo
    </body>
</html>



※web.xml

<jsp-config>
    <taglib>
        <taglib-uri>attrHaveContent</taglib-uri>
        <taglib-location>/WEB-INF/AttrHave.xml</taglib-location>
    </taglib>
</jsp-config>



※tld

<taglib version="2.1" 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">
    <tlib-version>1.0</tlib-version>
    <short-name>ht</short-name>
    
    <tag>
        <name>endTagTest</name>
        <tag-class>attr.AttrHaveContent</tag-class>
        <body-content>empty</body-content>
    </tag>
</taglib>



※java

public class AttrHaveContent extends TagSupport {
    @Override
    public int doEndTag() throws JspException {
        System.out.println("doEndTag");
    
        JspWriter out = this.pageContext.getOut();
        try {
            out.println("xxx");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return SKIP_PAGE;
    }
}

※回傳SKIP_PAGE時,不會印出ooo


沒有留言:

張貼留言