美文网首页
页面分块Block

页面分块Block

作者: stutterr | 来源:发表于2017-08-02 17:30 被阅读25次

    理解Block

    页面Block是一个组件,页面快。
    包含两个部分

    1. 负责取得数据,而不应该把取数据交给controller
    2. 负责把数据和相关的页面模块组合生成相应的html片段
    <bean id="product_cat" class="xxx.xx.PrdocutCatBlock">
        <property name="template" value="/WEB-INF/jsp/xx"
    </bean>
    

    其中template的jsp负责显示数据,PrdocutCatBlock负责读取数据和结合template生成相应的html

    product_cat.jsp大体样子

    <div>show product_cat</div>
    

    经过重新定义后的controller伪代码应该是这个样子(去掉了取数据步骤)

    {
         转到相应的jsp页面
    }
    

    jsp页面

    <%@page ~~~~>
    <%@ taglib url="/WEB-INF/jsp/xx" prefix="block"%>
    

    实现一个简单的taglib标签

    • 新建一个TestTaglib extends TagSupport
      重写
      doStartTag() return SKIP_BODY; 当在页面中开始标签时执行的方法 SKIP_BODY表示跳过中间的BODY部分
      doEndTag() return EVAL_PAGE标签结束时执行的方法 EVAL_PAGE表示 如果是SKIP_PAGE表示运行完该标签后后面的page都跳过
      release()方法

    • 在WEB-INF下新建一个block.tld文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3g.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd" version="2.0">
     <tlib-version>1.0</tlib-version>
     <jsp-version>1.1</jsp-version>
     <short-name>Block Taglib</short-name>
    
     <tag>
       <name>test</name>
       <tag-class>com.gavin.exam.taglib.TestTaglib</tag-class>
       <body-content>empty</body-content>
    <!--  定义属性,可以在TestTaglib中get,set 在标签中使用该属性
     <attribute>
       <name>size</name>
       <required>false</required>
       <rtexprvalue>true</rtexprvalue>  动态or静态
     </attribute>
     -->
       <dynamic-attributes>true</dynamic-attributes>
     </tag>
    </taglib>
    

    其中<body-content>empty</body-content>empty代表标签中间不能加内容。如果是JSP,则标签中间能够加内容

    • 在jsp中引用
      <%@ taglib uri="/WEB-INF/block.tld" prefix="block" %>
      其中prefix代表为名字 uri为block路径

    • 使用
      <block:test> 其中block为prefix定义,test为tld文件中<name>test</name>

    完整TestTaglib代码

    public class TestTaglib extends TagSupport {
    
        private static final long serialVersionUID = 6360666785036712366L;
    
        @Override
        public int doStartTag() throws JspException {
            return SKIP_BODY;
        }
    
        @Override
        public int doEndTag() throws JspException {
            JspWriter out = pageContext.getOut();
            try{
                out.println("block test");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return EVAL_PAGE;
        }
    
        @Override
        public void release() {
            super.release();
        }
    }
    

    taglib构架实现

    • 首先定义一个BlockTaglib
    public class BlockTaglib extends TagSupport {
    
        private static final long serialVersionUID = 2324376193807858374L;
    
        private String name;
        
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public int doStartTag() throws JspException {
            return SKIP_BODY;
        }
    
        @Override
        public int doEndTag() throws JspException {
            //这里使用spring框架,如果不使用,应该先解析block定义的xml文件
            ApplicationContext ctx = SpringUtil.getApplicationContext();
            //取到相应的block对象,
            BlockAbstract block  = (BlockAbstract)ctx.getBean(name);
            //得到生成的html片段
            String content = block.displayBlock(pageContext);
            //然后在页面上输出
            JspWriter out = pageContext.getOut();
            
            try{
                out.println(content);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return EVAL_PAGE;
        }
    
        @Override
        public void release() {
            super.release();
        }
    }
    
    • 实现BlockAbstract类,他是一个抽象的block,是其他block的父类,主要用来从template获取html段并输出
    public abstract class BlockAbstract {
    
        public String template; //The JSP template of this block.
        
        public String getTemplate() {
            return template;
        }
    
        public void setTemplate(String template) {
            this.template = template;
        }
    
        private static Logger log = Logger.getLogger(BlockAbstract.class);
        
        public String displayBlock(PageContext pageContext) {
            execute(pageContext); //取数据操作
            
            //HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
            Writer body = new StringWriter();
            try {
                if(template != null && !template.trim().equals("")) {
                    pageContext.pushBody(body);
                    pageContext.include(template);
                    pageContext.popBody();
                    
                    return body.toString();   //生成返回html段
                }
            } catch(Exception e) {
                log.error("log error====>", e);
            } finally {
                try {
                    body.close();
                } catch (IOException e) {
                    log.error("log error==>", e);
                    e.printStackTrace();
                }
                
            }
            
            return "";
        }
    
        abstract protected void execute(PageContext pageContext);
    }
    
    • 之后根据第一段理解Block的基本步骤,注册bean ,编写jsp页面,并在相应的block 继承 BlockAbstract 的类下写下相应的取数据代码 。
      然后在tld文件下将bean的id作为<attribute>的name注册到标签中,以后就可以根据attribute名来选择加载的block

    Block 代码示例

    **java code BookStatusBlock**
    
    public class BookStatusBlock extends BlockAbstract {
    
        private BookService bookService;
        
        public void setBookService(BookService bookService){
            this.bookService= bookService;
        }
        
        @Override
        protected vodi execute(PageContext pageContext){
            //get rqeust object
            HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
            
            //get some object from appContext
            User user = AppContext.getContext().getUser();
            
            /**
            do something
            **/
            //set the returned value 
            request.setAttribute("userName", user.getName);
        }
    }
    
    
    **tld code**
      <tag>
        <name>display</name>
        <tag-class>com.gavin.exam.taglib.BlockTaglib</tag-class>
        <body-content>empty</body-content>
    
      <attribute>
        <name>name</name> 
        <required>true</required>
        <rtexprvalue>true</rtexprvalue> 动态or静态
      </attribute>
    </tag>
    
    
    **bean.xml文件注册代码**
    <bean id="bookStatusBlock " class="com..BookStatusBlock ">
        <property name="template" value="/WEB-INF/jsp/xxxx.jsp"/>  <!--jsp页面-->
        <property name="bookService" ref="bookService"/>
    </bean>
    
    **在jsp页面中调用**
    
    <block:display name="bookStatusBlock " />
    
    

    注意此类中使用的service或其他类也要在xml文件中注册依赖关系

    相关文章

      网友评论

          本文标题:页面分块Block

          本文链接:https://www.haomeiwen.com/subject/eghylxtx.html