理解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文件中注冊依賴關系