首    页 建模架构 设计模式 培训咨询 jdon框架 论坛

返回目录列表

显示过滤器组件

过滤显示是论坛动态功能的一项重要功能,原来Jive论坛提供很多显示动态的过滤功能,如Html过滤等,这样可以动态地扩展指定帖子显示格式,如果有广告商看中帖子中的几个关键字,我们可以通过增加过滤器讲这些关键字连接指向广告商的网址,等等。总之,对内容显示样式的多样需求变化要求我们的设计也是可以动态可扩展的。

 

过滤器设计

我们设计通过后台管理来动态安装显示过滤器,如下图显示:

3

过滤器种类主要区分:当前正在使用的过滤器;没有在使用适合的过滤器。

过滤器的管理都通过com.jdon.jivejdon.service.filter. MessageFilterManager实现,MessageFilterManager是接口FilterManager一个实现。

MessageFilterManager通过其构造参数中initProperties()方法初始化过滤器设置,过滤器设置数据是保存在数据库setup数据表中,setupJiveJdon3.0新增的一个数据表,主要用来保存论坛的通用设置数据,原来Jive论坛是通过XML文件来保存设置数据,需要在服务器的绝对路径下写文件操作,这破坏了系统的可移植性和可伸缩性。在JiveJdon3.0中我们使用一个数据表来保存,setup结构如下:

CREATE TABLE setup (

  name varchar(50) NOT NULL default '',

  value text NOT NULL,

  PRIMARY KEY name (name) 

)

其中value字段是一个XML格式的字符串,例如显示过滤器的设置setupname字段值是FilterManager 接口中定义的“FILTERS”,setupvalue字段值是如下:

 

<?xml version="1.0" encoding="UTF-8"?>

<jiveFilters>

    <filterClasses>

        <filter0>com.jdon.jivejdon.service.filter.html.HTMLFilter</filter0>

        <filter1>com.jdon.jivejdon.service.filter.html.Newline</filter1>

        <filter2>com.jdon.jivejdon.service.filter.html.TextStyle</filter2>

        <filter3>com.jdon.jivejdon.service.filter.html.URLConverter</filter3>

        <filter4>com.jdon.jivejdon.service.filter.shield.Profanity</filter4>

        <filter5>com.jdon.jivejdon.service.filter.codeviewer.JavaCodeHighlighter</filter5>

        <filter6>com.jdon.jivejdon.service.filter.html.WordBreak</filter6>

        <filter7>com.jdon.jivejdon.service.filter.html.QuoteFilter</filter7>

        <filter8>com.jdon.jivejdon.service.filter.emot.Emoticon</filter8>

        <filter9>com.jdon.jivejdon.service.filter.html.ImageFilter</filter9>

    </filterClasses>

    <global>

        <filterCount>3</filterCount>

        <filter0>

            <className>com.jdon.jivejdon.service.filter.html.HTMLFilter</className>

        </filter0>

        <filter1>

            <className>com.jdon.jivejdon.service.filter.html.TextStyle</className>

        </filter1>

        <filter2>

            <className>com.jdon.jivejdon.service.filter.html.Newline</className>

        </filter2>

    </global>

</jiveFilters>

这个值是第一次执行时由MessageFilterManagercreateProperties方法实现的。

显示过滤器

显示过滤器都已经在XML配置文件中安装准备就绪,下面是在帖子显示要插入显示过滤器,这只要调用MessageFilterManagerapplyFilters方法即可。applyFilters方法如下:

public ForumMessage applyFilters(ForumMessage message) {

        for (int i = 0; i < filters.length; i++) {

            if (filters[i] != null) {

                message = filters[i].clone(message);

            }

        }

        return message;

    }

通过遍历过滤器集合中的每个过滤器,调用过滤器的clone方法,实现该过滤器中的特殊过滤功能。

下面问题的关键是:在哪个点调用applyFilters方法介入过滤器显示?

在我们的JiveJdon3设计中,ForumMessage对象通常是保存在缓存中的,因此,第一选择是在ForumMessage加入缓存时介入过滤器显示,很显然,这时为时过早,缓存中的ForumMessage可能被用于修改或作其他目的,同时,因为缓存,过滤器是实时更新无法立即得到反映的,对功能有所影响。

所以,将缓存中的ForumMessage对象直接应用显示过滤器规则进行修改,并不是一个非常理想的方案,换句话:介入过滤器显示的切入点过于宽泛,那么能否在某点直接介入呢?

我们发现面向表现层的服务接口ForumMessageServicegetMessage方法是用来获得ForumMessage对象的,因此,在这个方法点中切入是比较合适的,但是又有一个问题:getMessage方法因为方法名称包括get,而且方法返回结果是一个Model类型,符合Jdon框架中缓存拦截器com.jdon.aop.interceptor.CacheInterceptor拦截原则,因此,在表现层真正激活ForumMessageServicegetMessage之前,CacheInterceptor将首先被激活,所以,getMessage方法实体并没有真正被执行。

这样,我们就不希望CacheInterceptor激活,那么比较方便的方式是更改ForumMessageServicegetMessage方法名,我们改为findFilteredMessage,这样在ForumMessageService的子类ForumMessageShellfindFilteredMessage的方法如下:

  public ForumMessage findFilteredMessage(Long messageId){   

        logger.debug("enter findFilteredMessage");

        return filterManager.applyFilters(super.getMessage(messageId));

  }

至此,为了保证表现层每次都能够通过ForumMessageServicefindFilteredMessage获得过滤后的ForumMessage,我们希望缓存对整个表现层都是封闭的,只有业务层能够访问缓存,为了做到这点,除了上述失效CacheInterceptor激活方法外,我们考察帖子显示的执行环节:

messageListAction.do ---> messageList.jsp

MessageListActionJdon框架ModelListAction的子类,ModelListAction主要是根据ForumMessageID集合,调用业务层的findFilteredMessage获得一个个ForumMessage实例,进而封装成集合,供messageList.jsp遍历。

ModelListAction中调用业务层获得ForumMessage之前,会访问缓存,检查缓存中是否有已经保存进去的ForumMessage,因此,我们必须关闭这个缓存访问,这时只要覆盖下列方法就可以了:

protected boolean isEnableCache() {

        return false;

}

  

调试问题

以上过滤器设计编程基本完成,调试时碰到一个非常令人头疼的问题:

messageList中对ForumMessage集合进行遍历时,如下语句:

<logic:iterate id="forumMessage" name="messageListForm" property="list" indexId="i">

  <bean:write name="forumMessage" property="messageId"/>

</logic:iterate>

总是报错:no getter method for the property messageId of the bean forumMessage,也是不是messageListForm集合list中安装的不是ForumMessage对象呢?

通过forumMessage.getClass().getName()打印是com.jdon.jivejdon.service.filter.html.Newline,而Newline是继承ForumMessageDecorator子类,而ForumMessageDecorator又是ForumMessage的子类,现在怎么会不认识ForumMessage呢?

再次检测确认:通过java语句forumMessage.getMessageId()输出没有问题,这说明我们前面逻辑设计正确,为什么Struts的标签<bean:write name="forumMessage" property="messageId"/>会报错呢?

经过研究发现,struts的标签是通过JavaBean反射机制检查某个Bean是否有某个方法,而com.jdon.jivejdon.service.filter.html.Newline等过滤器,我们已经通过NewlineBeanInfo指定其属性,这些属性中没有指定messageId,因而struts的标签会报错。

解决办法有两个:

更改NewlineBeanInfo代码,因为过滤器是可变的,而且数量多,修改量大,而且有这种规定,对于拓展新的过滤器很不方便。

messageListFormlist包装的是真正ForumMessage集合。

2方案比较方便,该方案比较方便,由于过滤的是内容ForumMessagebody字段,因此,我们将最终过滤后的bodu内容再装回ForumMessage当中,因此,更改ForumMessageService的子类ForumMessageShellfindFilteredMessage的方法如下:

public ForumMessage findFilteredMessage(Long messageId){   

        logger.debug("enter findFilteredMessage2");

        ForumMessage forumMessage = super.getMessage(messageId);

      

ForumMessageDecorator forumMessageDecorator = null;

        ForumMessageDecorator[] filters = filterManager.getFilters();

        for (int i = 0; i < filters.length; i++) {

            if (filters[i] != null) {

                logger.debug("enter applyFilter: " +  filters[i].getClass().getName());

                forumMessageDecorator = filters[i].clone(forumMessage);

        //forumMessageDecorator过滤后的body装回forumMessage

                forumMessage.setBody(forumMessageDecorator.getBody());

            }

        }

        return forumMessage; //返回的是货真价实的ForumMessage

    }

 

 

 

业务过滤器体系

 

设立两种过滤器:In类型和Out类型;如下图:

3

In类型过滤器:主要是帖子形成或修改时发生作用,主要是对ForumMessage进行一些增添和修改。

Out类型过滤器:主要是帖子输出显示时发生作用,用于在ForumMessage显示输出时对内容进行适当的修饰。

这两种过滤器的特点:就是对ForumMessage一些字段如subjectbody 或者Property进行修改,当然可以拓展到其他字段进行修改。

 

com.jdon.jivejdon.manager.message.InFilterManager属于In类型过滤器,InFilterManager目前和UploadFilterManager有依赖,因为上传文件或图片需要加入img等特殊语法在ForumMessagebody中,以后如果有其他属于In类型过滤器类型的可加入。

 

com.jdon.jivejdon.manager.message.OutFilterManager属于Out类型过滤器

 

业务过滤器专门在划分为InOut主要是因为在考虑ForumMessageProperty设计时促成的。

 

更多Jdon框架专题讨论

JdonFramework作为一个免费开源软件开发平台,可以商用开发大多数数据库应用软件和管理软件: 电子商务软件 在线教育软件 税务软件 Web快速开发软件 财务软件 购物车软件 医院帐务软件 crm software medical software 人事薪资软件payroll software 在线购物软件 销售软件 项目管理软件 房产不动产管理软件 生产软件 PDM软件 制造业软件 仓库软件 采购软件 进销存软件 危险源监控软件 物流软件 超市软件 银行软件 保险软件 汽车软件 医疗软件 电子软件 自动化软件 服装软件 烟草软件 分销管理软件 供应商管理软件

下载源码

框架文档

框架应用系统

演示运行

JiveJdon3

性能测试

Q&A 问答

技术支持

 

 

更多标签...



Jdon框架演示

JiveJdon
源码下载

VIP收费区

历史热点讨论排行榜




google yahoo 新浪ViVi 365Key网摘 天极网摘 CSDN网摘 添加到百度搜藏 POCO网摘





手机 add to google add to yahoo
联系我们 | 关于我们 | 广告联系 | 网站地图 | 设为首页

沪ICP证08026060 如有意见请与我们联系 Powered by JdonFramework
_×
您有新消息