OpenJWeb快速开发平台-内容管理系统(CMS)
OpenJWeb快速开发平台-内容管理系统(CMS)
栏目标签库的设计与实现
2010-1-19
王保政
(QQ:29803446)
一、 标签库的设计
为了尽可能减少在JSP页面中直接编写代码,OpenJWeb中新增了栏目显示的标签库,此标签库用来控制在页面中显示的信息栏目的样式、内容,并可以根据权限控制,只有授权的用户才可以看到对应的栏目。
下面是设计的栏目显示的标签库的属性:
<cms:category categoryCode="P0101" rowCount="10" pointColor="#ff0000" titleLen="20" serviceBean="IDBSupportService3" style="Style1" authId="AUTH_CATE1" title="测试!!!!"/>
在JSP页面中可使用
<%@taglib prefix="cms" uri="http://www.openjweb.com/cms/tags" %>
来引用openjweb的cms系统的标签库。
具体属性介绍:
属性名 |
值 |
说明 |
categoryCode |
P0101 |
此栏目编码对应栏目表(cms_category)的cate_code字段,确定栏目编码可以找到此栏目相关的信息条目 |
rowCount |
10 |
在一个栏目中显示的信息行数 |
pointColor |
#ff0000 |
栏目中信息列表开头的小圆点的颜色 |
titleLen |
20 |
栏目中信息标题显示多长的字符串,过长则被截短 |
serviceBean |
IDBSupportService3 |
对应的Spring中配置的数据连接组件 |
Style |
Style1 |
对应栏目样式表中的样式编码,此样式编码对应一段栏目的HTML代码,这样更改栏目样式的时候,不需要在页面中修改。具体见说明1. |
authId |
权限码 |
如果为空串,authId=“”则不需要权限,否则当前用户必须拥有给定的权限码才可以显示栏目,权限码的分配是采用Spring Security机制,在平台中可用权限管理来定义。 |
Titile |
测试 |
这是栏目的标题 |
说明1:
栏目样式配置,对应的功能为门户网站-栏目样式定义,对应的数据库表portal_category_html,此表中定义了栏目编码Style1(对应style_code字段),此编码对应的栏目的html代码:
</div></div><div class="vscape"></div>
<div class="md1"><font color="#FFFFFF"><b>
${categoryTitle}</b></font>
</div>
<div class="md2">
<div class="txt fh" >${infoContent}
</div>
</div>
其中${categoryTitle} 是栏目标题,${infoContent}是隶属此栏目的第一页的信息列表。
这样我们在修改栏目样式的时候,不需要在jsp页面中进行修改了,可直接在栏目样式定义功能中调整就可以了,而且我们还可以设置多个样式,在标签库中可引用其他的样式码。
对比没有使用标签库的JSP页面,首先要在页面前面import一堆java类,然后在页面中到处使用<%%>来分隔java代码和html代码,下面是没使用标签库的jsp部分代码:
<%@ page import="java.util.*"%>
<%@ page import="org.openjweb.core.util.*"%>
<%@ page import="org.openjweb.core.service.*"%>
<%@ page import="org.openjweb.core.entity.*"%>
…
<div class="vscape"></div>
<div class="md1"><font color="#FFFFFF"><b>
其他栏目</b></font>
</div>
<div class="md2">
<div class="txt fh" >
<%
List infoList2 = CMSUtil.getCateInfoList("P0101",10,"desc",20 );
if(infoList2!=null)
{
for(int i=0;i<infoList2.size();i++)
{
CmsInfo infEnt = (CmsInfo)infoList2.get(i);
out.println("<font color=/"#FF0000/">¡¤</font> <a href=/""+infEnt.getInfUrl()+"/" target=/"_blank/">"+infEnt.getInfTitle()+"</a><br /> ");
}
}
%>
可以看出,上面的代码比较长,而使用标签后,只需要通过这种方式就可以动态生成信息栏目:
<cms:category categoryCode="P0101" rowCount="10" pointColor="#ff0000" titleLen="20" serviceBean="IDBSupportService3" style="Style1" authId="AUTH_CATE1" title="测试!!!!"/>
二、 标签库tld文件
Openjweb的标签库放在WEB-INF/tld/openjweb.tld,此文件的具体内容:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>openjweb</short-name>
<uri>http://www.openjweb.com/cms/tags</uri>
<description>
OpenJWeb Cms Tag Library
$Id: openjweb.tld 3173 2010-01-19 08:14:28Z baozhengwang $
</description>
<tag>
<name>category</name>
<tag-class>org.openjweb.core.portal.taglibs.CmsTag</tag-class>
<description>
OpenJWeb Cms category tablib.
</description>
<attribute>
<name>categoryCode</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
category code
</description>
</attribute>
<attribute>
<name>rowCount</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
rowCount
</description>
</attribute>
<attribute>
<name>pointColor</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
point color
</description>
</attribute>
<attribute>
<name>titleLen</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
title len
</description>
</attribute>
<attribute>
<name>serviceBean</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
DB ServiceBean
</description>
</attribute>
<attribute>
<name>authId</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
authId
</description>
</attribute>
<attribute>
<name>style</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
style
</description>
</attribute>
<attribute>
<name>title</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>
category title
</description>
</attribute>
</tag>
</taglib>
此标签属性在上文已经介绍。
三、 在web.xml中引用标签库
在web.xml中的taglib区域添加:
<taglib>
<taglib-uri>http://www.openjweb.com/cms/tags</taglib-uri>
<taglib-location>
/WEB-INF/tld/openjweb.tld
</taglib-location>
</taglib>
四、 标签库实现类org.openjweb.core.portal.taglibs.CmsTag
代码简要说明:
此Tag类读取页面标签中设置的属性,构造html代码输出到页面中,并且可以按用户权限来进行显示,此Tag类灵活结合了SpringSecurity的权限框架,不需要在JSP页面中手工编写跟栏目授权相关的代码。Openjweb中可从v_user_auth视图中读取当前用户拥有哪些权限ID。
package org.openjweb.core.portal.taglibs;
import java.io.IOException;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
import org.apache.log4j.Logger;
import org.openjweb.core.entity.CmsInfo;
import org.openjweb.core.entity.CommUser;
import org.openjweb.core.service.IDBSupportService;
import org.openjweb.core.service.ServiceLocator;
import org.springframework.security.context.SecurityContextImpl;
import org.springframework.web.util.ExpressionEvaluationUtils;
public class CmsTag extends TagSupport
{
private static final Logger logger = Logger.getLogger(CmsTag.class);
private String categoryCode ="";//栏目编码
private int rowCount = 0;//显示的信息条目数量,可直接从页面获得
private String pointColor ="#FF0000"; //信息标题前面的小圆点颜色
private int titleLen = 20;//截取的字符串的长度
private String serviceBean ="IDBSupportService3";
private String authId="";//栏目对应的authId
private String style = "";//栏目的样式
private String title ="";//栏目的标题
public void setTitle(String value)
{
this.title = value;
}
public String getTitle()
{
return this.title;
}
public void setStyle(String value)
{
this.style = value;
}
public String getStyle()
{
return this.style;
}
public void setAuthId(String value)
{
this.authId = value;
}
public String getAuthId()
{
return this.authId;
}
public void setServiceBean(String value)
{
this.serviceBean = value;
}
public String getServiceBean()
{
return this.serviceBean;
}
public void setTitleLen(int len)
{
this.titleLen = len;
}
public int getTitleLen()
{
return this.titleLen;
}
public void setPointColor(String value)
{
this.pointColor = value;
}
public String getPointColor()
{
return this.pointColor;
}
public void setCategoryCode(String value)
{
this.categoryCode = value;
}
public String getCategoryCode()
{
return this.categoryCode;
}
public void setRowCount(int value)
{
this.rowCount = value;
}
public int getRowCount()
{
return this.rowCount;
}
public int doStartTag() throws JspException
{
//似乎可直接从页面获得
final String code = ExpressionEvaluationUtils.evaluateString("cateGoryCode", categoryCode, pageContext);
final String dbService = ExpressionEvaluationUtils.evaluateString("serviceBean", serviceBean, pageContext);
final String pointColor1 = ExpressionEvaluationUtils.evaluateString("pointColor", pointColor, pageContext);
IDBSupportService service = (IDBSupportService)ServiceLocator.getBean(dbService);
//尝试获取用户信息
String loginId="";//当前登录用户
try
{
SecurityContextImpl securityContext=(SecurityContextImpl)pageContext.getSession().getAttribute("SPRING_SECURITY_CONTEXT");
if(securityContext!=null)
{
CommUser currUser = (CommUser)securityContext.getAuthentication().getPrincipal();
logger.info("当前用户为:");//当登录后,会取得用户名称,可以据此来控制权限
logger.info(currUser.getUsername());
loginId = currUser.getLoginId();//当前登录用户
}
}
catch(Exception ex)
{
logger.error("获取用户上下文信息失败");
}
if(this.getAuthId()==null||this.getAuthId().trim().length()==0)
{
//如果没有设置authId,则说明为不限制栏目访问权限
logger.info("未设置权限,可以显示栏目");
}
else
{
//如果有authId,则查看
if(loginId==null||loginId.trim().length()==0)
{
//说明未登录,应该不允许查看栏目
logger.info("当前登录帐号为空,所以不显示内容");
return Tag.SKIP_BODY;
}
else
{
//查找权限
String sql = "select count(*) from v_user_auth where login_id='"+loginId+"' and comm_code='"+this.getAuthId()+"' ";
logger.info("标签中的查询语句:");
logger.info(sql);
try
{
int authCount = service.getJdbcTemplate().queryForInt(sql);
if(authCount ==0)
{
logger.info("此栏目没有获得授权.....");
return Tag.SKIP_BODY;//没有获得授权
}
else
{
logger.info("此栏目获得授权....");
}
}
catch(Exception ex)
{
logger.error(ex.toString());
return Tag.SKIP_BODY;//如果出现异常,不允许访问栏目
}
}
}
try
{
//获取栏目的样式
if(this.getStyle()==null||this.getStyle().trim().length()==0)
{
logger.info("未设置样式,退出!");
return Tag.SKIP_BODY;
}
else
{
String sStyle = this.getStyle();
Object obj = service.getJdbcTemplate().queryForObject("select style_html from portal_category_html where style_code='"+this.getStyle()+"'",String.class);
if(obj==null)
{
logger.info("未设置栏目样式,退出!");
return Tag.SKIP_BODY;
}
else
{
String htmlExpr = obj.toString();
htmlExpr = htmlExpr.replace("${categoryTitle}", this.getTitle());
String infoContents = "";
List list = service.findPage("org.openjweb.core.entity.CmsInfo"," where cateTreeCode in (select treeCode from CmsCategory where cateCode='"+code+"') order by createDt "+"desc",1,20);
if(list!=null&&list.size()>0)
{
for(int i=0;i<list.size();i++)
{
CmsInfo infEnt = (CmsInfo)list.get(i);
infoContents +="<font color=/""+pointColor1+"/">¡¤</font> <a href=/""+infEnt.getInfUrl()+"/" target=/"_blank/">"+infEnt.getInfTitle()+"</a><br /> /r";
}
}
htmlExpr = htmlExpr.replace("${infoContent}", infoContents);
pageContext.getOut().print(htmlExpr);
}
}
}
catch(Exception ex)
{
logger.error("cms tab error:"+ex.toString());
}
return Tag.EVAL_BODY_INCLUDE;
}
}
五、 总结
使用标签库开发JSP页面并不难,这样可以使得JSP页面更加规范,而且给定一个标准的标签库规则,美工人员在制作静态页面后,可以不需要开发人员就能将静态页面转换为JSP动态页面。