理解Block
页面Block是一个组件,页面快。
包含两个部分
- 负责取得数据,而不应该把取数据交给controller
- 负责把数据和相关的页面模块组合生成相应的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文件中注册依赖关系