JspRun插件开发

来自站长百科
跳转至: 导航、​ 搜索

序言[ ]

插件,是基于 JspRun! 论坛系统之上,设计开发的一种小程序或小方案,用来实现对论坛现有功能扩展和改进。由于 JspRun! 已具有相当完备的底层架构,因此插件并不需要具备很多深层的设计思想,也不需要很专业的开发人员,只要把想实现的功能与论坛的基本体系挂接起来,论坛就能拥有更加个性化的功能。插件与界面风格都是实现论坛个性化的有效方式,前者多用于论坛功能和特性的扩充,后者则用来满足访问者多样化的审美取向。
JspRun! 采用了标准的开发方式,为了方便程序员开发插件和用户安装使用插件,特别设计了一套完整的插件接口,为外挂型插件提供了一系列完善的支持。如果您是程序员,想为论坛实现某些附加功能,请仔细阅读插件设计和插件安装两部分的说明;如果您是论坛建立者,想使用他人开发好的插件模块,则只需阅读插件安装部分的说明。
JspRun! 的插件接口,是JspRun! 开发组设计的一套接口规范,尽量使得插件设计、发布、安装和使用都更加方便,同时与论坛结合的更紧密,有助于程序员把最大限度的精力投入到插件本身去,而无需考虑过多的挂接和兼容问题。
JspRun! 的插件接口采用外挂程序的方式,拥有相对独立而完整的功能,此种方式通常用来实现较多和较为复杂的论坛功能,可以通过 JspRun! 插件接口实现傻瓜化的安装和配置,同时兼容性较好,安装和升级比较方便。
本文档主要对功能相对独立,使用外挂程序方式的插件的设计与使用作以说明。

插件安装[ ]

作为论坛软件的使用者,您将可能获得丰富而多样的论坛插件。此类插件通常由第三方开发,其中大部分为免费提供的形式,在 JspRun! 现有功能的基础上,提供了更加个性化的选择。如果您热衷于为您的网友提供更加个性化的论坛服务,或把 DIY 您的论坛作为一项个人爱好,使用插件进行论坛扩充将会是很好的选择。作为软件开发商,我们无法对插件的安装和使用提供技术支持,因此您使用插件的重要前提,是自身具有相当的经验和程序调试能力,以便在出现问题时妥善的解决,不至于影响到正常的论坛服务。
如果您是插件开发者,并希望公开发布您设计的论坛插件,也请仔细阅读本文档。更多的了解使用者的心态和感受,并将获得的经验应用于插件设计中去,将使您的插件受到更多使用者的欢迎和好评。

使用插件的风险
安装和使用插件无疑为使用者提供了令人兴奋的扩展特性,但您在动手之前必须要考虑清楚使用插件的风险,依据对风险的评估来决定是否安装插件,毕竟对于网站论坛来说,运行稳定和访问快速是压倒一切的根本目标。插件由第三方开发的性质,决定了插件的质量可能参差不齐,可能导致的问题有:

  • 由于对系统权限控制的不精通和安全编码经验的不充足导致的论坛安全性下降,严重时插件可能会被作为攻击论坛系统、非法获取管理权限的入口;
  • 并不是所有的插件作者和开发团队都深谙高效的编码技术和优化的数据结构设计,例如一条编写不当的 SQL 语句,可能会耗费比整个论坛系统更多的服务器资源。因此有些插件可能导致论坛变得不稳定、访问速度变慢、资源消耗提高;
  • 由于 JspRun! 开发组长期坚持对论坛系统的功能及结构进行改进,以实现更优化的系统效率和更强大的系统功能。虽然采用插件接口推荐的设计方式,可以尽可能的避免兼容性问题,但由于插件实现方式的多样性,您使用的插件仍然有可能无法兼容于未来的 JspRun! 版本。通常适用于老版本的插件稍作修改就可以用于新版本 JspRun! 上,因此您需要等待插件开发团队提供专供新版本的插件升级包,或自行修改代码。某些情况下,因为模板和程序代码的升级,即便插件具有后续兼容性,您仍然需要重复修改插件用到的这些模板和代码,才能把插件挂接在新的版本上;
  • 不少插件作者是属于兼职或个人爱好的性质,并不能坚持对插件提供升级和技术支持,因此您不能奢望插件作者一直帮助您解决使用插件的疑难问题,您自身良好的代码调试能力和丰富的 Web 应用程序开发使用经验,是使用论坛插件的必要保证。

安装插件的流程
如果您经过以上的风险评估,认为使用插件适合您当前的自身情况,就可以开始插件的安装了。如果插件基于 JspRun! 插件接口进行开发(请参考《插件设计》中的说明),则插件安装的流程就变得非常简单,可以按照如下的步骤进行:

  • 下载所需的插件,仔细阅读插件说明书;
  • 在 系统设置 的 插件管理中,将插件提供的导入代码粘贴到文本框中并提交;
  • 按照插件说明书的描述,修改指定模板、程序,上传相应的插件文件到指定的目录;
  • 按照插件说明书的描述,开启插件、设置插件参数并开始使用插件。

注意:上述步骤只是按照通用流程进行描述的,如果本文介绍的安装流程与插件说明书中的描述不符,请以插件提供者的描述为准。

插件设计[ ]

您在开始论坛插件的设计之前,有必要了解一下我们所推荐的插件设计方式,更好的规范性和兼容性,将使得您设计的插件受到更多使用者的欢迎,对于程序员而言,也有助于形成良好的编码习惯,实现自身能力的提升。如果您有意编写 JspRun! 论坛插件,请按照先后顺序仔细阅读本文档。

准备工作[ ]

插件实现流程
开始编写论坛插件,您应当首先对插件实现的流程有一个大致的了解,以下是我们推荐的插件编写流程:

  • 熟练使用 JspRun! 论坛系统后,对希望完善或补充的个性化功能进行评估,进而提出插件的功能需求。
  • 对插件做一个概括性的设计,例如:需要使用什么菜单、什么参数,配置哪些选项、数据结构如何设计、前后台实现哪些功能等等。。
  • 阅读本文档并在系统设置中实际体验 JspRun! 插件接口所实现的功用,例如:您的插件应当如何设计才能良好的挂接到论坛系统中来。插件接口能够实现哪些功能、不能实现哪些功能,插件为此而需要做的优化、改造和取舍。
  • 编写相应程序代码和模板语句,实现所需的功能并进行代码测试、兼容性测试和代码改进。
  • 如果需要公开您的插件,可以用插件导出的方式,将插件配置信息导出到一个文本文件中,连同相应的程序和模板文件一同打包。同时,编写一个适合新手的插件的说明书也是必不可少的,其中包括:插件适用的 JspRun! 版本、功能概述、兼容性声明、安装方法、使用方法、卸载方法等等。
  • 将插件提供给他人,或自己使用,根据使用者反馈,对插件进行完善。插件实现流程至此结束。

文件命名规范
JspRun! 按照如下的规范对程序和模板进行命名,请在设计插件时尽量遵循此命名规范:

  • 可以直接通过浏览器访问的普通程序文件,以 .jsp后缀命名。
  • 被普通程序文件引用的程序文件,以 .inc.jsp后缀命名。
  • 被普通程序文件,或引用程序文件引用的函数库或类库,以 .func.jsp(函数库) 或 .class.jsp(类库) 后缀命名。
  • 模板文件,以 .jsp 后缀命名,模板文件只存在于 ./templates/default 目录中。
  • 动态缓存文件,存放于 ./forumdata/cache 目录中,依据不同的功能进行独立的命名。
  • 使用后台数据备份功能生成的备份文件,通常以 .sql 为后缀,存放于 ./forumdata/ 目录中。
  • 有些目录中存在内容为空白的 index.htm 文件,此类文件是为了避免 Web 服务器打开 Directory Index 时可能产生的安全问题。

OnlineFilter.java功能白皮书
cn.jsprun.filter.OnlineFilter.java是 JspRun! 的通用初始化过滤程序,其在所有的可执行代码之前被执行,在您开始插件设计之前,可以先对该模块的大致功能做一定的了解。OnlineFilter.java主要完成了以下任务:

  • 对不同 JSP 及操作系统环境做了判断和兼容性处理,使得 JspRun! 可以运行于各种不同配置的服务器环境下。
  • 通过 config.properties 中提供的数据库账号信息,建立数据库连接。
  • 判断用户是否登录并存储在当前会话(HttpSession)中,如登录标记 jsprun_uid 为非 0,同时将 jsprun_user(加了 slash 的用户名,可用于不加修改的插入数据库)、 jsprun_userss(原始的用户名,可用于页面显示)、jsprun_pw(用户密码的MD5串)、jsprun_secques(登录提示问题的加密串)等相应用户信息赋值。
  • 判断用户管理权限并存储在当前会话(HttpSession)中,将管理权限标记 jsprun_adminid 为 -1~3 中间的值。-1 代表为特殊用户组用户。0 代表普通用户;1 代表论坛管理员;2 代表超级版主;3 代表论坛版主。将用户权限按照其所在的主用户组 ID 标记为 jsprun_groupid,相关权限从该 jsprun_groupid 所对应的系统缓存中读出(forumdata/cache/usergroup_${jsprun_groupid}.jsp)。将用户扩展权限按照其扩展用户组 ID 标记为 extgroupids,中间以 \t(tab) 分隔,格式为“groupid1\tgroupid2...”,扩展用户组用于确定用户的扩展浏览权限,例如能否访问某些有特殊权限设定的论坛等。
  • 读入系统设置中的各种变量,并根据 Cache 模块的设定,根据当前被调用的程序文件名(如 index.jsp,forumdisplay.jsp等等)读入相应的缓存代码。缓存代码被存放于 ./forumdata/cache/ 中。除了对应当前程序的缓存,可能还会加载一些通用的缓存数据,例如整个论坛的设置(./forumdata/cache /cache_settings.jsp)、界面风格(./forumdata/cache/style_x.jsp)、当前用户的用户组(. /forumdata/cache/usergroup_x.jsp)、管理组权限(./forumdata/cache /admingroup_x.jsp)等。
  • 缓存数据的格式,大多是存放在 ${cachename} 数组中,有些常用的参数,如系统设置中的参数、风格界面等,通常还被进行了展开操作(extract)或使用常量进行赋值。
  • 用户如果处在登录状态,会自动读出 members 表相关用户的参数值,用户的个性设置参数:如时差、时间格式、界面风格等等,会根据实际情况覆盖系统默认值,因此在后续程序通常不用再做判断。
  • 如果程序提交的 URL 中包含 tid=x 或 fid= x,OnlineFilter.java模块会自动读出其所对应的论坛记录及包括 access masks、版主设定等相应权限。


插件接口概述[ ]

使用管理员账号登录 JspRun! 系统设置,在左侧菜单将可以看到“插件设置”和“插件管理”两个选项,使用超级版主或版主账号登录,将只出现“插件设置”一个选项。“插件管理”是控制插件打开与否、设计插件模块、菜单、参数和使用权限的地方,插件开发者可以依照设计意图,在此进行插件的初步设置,这里同时也提供插件导入和插件开关的功能,用于导入他人设计的插件和对插件的可用状态进行变更。“插件设置”是对已经安装的插件进行设置的地方,供使用者对插件参数进行调整以实现不同的插件功能。即前者主要面向开发者,后者主要面向使用者。
开始编写一个新插件,请首先在插件管理中,输入新插件的名称和惟一标识符。名称用于表明此插件的用途,例如设置为“虚拟银行插件”。惟一标识符用于在后续的插件模块中调用本插件,不可与现有插件重复,命名规则限制与 java 变量命名相同,虽然初次设置后仍可改动,但强烈建议一次性将此配置设置好,否则可能涉及到很多代码方面的变更,增加编码的麻烦。请注意:惟一标识符请不要设置的过短,或使用有可能与其他插件重复的命名,例如制作此插件的公司叫做 JspRun Inc.,插件名称是“虚拟银行插件”,惟一标识符可设置为“jsprun_virtual_bank”,后面将以“虚拟银行插件”和 “jsprun_virtual_bank”为例进行说明。
在插件管理中添加插件后,仅仅是增加了一条插件记录,后面还需要很多相关的设计和设置。在列表中选择插件的“详情”进入插件的详细设置。插件设置分为三个部分:

  • 插件基本设置:
    设置插件的基本参数,配置项目右边括号中的内容,为此设置对应的参数名称,调用方法将在后面的《参数读取与缓存控制》中详细说明。
  • 插件模块和自定义菜单:
    插件接口默认提供六种可选的模块方式:
    • 直接链接(前台菜单):可在前台右上角加入一个菜单项,可自主指派菜单链接的 URL。注意:由于引用外部程序,因此即便设置了模块的使用等级,您的程序如需权限判断,仍需要引用 OnlineFilter.java 和插件相关的缓存文件(将在后面的《参数读取与缓存控制》中详细说明),并自行判断使用等级是否合法。
    • 前台调用(前台菜单):与直接链接类似,但其调用的是插件的一个模块,模块文件名指派为“./plugins/插件目录/插件模块名.inc.jsp”,由 plugin.jsp调用此模块,调用 URL 将在后面的《编写插件的原则与注意事项》中详细说明。
    • 后台调用(后台菜单):可在后台插件设置中为此插件增添一个管理模块,模块文件名指派为“./plugins/插件目录/插件模块名.inc.jsp”,由 admincp.jsp调用此模块,调用 URL 将在后面的《编写插件的原则与注意事项》中详细说明。
    • 包含运行(无菜单):可设置一个在论坛所有页面均包含运行的脚本,此脚本在 OnlineFilter.java 中加载,脚本文件名指派为“./plugins/插件目录/插件模块名.inc.jsp”。请注意,为了不导致错误的插件影响论坛运行,在 OnlineFilter.java 加载此模块时,屏蔽了错误信息,因此请务必仔细检查是否存在语法错误,任何微小的语法错误都将不被提示出来,并且导致此模块不被正常加载。如果您配置了不正确的包含脚本而导致论坛系统设置无法使用,删除服务器上相应的脚本文件即可解决。
    • 直接链接(前台下拉菜单):可在前台右上角加入一个菜单项,并以下拉的方式显示。调用及加载方式同“直接链接(前台菜单)”。
    • 前台调用(前台下拉菜单):可在前台右上角加入一个菜单项,并以下拉的方式显示。调用及加载方式同“前台调用(前台菜单)”。
    您可以为每个模块设置不同的使用等级,例如设置为“超级版主”,则超级版主及更高的管理者(例如论坛管理员)可以使用此模块。
  • 插件钩子设置:
    插件钩子能够将插件代码埋藏在程序中的任意位置,从而实现更加灵活的插件功能,最大限度的减少对原有程序代码的修改。 论坛版本升级后,只需将相应钩子重新埋入相应程序中,原有插件即可继续使用。 关于插件钩子的具体设计方法请见下面的《插件钩子的设计》。
  • 插件变量配置:
    插件接口中提供了一个通用的插件配置管理程序,在大多数情况下可实现插件的参数配置,省却了插件开发者自行编写后台管理模块(即上面提到的“后台调用(后台菜单)”模块)的麻烦。通常情况下,应优先使用通用插件配置管理程序来实现插件的参数配置,只有在通用程序确实无法实现时,才自行编写后台管理模块。输入配置名称和配置变量名、选择合适的配置类型后,即可为此插件增加一个配置变量,点“详情”可以编辑此配置变量的更多信息。为了方便插件程序调用使用者配置好的参数,配置变量同样被存放在了缓存文件中,读取方法将在后面的《参数读取与缓存控制》中详细说明。

注意:您只有在插件管理中将插件设置为“可用”,以上设置才能生效。

参数读取与缓存控制[ ]

编写插件程序时,可能需要读取一些插件的信息,如果插件需要使用者进行配置,还需要读取使用者设置的参数值。JspRun! 允许插件程序使用数据库读取和缓存读取这两种方法获取插件信息和参数。JspRun! 的插件接口已经对插件信息进行了合理的缓存,使用缓存读取的方式,将比数据库读取速度更快,消耗的资源更是几乎可以忽略不计。缓存读取唯一的局限是需要插件使用插件接口提供的通用后台管理程序。如果使用自定义后台模块的方式,需要后台模块将参数存放到 pluginvars 数据表中,才能被系统正常缓存。我们强烈推荐您通过缓存读取插件信息和配置数据。

插件数据结构
插件数据使用两个数据表存放,分别是 plugins 和 pluginvars。前者用于存放插件信息:安装了多少个插件,就有多少条记录;后者用于存放插件的配置参数和配置值:所有已安装的插件总共有多少个配置项目,就有多少条记录。下面的表格列出了这两个表的主要字段及其用途说明。

plugins 表
字段名 用途说明
pluginid 插件的惟一 ID,自动递增
available 插件是否可用,1=是,0=否
adminid 使用系统设置中插件接口自带的插件参数设置程序所需的最低权限等级要求,1=管理员,2=超级版主,3=版主
name 插件名称
identifier 插件惟一标识符
description 插件简介
datatables 插件数据表,不包含前缀,多个表使用半角逗号“,”分隔
directory 插件所在目录,例如设置为 jsprun_bank,则对应论坛目录的位置为 ./plugins/jsprun_bank/
copyright 插件版权信息
modules 插件模块信息,数组格式,使用 serialize() 序列化后存放


pluginvars 表:
字段名 用途说明
pluginvarid 插件配置的惟一 ID,自动地增
pluginid 本项配置所隶属的插件 ID
displayorder 本项配置的显示顺序,数值低的排在前面
title 插件配置的名称
description 插件配置的简介
variable 插件配置的变量名
type 插件配置的类型
value 插件配置的值
copyright 插件版权信息
extra 当本项配置为“选择(select)”时,可选的取值范围


如果您使用自行编写的插件后台管理模块进行插件参数配置,请尽量将配置项目按照 pluginid 的对应关系,将参数存储于 pluginvars 表中,这样系统就可以自动将您增加的配置参数缓存起来,以供插件程序进行调用。

插件参数读取
了解了 JspRun! 插件存储的数据结构后,您可以在插件程序中根据需要选择合适的数据读取方式。由于数据库读取方式可以由数据结构推断而来,因此这里只介绍缓存读取的方式,这种方式是我们强烈推荐的插件数据读取方式。
在管理者配置好插件信息,或用户进行插件的参数设置之后,系统将根据插件设置的惟一标识符,自动生成一个插件数据的缓存文件,例如惟一标识符为 jsprun_virtual_bank,则缓存文件位于 ./forumdata/cache/plugin_jsprun_virtual_bank.jsp,您可以打开此文件查看其中的数据内容和格式。缓存采用数组的方式进行存储,引用此文件即可将所需的插件参数一次性赋值。
其中,${jsprun_virtual_bank} 这个数组下标,为插件的惟一标识符,所有插件缓存数据,一经被引用,就会赋值到 HashMap集合中。modules 描述了这个插件的模块信息,其中 type 为 1~4 的整数值,从小到大依次为“直接链接(前台菜单)”、“前台调用(前台菜单)”、“后台调用(后台菜单)”、“包含运行(无菜单)”;vars 描述了这个插件的配置变量,前面为变量名,后面为使用者赋予这个变量的值。

编写插件的原则与注意事项[ ]

请在您动手编写插件之前,还需要仔细的阅读以下原则,遵循这些原则,将有效的避免可能发生的问题:

  • 所有与插件的程序,包括其全部的前后台程序,请全部放入 ./plugins 目录中,同时在插件的安装说明中指出,插件的文件需要复制到哪些目录。为了避免与其他插件冲突,请尽量建立 ./plugins 下的子目录,并将插件程序放置于子目录下,这样您编写的插件将获得更好的兼容性。
  • 如果您的插件包含“前台调用(前台菜单)”模块,该模块将统一用plugin.jsp?identifier=xxx&module= yyy 的方式调用,请在相应链接、表单中使用此方式。其中 xxx 为插件的惟一标识符,yyy为模块名称。前台插件外壳程序plugin.jsp已经加载了通用初始化模块(OnlineFilter.java),不需再次引用。
  • 如果您的插件包含“后台调用(后台菜单)”模块,该模块将统一用admincp.jsp?action=plugins& amp;identifier=xxx&mod= yyy的方式调用,请在相应链接、表单中使用此方式。其中xxx和yyy的定义与“前台调用(前台菜单)”模块中的相同。系统还允许用 admincp.jsp?action=plugins&edit=${edit}&mod=${mod} 的方式来生成链接和表单地址,${edit} 和 ${mod} 变量已经被插件后台管理接口赋值,因此将这两个变量值带入 URL 中也是被支持的。由于后台模块是被 admincp.jsp 调用,因此已加载了通用初始化模块(OnlineFilter.java)并进行了后台管理人员权限验证,因此模块程序中可直接写功能代码,不需再进行验证。
  • 请勿绕过插件的前后台外壳(plugin.jsp和 admincp.jsp)而以直接调用某程序的方式编写插件,因为这样既导致了用户使用不便,代码冗余和不规范,同时又产生了因验证程序考虑不周到而带来的安全隐患。您可以在任何地方,包括链接、表单等处方便的使用上述 URL 地址对插件模块进行调用。

以免其被 URL 直接请求调用,产生安全问题。

  • 一般情况下,您发布插件请使用插件导出的功能,以方便使用者一次性导入插件的配置数据,极特殊的情况下,也可以分步骤告知使用者如何进行插件配置管理和安装此插件。
  • 如果功能独立,请尽量使用单独程序的方式编写插件(即外挂型插件),而尽量少的对论坛本身代码进行修改,这将为使用者今后的升级带来很大方便。
  • 您可以修改 JspRun! 本身的数据结构,但更推荐在不很影响效率的前提下将插件数据用另外的数据表存储,因为不能排除您增加的字段或索引和今后版本 JspRun! 核心数据字段重名的可能。在任何情况下,请不要删除 JspRun! 标准版本数据结构中已有的字段或索引。
  • 请在插件说明书中对插件做以详尽的描述,例如增加了哪些字段、哪些表,修改了或新增了哪些程序,版本兼容性,后续支持的提供方式(例如不提供支持,或以什么样的方式提供)。如果方便,请尽可能提供插件的卸载方法,例如去除哪些字段、删除哪些新增的程序、将哪些被插件修改的程序恢复原状等等,使用者会感激您为此付出的辛勤劳动,甚至愿意支付相应的费用支持您未来的发展。
  • 如果插件使用另外的数据表存储,请在插件管理中准确的设置插件所使用的数据表名称(不包含前缀),这样用户在备份数据的时候,能够把插件数据一同备份。
  • JspRun! 内置了 8 种自定义积分,存储于 members 表中的 extcredits1 至 extcredits8 字段中,类型为有符号整数,您可以在引用 OnlineFilter.java 后,在 ${settings.extcredits} 中读取 8 种积分的启用信息(详情请参考 ./forumdata/cache/cache_settings.jsp)。插件程序中如需更新用户积分,可直接 UPDATE 相应的积分字段,无需其他操作。


插件钩子的设计[ ]

插件钩子的设计,需要您具有一定编程基础,比较了解 JspRun! 论坛程序的结构,并能够使用 JSP 语言撰写代码。对于普通用户,可以略过以下内容。插件钩子(以下简称“钩子”)属于插件的一部分,因此在设计钩子之前应当首先进入后台——插件管理,新增插件或者编辑一个现有的插件,即可看到相关设置。

钩子的添加

  • 钩子名称:在一个插件内,钩子的名称是唯一的,不可重复。名称可以由英文字母、数字和“_”组成,不支持中文,最长255个字符。为了便于理解和记忆钩子的作用, 名称应当尽量简洁清晰,能够表述一定的含义。注意:钩子名称对字母大小敏感,例如:Index_start 和 index_start 将视为两个不同的钩子。
  • 钩子描述:对钩子的详细说明,如功能介绍、调用方法、使用方法等。
  • JSP代码:这里是钩子的核心内容,也是一段JSP代码,需要您自行设计,完成钩子需要处理的数据或者需要执行的操作。
  • 可用:每个插件允许有多个钩子,您可以自由选择关闭或者开启某个钩子。


钩子的删除
在钩子管理界面,您可以随时删除某一个钩子。 钩子删除以后,您应当及时修正放置钩子的程序文件,清除钩子标记,以免影响您论坛的正常使用。

钩子的编辑与升级

  • 编辑:插件设计阶段,您可能需要随时编辑钩子,每次更改,系统会自动更新缓存文件,您可以立即看到更改的效果。如果是更改钩子名称,那么您可能需要调整钩子放置的程序,修改钩子调用的名称。
  • 升级:论坛程序进行升级之前,您应当使用插件的导出功能,导出插件备份。论坛升级并正常运行后,再导入插件备份,修改相关程序,重新安放钩子。


钩子的放置与调用
钩子设计完成以后,您需要在相应的程序中安放钩子,不同钩子由于作用的不同,放置的位置也是不同的。 安放钩子,您仅仅需要将钩子的调用代码放入即可。

设计范例
此处我们为您提供一个使用钩子技术的插件范例,完成功能十分简单,旨在使您直观的了解钩子的使用。此范例实现了当游客访问论坛首页时,强制用户登录的功能。

  • 进入系统设置中的插件管理,添加一个名称和惟一标识符均为 demo 的插件。
  • 编辑插件 demo 详情,找到“插件钩子设置”,添加一个名为 index_force_loggedin 的钩子,然后提交。
  • 编辑钩子 index_force_loggedin,按如下内容填写设置:
    • 钩子描述:当游客访问论坛首页的时候,程序会弹出提示框,并自动跳转到登陆页面。
    • JSP代码:
      if(jsprun_uid==0){ 
                   request.setAttribute("successInfo", "请您登陆后访问本站,现在将转入登录页面。"); 
                   request.setAttribute("requestPath","logging.jsp?action=login");
                   return mapping.findForward("showMessage");
                 }
  • 提交后,回到此插件的设置页面。将钩子 index_force_loggedin 设置为可用。
  • 点击左侧导航,进入插件管理,将插件 demo 设置为可用。
  • 编辑论坛程序 index.jsp 安放钩子,方法如下:
    • 查找代码:
      jsprun_action = 1;
    • 在上述代码下放添加代码:
       ${hooks.demo_index_alter
    • 保存文件后将文件上传到服务器。
    • 至此,一个简单的使用钩子实现的插件已经彻底完成。您可以退出登陆并访问论坛首页,测试一下插件的效果。

JspRun! 插件的钩子技术,为广大的插件开发者提供了一个更加灵活的插件设计机制。当 JspRun! 升级后,用户只需重新将钩子调用代码安放到程序中原来的位置,就几乎可以继续使用原来已安装的插件,降低了对于程序修改的幅度和插件安装的难度,更加有利于插件程序的规范、管理、维护、相互交流。因此我们强烈建议插件开发者能够深入研究个应用这一机制,创作出越来越多的优秀插件。

插件设置及管理[ ]

插件,是基于 JspRun! 论坛系统之上,设计开发的一种小程序或小方案,用来实现对论坛现有功能扩展和改进。由于 JspRun! 已具有相当完备的底层架构,因此插件并不需要具备很多深层的设计思想,也不需要很专业的开发人员,只要把想实现的功能与论坛的基本体系挂接起来,论坛就能拥有更加个性化的功能。
那么我针对插件管理和设置做一个详细的说明。插件管理主要是针对插件设计者使用,而一般的使用者,使用插件设置即可。
我们进到后台 -> 扩展设置 -> 论坛插件,可以看到个当前安装的插件。如图 1 所示:

Jsprun PluginManagement1.gif


对于插件设计者来说,插件管理到底是怎么使用的呢?或者怎么设计一个插件呢?进插件管理选项。首先得新增加一个插件的配置,那么在新增那里,填写好插件名称和唯一标识符,提交后,就可以得到一个新的插件配置了的。如图 2 所示:

Jsprun PluginManagement2.gif


下面的那个导入插件数据,这个文本输入框,这个是把插件作者设计好的配置,直接粘贴,即可导入论坛。如果插件在论坛的版本不一致的情况下开发的,那么勾选上 允许导入不同版本 JspRun! 的插件(易产生错误!!) 即可导入插件的配置详细。
在我们新增加了一个插件配置后,我们得对插件的配置进行细节的配置。
那么我们增加好的列表里面,选择对应的插件,点详情,如图 3 所示:

Jsprun PluginManagement3.gif


这个就是点帐户中心的详情,进来看到的各个基本配置。但是有这个基本配置还是不够的。
那么需要增加对应的模块来实现需要的功能。但是因为为了插件的安全和使用我们提供的统一调用接口,那么配置对应的模块:如图 4 所示:

Jsprun PluginManagement4.gif


增加对应模块的方法,同样是写上模块的名称(模块的标识符)和 菜单名称即可增加新的模块。
直接链接URL,这个选项,如果填写,那么这个就是在前台增加一个url链接,直接跳转到你填写的地址。

模块类型有下面几种:
直接链接(前台菜单):可在前台右上角加入一个菜单项,可自主指派菜单链接的 URL。注意:由于引用外部程序,因此即便设置了模块的使用等级,您的程序如需权限判断,仍需要引用 OnlineFilter.java和插件相关的缓存文件,并自行判断使用等级是否合法。
前台调用(前台菜单):与直接链接类似,但其调用的是插件的一个模块,模块文件名指派为“./plugins/插件目录/插件模块名.inc.jsp”,由 plugin.jsp调用此模块。
后台调用(后台菜单):可在后台插件设置中为此插件增添一个管理模块,模块文件名指派为“./plugins/插件目录/插件模块名.inc.jsp”,由 admincp.jsp调用此模块。
包含运行(无菜单):可设置一个在论坛所有页面均包含运行的脚本,此脚本在 OnlineFilter.java中加载,脚本文件名指派为“./plugins/插件目录/插件模块名.inc.jsp”。请注意,为了不导致错误的插件影响论坛运行,在 OnlineFilter.java加载此模块时,屏蔽了错误信息,因此请务必仔细检查是否存在语法错误,任何微小的语法错误都将不被提示出来,并且导致此模块不被正常加载。如果您配置了不正确的包含脚本而导致论坛系统设置无法使用,删除服务器上相应的脚本文件即可解决。
您可以为每个模块设置不同的使用等级,例如设置为“超级版主”,则超级版主及更高的管理者(例如论坛管理员)可以使用此模块。
前后台调用方式为:
如果您的插件包含“前台调用(前台菜单)”模块,该模块将统一用plugin.jsp?identifier=xxx& module=yyy 的方式调用,请在相应链接、表单中使用此方式。其中 xxx 为插件的惟一标识符,yyy 为模块名称。前台插件外壳程序 plugin.jsp已经加载了通用初始化模块(OnlineFilter.java),不需再次引用。
如果您的插件包含“后台调用(后台菜单)”模块,该模块将统一用admincp.jsp?action=plugins& identifier=xxx&mod=yyy的方式调用,请在相应链接、表单中使用此方式。其中xxx和yyy的定义与“前台调用(前台菜单)”模块中的相同。系统还允许用admincp.jsp?action=plugins&edit=${edit}& mod=${mod} 的方式来生成链接和表单地址,${edit} 和 ${mod} 变量已经被插件后台管理接口赋值,因此将这两个变量值带入 URL 中也是被支持的。由于后台模块是被 admincp.jsp调用,因此已加载了通用初始化模块(OnlineFilter.java)并进行了后台管理人员权限验证,因此模块程序中可直接写功能代码,不需再进行验证。
这些是模块的设计,基本的变量设置,例如本插件需要用到的设置变量,那么该怎么增加的呢?
在前面点进某个插件的详情,在最下面,就是显示的是本插件当前所有的变量设置:如图 5 所示:

Jsprun PluginManagement5.gif


变量的增加和前面插件的增加类似。例如增加好了一个 管理员是否可用的 这个变量设置,点详情,如图 6 所示:

Jsprun PluginManagement6.gif


根据每一项的左边的提示就可以完成一个变量的设置。
我们设计的插件变量已经设置好了之后,如果我们需要修改到 JspRun! 本身的文件,那么我们可以使用插件钩子。如图 7 所示:

Jsprun PluginManagement7.gif


点详情:如图 8 所示:

Jsprun PluginManagement8.gif


最后调用是在需要修改代码的页面增嵌入例如 ${hooks.accounts_hook}; 这样的代码即可。
现在整个插件的管理我介绍的差不多了。
那么设计出来的插件效果是什么样的呢,那么我们可以到插件设置来看,进入插件设置,如图 9 所示:

Jsprun PluginManagement9.gif


这里就把论坛安装的所有的插件都罗列出来。
就以我们增加的插件帐户中心来看看我们的设计:
首先是插件参数设置:如图 10 所示:

Jsprun PluginManagement10.gif


对应插件管理的设置:如图 11 所示:

Jsprun PluginManagement11.gif


参数设置的效果就是这个样子表现了的。< /p>

那么模块:绑定搜索的效果,如图12所示:(访问的地址:admincp.jsp?action=plugins&identifier=accounts&mod=stats)

Jsprun PluginManagement12.gif


这个对应的插件管理,如图 13 所示:

Jsprun PluginManagement13.gif


那么实际上是后台调用执行了我自己写的模块代码:./plugins/accounts/stats.inc.jsp,如图 14 所示:

Jsprun PluginManagement14.gif


模块:参数设置的效果,如图15所示:(访问地址:admincp.jsp?action=plugins&identifier=accounts&mod=setting)

Jsprun PluginManagement15.gif


对应插件管理:如图 16 所示:

Jsprun PluginManagement16.gif


那么实际上是后台调用执行了我自己写的模块代码:./plugins/accounts/setting.inc.jsp。
后台的插件设置已经已经介绍完毕,那么刚才还有一个 帐户中心的这个模块,这个到哪去了呢?
这个设置为前台的链接:如图 17 所示:

Jsprun PluginManagement17.gif


可以看出是前台的菜单模块,而且是直接链接的。
那么到前台看是什么效果的呢?如图 18 所示:

Jsprun PluginManagement18.gif


就是显示一个链接,跳到你设置的直接链接的 url 。
一个插件配置设计基本就是上面说明了的,我们可以根据需要关闭或者导出这个插件配置如图 19 所示:

Jsprun PluginManagement19.gif


看完上面所有的说明,是不是发现设计一个插件也是如此简单!

插件代码的安全规范[ ]

总的来说 JSP 还是相对安全的 Web 程序,但是由于一些代码在处理方式上的不成熟导致了安全隐患。
那么,对于插件安全究竟我们要做些什么怎么做?
1、变量的初始化
这里不讨论 magic_quotes_gpc 和 register_globals 的设置情况,大家只要注意不要“无中生有”变量,每个变量的得到都是自己初始化过的。
2、逻辑关系清楚
对于逻辑的判定不是一句话能够说明白的,举个简单的例子,在判断上传文件的时候,我们判断的依据是他的后缀是否在我们允许的后缀里面,如果是允许的就执行上传,反之就提示上传文件后缀不对,但是如果用户上传的文件名是 webshell.xxx.mht(允许mht 文件上传,mht 是一种网页存储格式),于是文件上传了,在 apache 系统的默认配置下,这个文件是会用 JSP 来解析的,利用这个算是 BUG 的问题吧,小版本人就曾伙同JSP安全界知名人士(帮他匿了)对我们学校的服务器完成了入侵,并最终取得了 root 权限(目前俺们学校的服务器已经修正此问题),举这个例子是为了说明程序处理的重要性,如果当时多一步判断上传的文件,也许这个安全问题就不再存在,其实这个例子来说明逻辑关系并不是很合适,但是程序处理真的是一个非常重要的部分。
3、' '与" "的区别运用
单引号中,任何变量(var)、特殊转义字符(如“\t \r \n”等)不会被解析,因此JSP的解析速度更快,转义字符仅仅支持“\’”和“\\”这样对单引号和反斜杠本身的转义;
双引号中,变量(var)值会代入字符串中,特殊转义字符也会被解析成特定的单个字符,还有一些专门针对上述两项特性的特殊功能性转义,例如“\$”和“${key}.这样虽然程序编写更加方便,但同时JSP的解析也很慢;
因此,在绝大多数可以使用单引号的场合,禁止使用双引号.依据上述分析,可以或必须使用单引号的情况包括但不限于下述:
字符串为固定值,不包含“\t”等特殊转义字符;
4、数据的过滤与处理
对于任何得到的数据在不能确定或者不能充分确定其来路的时候一定要进行过滤与处理,在数据进入程序运行处理阶段之前,一定要保证它的准确性和正确性。
5、不要相信任何数据的准确性和正确性
这条视乎是和上面一条雷同,但是即使是从数据库中查出来的数据也一样不能确定,比如生成 cache 文件,如果用户 POST 的数据错误不是我们期望的数据,而“恰巧”生成到文件中,于是一个webshell产生了,同样这个例子也不是很合适,我只是希望大家明白这么一点,如果我们没有一个很好的处理数据的方式,那么代码的安全崩溃也就指日可待。
6、不要妄图直接把低版本的 JspRun! 插件直接运行
由于每个大版本的升级都会带来系统构架的一些变化,可能旧版本的插件仍然可以使用,但是或许一些不可预料的问题正在隐藏中,所以建议任何低版本的 JspRun! 插件最好是经过仔细研究之后再公告说可以适用新版本 JspRun! 插件。