西部村里人

常用链接

统计

其它BLOG

最新评论

WebWork标签技术的简化版本--JSP模板

   WebWork标签非常出色,在有些应用中,可能不想使用其环境,但希望能够使用其标签思路。JSP模板的使用面更广,随简化WebWork方式,提供思路供大家参考。

1、开发标签基础类:
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.io.Writer;
import java.util.Iterator;
import java.util.LinkedList;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public abstract class AbstractTag extends BodyTagSupport {

    protected String templateName ;

    private final static String templatePath = "/WEB-INF/tags/";

    private static final long serialVersionUID = -1201668454354226175L;

    public String getTemplateName() {
        return templateName;
    }

    public void setTemplateName(String templateName) {
        this.templateName = templateName;
    }

    protected String getBody() {
        if (bodyContent == null) {
            return "";
        } else {
            return bodyContent.getString().trim();
        }
    }
   
    protected abstract void prepareData ();

    public int doEndTag() throws JspException {
        try {
            prepareData ();
            include(templatePath + this.getTemplateName(), pageContext.getOut(),
                    pageContext.getRequest(),
                    (HttpServletResponse) pageContext.getResponse());

        } catch (Exception e) {
            // e.printStackTrace();
            throw new JspException(e);
        }
        return EVAL_BODY_INCLUDE;
    }

    public int doStartTag() throws JspException {
        try {
            pageContext.getOut().write(getBody());
        } catch (IOException e) {
            throw new RuntimeException("IOError: " + e.getMessage(), e);
        }
        return EVAL_PAGE;
    }

    public static void include(String aResult, Writer writer,ServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        String resourcePath = aResult;
        RequestDispatcher rd = request.getRequestDispatcher(resourcePath);
        if (rd == null) {
            throw new ServletException("Not a valid resource path:"
                    + resourcePath);
        }
        // Include the resource
        PageResponse pageResponse = new PageResponse(response);

        // Include the resource
        rd.include((HttpServletRequest) request, pageResponse);

        // write the response back to the JspWriter, using the correct encoding.
        String encoding = "GB2312";

        if (encoding != null) {
            // use the encoding specified in the property file
            pageResponse.getContent().writeTo(writer, encoding);
        } else {
            // use the platform specific encoding
            pageResponse.getContent().writeTo(writer, null);
        }
    }

    static final class PageResponse extends HttpServletResponseWrapper {

        protected PrintWriter pagePrintWriter;

        protected ServletOutputStream outputStream;

        private PageOutputStream pageOutputStream = null;

        /**
         * Create PageResponse wrapped around an existing HttpServletResponse.
         */
        public PageResponse(HttpServletResponse response) {
            super(response);
        }

        /**
         * Return the content buffered inside the {@link PageOutputStream}.
         *
         * @return
         * @throws IOException
         */
        public FastByteArrayOutputStream getContent() throws IOException {
            // if we are using a writer, we need to flush the
            // data to the underlying outputstream.
            // most containers do this - but it seems Jetty 4.0.5 doesn't
            if (pagePrintWriter != null) {
                pagePrintWriter.flush();
            }

            return ((PageOutputStream) getOutputStream()).getBuffer();
        }

        /**
         * Return instance of {@link PageOutputStream} allowing all data written
         * to stream to be stored in temporary buffer.
         */
        public ServletOutputStream getOutputStream() throws IOException {
            if (pageOutputStream == null) {
                pageOutputStream = new PageOutputStream();
            }

            return pageOutputStream;
        }

        /**
         * Return PrintWriter wrapper around PageOutputStream.
         */
        public PrintWriter getWriter() throws IOException {
            if (pagePrintWriter == null) {
                pagePrintWriter = new PrintWriter(new OutputStreamWriter(
                        getOutputStream(), getCharacterEncoding()));
            }

            return pagePrintWriter;
        }
    }

    static final class PageOutputStream extends ServletOutputStream {

        private FastByteArrayOutputStream buffer;

        public PageOutputStream() {
            buffer = new FastByteArrayOutputStream();
        }

        /**
         * Return all data that has been written to this OutputStream.
         */
        public FastByteArrayOutputStream getBuffer() throws IOException {
            flush();

            return buffer;
        }

        public void close() throws IOException {
            buffer.close();
        }

        public void flush() throws IOException {
            buffer.flush();
        }

        public void write(byte[] b, int o, int l) throws IOException {
            buffer.write(b, o, l);
        }

        public void write(int i) throws IOException {
            buffer.write(i);
        }

        public void write(byte[] b) throws IOException {
            buffer.write(b);
        }
    }
   
   
    static public class FastByteArrayOutputStream extends OutputStream {

        // Static --------------------------------------------------------
        private static final int DEFAULT_BLOCK_SIZE = 8192;


        private LinkedList buffers;

        // Attributes ----------------------------------------------------
        // internal buffer
        private byte[] buffer;

        // is the stream closed?
        private boolean closed;
        private int blockSize;
        private int index;
        private int size;


        // Constructors --------------------------------------------------
        public FastByteArrayOutputStream() {
            this(DEFAULT_BLOCK_SIZE);
        }

        public FastByteArrayOutputStream(int aSize) {
            blockSize = aSize;
            buffer = new byte[blockSize];
        }


        public int getSize() {
            return size + index;
        }

        public void close() {
            closed = true;
        }

        public byte[] toByteArray() {
            byte[] data = new byte[getSize()];

            // Check if we have a list of buffers
            int pos = 0;

            if (buffers != null) {
                Iterator iter = buffers.iterator();

                while (iter.hasNext()) {
                    byte[] bytes = (byte[]) iter.next();
                    System.arraycopy(bytes, 0, data, pos, blockSize);
                    pos += blockSize;
                }
            }

            // write the internal buffer directly
            System.arraycopy(buffer, 0, data, pos, index);

            return data;
        }

        public String toString() {
            return new String(toByteArray());
        }

        // OutputStream overrides ----------------------------------------
        public void write(int datum) throws IOException {
            if (closed) {
                throw new IOException("Stream closed");
            } else {
                if (index == blockSize) {
                    addBuffer();
                }

                // store the byte
                buffer[index++] = (byte) datum;
            }
        }

        public void write(byte[] data, int offset, int length) throws IOException {
            if (data == null) {
                throw new NullPointerException();
            } else if ((offset < 0) || ((offset + length) > data.length) || (length < 0)) {
                throw new IndexOutOfBoundsException();
            } else if (closed) {
                throw new IOException("Stream closed");
            } else {
                if ((index + length) > blockSize) {
                    int copyLength;

                    do {
                        if (index == blockSize) {
                            addBuffer();
                        }

                        copyLength = blockSize - index;

                        if (length < copyLength) {
                            copyLength = length;
                        }

                        System.arraycopy(data, offset, buffer, index, copyLength);
                        offset += copyLength;
                        index += copyLength;
                        length -= copyLength;
                    } while (length > 0);
                } else {
                    // Copy in the subarray
                    System.arraycopy(data, offset, buffer, index, length);
                    index += length;
                }
            }
        }

        // Public
        public void writeTo(OutputStream out) throws IOException {
            // Check if we have a list of buffers
            if (buffers != null) {
                Iterator iter = buffers.iterator();

                while (iter.hasNext()) {
                    byte[] bytes = (byte[]) iter.next();
                    out.write(bytes, 0, blockSize);
                }
            }

            // write the internal buffer directly
            out.write(buffer, 0, index);
        }

        public void writeTo(RandomAccessFile out) throws IOException {
            // Check if we have a list of buffers
            if (buffers != null) {
                Iterator iter = buffers.iterator();

                while (iter.hasNext()) {
                    byte[] bytes = (byte[]) iter.next();
                    out.write(bytes, 0, blockSize);
                }
            }

            // write the internal buffer directly
            out.write(buffer, 0, index);
        }

        public void writeTo(Writer out, String encoding) throws IOException {
            // Check if we have a list of buffers
            if (buffers != null) {
                Iterator iter = buffers.iterator();

                while (iter.hasNext()) {
                    byte[] bytes = (byte[]) iter.next();

                    if (encoding != null) {
                        out.write(new String(bytes, encoding));
                    } else {
                        out.write(new String(bytes));
                    }
                }
            }

            // write the internal buffer directly
            if (encoding != null) {
                out.write(new String(buffer, 0, index, encoding));
            } else {
                out.write(new String(buffer, 0, index));
            }
        }

        /**
         * Create a new buffer and store the
         * current one in linked list
         */
        protected void addBuffer() {
            if (buffers == null) {
                buffers = new LinkedList();
            }

            buffers.addLast(buffer);

            buffer = new byte[blockSize];
            size += index;
            index = 0;
        }
    }
}

2、定义一个具体的标签类
public class ListTag extends RiseAbstractTag {

    private static final long serialVersionUID = 3385568988234498913L;

    protected String templateName = "list.jsp";

    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    protected void prepareData() {
        this.setTemplateName(this.templateName);
        pageContext.getRequest().setAttribute("id", this.id);
    }
}

3、定义TLD文件
   参考TLD文档
4、定义list.jsp模板
<%@ page contentType="text/html; charset=GBK" %>

<%
String id = (String)request.getAttribute("id");
%>
<table width="90%" border="0" cellpadding="0" cellspacing="2">

  <tr>
    <td>Id</td>
    <td align="right"><%= id %></td>
  </tr>
</table>
5、使用默认模板
   <WWTag:list id="Hello World!"/>
6、使用自定义模板
   a: 定义模板
<%@ page contentType="text/html; charset=GBK" %>

<%
String id = (String)request.getAttribute("id");
out.println("Id is : " + id);
%>
   b: use it , 模板名:testList.jsp,放在/WEB-INF/tags目录下
   <WWTag:list id="Hello World!" templateName="testList.jsp"/>


posted on 2006-03-16 22:57 西部村里人 阅读(1114) 评论(2)  编辑  收藏 所属分类: WebWork+FreeMarker

评论

# re: WebWork标签技术的简化版本--JSP模板[未登录] 2007-01-17 22:03 过客

这种写法,可能会丢字符,即使不丢字符,能保证页面正常输出,
private static final int DEFAULT_BLOCK_SIZE = 8192;
这样就说明要是有人访问就要开辟8M的空间写数据,如果并发量打了,是不是就要报outofmemory呢?对不?考虑一下吧!  回复  更多评论   

# re: WebWork标签技术的简化版本--JSP模板[未登录] 2007-01-18 01:16 过客

应改为:(仅供参考)

if ((index + length) > blockSize) {
/*int copyLength;
do {
if (index == blockSize) {
addBuffer();
}
copyLength = blockSize - index;

if (length < copyLength) {
copyLength = length;
}

System.arraycopy(data, offset, buffer, index, copyLength);
offset += copyLength;
index += copyLength;
length -= copyLength;
} while (length > 0);*/
addBuffer();
if(length > blockSize){
buffer = new byte[length];
System.arraycopy(data, offset, buffer, index, length);
addBuffer();
}else{
System.arraycopy(data, offset, buffer, index, length);
index += length;
}
} else {
// Copy in the subarray
System.arraycopy(data, offset, buffer, index, length);
index += length;
}
  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问