Jive talkin':开放源码的 Java论坛软件

来源:互联网 发布:c语言编程代码 编辑:程序博客网 时间:2024/06/01 09:25

很快我们就决定采用Jive,正如 lockerjock.com 一样, Jive 采用服务器端Java,支持我们的数据库(mySQL)和应用服务器(JRun), 并采用 JSP文件表示。我们不仅是只有一个论坛,而是可以有很多个性化的论坛。所有的论坛都能很好的和 lockerjock.com 结合在一起。

安装 Jive 和创建 Jive表一样简单。将 jive.jar 文件拷贝到 classpath 目录下, 将论坛和管理JSP 文件放在站点的合适的位置,并运行 Jive 安装页面。唯一的问题就是我们的 JSP 版本是 0.92,而 Jive 需要 JSP 1.0或者更高的版本。因此我花了几天 时间将 JSP升级到最新版本。

Jive 是如何工作的?

Jive 由一系列的存在 SQL 数据库中的表以及一系列的类库组成,这些表中存放论坛数据,类库操纵表、JSP 文件,并能显示论坛数据。两套待用的 JSP 文件和 Jive 一起提供;它们的功能相同,显示论坛并允许用户和论坛交互。lockerjock.com 用的一套是viewForum.jsp,viewMessage.jsp 和 post.jsp。这些 JSP文件的功能如它们的名字一样。 如果想在发送消息和访问论坛时使用 Jive验证方案,正好可以使用这些文件。

Example 1: 一个简单的 Jive应用程序

清单 1 列出的 JSP 文件利用了 Jive主要对象来显示一个给定论坛中线程的名称。后面会详细的讨论每个对象和方法,但是这里给出的概念对理解 Jive 是如何工作是非常重要的。

  • 在开始任何 Jive操作之前,首先创建一个 Jive授权令牌,在本例中将创建一个匿名授权令牌。
  • 利用授权令牌,创建一个具体的论坛工厂。
  • 从论坛工厂创建一个论坛,如果授权令牌的许可和论坛的许可集不匹配,将抛出一个异常,而且用户不能访问论坛。
  • 对论坛中的每一个线程迭带,打印出每个线程的名称。

清单 1:打印论坛中每个线程的名字
<%@ page import="java.util.Iterator,com.coolservlets.forum.*" %> <%   //JSP to print out the names of all the threads in a forum.   //Get an anonymous authorization object.   Authorization auth = AuthorizationFactory.getAnonymousAuthorization();   ForumFactory factory = ForumFactory.getInstance(auth);   //Loading a forum object throws an Unauthorized exception if the   //the permissions set on the forum don't correspond to your access level.   try {       //Load the forum named myForum       Forum forum = factory.getForum("myForum");              //Get an iterator for all the threads in myForum       Iterator threads = forum.threads();       while (threads.hasNext() ) {           ForumThread thread = (ForumThread)threads.next(); %>       <%= thread.getName() %>  <%       }   }   catch (UnauthorizedException ue) {     System.err.println("You do not have permission to read this forum.");   } %>

Jive Example 2: 定制Jive

在 lockerjock我们已经拥有了一些客户以及自己的客户授权方案,因此,如果不修改 Jive授权方案,我们就无法使用它。我们需要将 Jive用户授权方案和我们的用户授权方案融合。 在我修改 Jive 代码中的 SQL使它从我们的用户数据表而不是 Jive 表中查询之前,我觉得如果 使用Jive用户数据表将会非常简单,并且将来需要很少的维护因此,我决定同时保持两套用户数据表。当一个 lockerjock 用户被创建,我同时创建一个 Jive用户;当一个用户改变了它的数据, 我将更新 Jive表中的数据。为了将所用到的所有 Jive 方法进行封装,我创建了 Jivehelp 类。

操纵 Jive 用户需要一个 Jive授权对象。当一个授权对象创建任何用户之前,只有有 Jive 管理员用户(ID 号为 1的用户)创建的授权对象才有操纵其它用户的权力。清单 2 显示了创建一个Jive 授权对象 helper 类的方法。


Listing 2: 创建管理员授权对象
public static Authorization getLJJiveAdminAuthorization(){  if (m_adminAuth != null)   {     return m_adminAuth;    }  else   {     try      { m_adminAuth =          AuthorizationFactory.getAuthorization( ADMIN_ID, ADMIN_PWD );}     catch( UnauthorizedException ue ) {     System.out.println("Error in getLJJiveAdminAuthorization: "                            + ue.toString());     }  }  return m_adminAuth;}

代码首先检查管理员授权对象是否已经存在,然后从 AuthorizationFactory 中创建一个管理员授权对象。管理员授权令牌将被广泛的使用。

下一步是位一个 Jive 用户创建一个 helper 类方法( 参见 清单 3 这段代码通过管理员授权令牌调用 getInstance() 获得一个 ForumFactory 实例。传递给论坛工厂的授权令牌决定所创建的对象在系统中的访问等级;由于利用了管理员授权令牌,因此可以完全访问所有的Jive对象。代理管理所有的用户和组,在本例中,它用来创建用户并设置用户的属性。并返回新创建的用户对象。


Listing 3: 创建一个 Jive 用户
public User createForumUser(String name, String username,                              String password, String email) {    ProfileManager profileManager = null;    ForumFactory forumFactory = null;    User newUser = null;    forumFactory =       ForumFactory.getInstance(ForumHelper.getLJJiveAdminAuthorization());     try {              if (forumFactory != null)       {         profileManager = forumFactory.getProfileManager();         newUser = profileManager.createUser(username,password,email);         newUser.setName( name );         newUser.setEmailVisible(true);         newUser.setNameVisible(true);       }      }    catch( UserAlreadyExistsException uaee )     {           System.out.println("Error in createUser: " + uaee.toString());       System.out.println("User is: " + username);    }    catch( UnauthorizedException ue )     {       System.out.println("Error in createUser: " + ue.toString());    }    return newUser; }

清单 4 显示了获得一个 Jiv e用户的 helper方法。这段代码为被检索的用户创建了一个授权令牌,这个授权令牌中包含了一个用户ID,因为代理用这个 ID 来检索 Jive 用户对象。注意到这个方法包含了利用管理员授权令牌的代理。


Listing 4: 获得一个 Jive 用户
public User getUser(String userName, String password) {    ProfileManager profileManager = null;    ForumFactory forumFactory = null;    User user = null;          Authorization userAuth = getUserAuthorization(userName, password);    if (userAuth == null)    {       return null;    }    forumFactory =       ForumFactory.getInstance(ForumHelper.getLJJiveAdminAuthorization());    try {              if (forumFactory != null)       {          profileManager = forumFactory.getProfileManager();          user = profileManager.getUser( userAuth.getUserID() );       }      }    catch( UserNotFoundException unfe ) {      System.out.println("Error in getUser: " + unfe.toString());    }          return user; }

将它们组合在一起

在 lockerjock 我们利用 servlets (服务器程序片)来管理应用程序、 数据beans 来存放数据,以及 JSP 文件类显示数据。

在登录服务器程序片中,创建了 ForumHelper 并调用 getUser() , 传递从 lockerjock用户获得的名称和密码。如果 Jive用户对象的返回值非空,它将会把其它的 数据 beans保存在会话过程,如清单5中所示。


清单 5: 在会话中添加 Jive 用户
ForumHelper forumHelper = new ForumHelper(); User user = forumHelper.getUser(userBean.getScreenName(),                                 userBean.getPassword());if (user != null){   session.putValue(LockerjockConstants.SESSION_JIVE_USER, user);}

我用了 3 个修改版的 Jive JSP文件: viewForum.jspviewMessage.jsppost.jsp 。因为 Jive 提供的默认的 JSP文件允许非法用户作为一个特殊的匿名用户访问。因为我们要求所有的论坛用户均为 lockerjock 用户,因此我修改了 Jive 的JSP 文件以检查会话,确认 Jive 用户 和 lockerjock的同时存在。只有两个用户同时存在的情况下,该用户才能访问论坛。这段代码在清单6种给出。


清单 6: 从 Jive 论坛的 JSP 文件中控制访问
<% User jiveUser     = (User)session.getValue(LockerjockConstants.LOCKERJOCK_JIVE_USER); UserBean userBean     = (UserBean)session.getValue(LockerjockConstants.LOCKERJOCK_USER_BEAN);     if (jiveUser != null && userBean != null) {   // do forum stuff, yadayadayada }%>

不象默认的 Jive JSP 文件,我们基于 lockerjock用户可以访问的部分来控制对论坛的访问,而不是基于论坛用户的访问许可。例如,只有当用户为某个社区的成员时,他才能访问某个社区的论坛。用户的 Jive 许可服从 lockerjock许可。因此,得到的论坛对象是基于我们的管理员授权不是用户授权。在这点上,如果用户不是这个论坛的授权用户,默认的 JiveJSP 文件将重定向到一个出错页。但我们不需要重定向,因为管理级用户总是被授权的。如果不是 lockerjock这部分的授权用户,在运行 清单 7中的代码前就会被重定向。 这段代码从论坛对象中检索用户的名称。


清单 7: 获得论坛的名称
<%   String pForumID = request.getParameter("forum");      // get the forumID, create the forum object   int forumID =     ((pForumID!=null&&!pForumID.equals(""))?(Integer.parseInt(pForumID)):-1);   ForumFactory forumFactory =      ForumHelper.getForumFactory(ForumHelper.getLJJiveAdminAuthorization());    Forum forum = null;   String forumName = null;   try {        if (forumFactory != null)           forum = forumFactory.getForum(forumID);    }    catch( UnauthorizedException ue )     {      //default Jive forum JSPs redirect to an error page if      //the forum factory doesn't have permission to get this forum    }    catch( ForumNotFoundException fnfe )     {     }   if (forum != null)     forumName = forum.getName();%>

Jive 令我着迷之处还包括一个最酷的特性--随时创建论坛的能力。 清单 8显示了一个简单的简直令人吃惊的方法来创建一个论坛。这个方法仅仅是获得一个带有管理员授权令牌的论坛工厂,然后调用这个论坛工厂的 createForum() 方法。当一个用户创建一个新的主题社区时,利用这个方法可以创建一个新社区论坛。


清单 8: 随时创建一个论坛
public Forum createForum(String name, String description) {    ForumFactory forumFactory = null;    Forum newForum = null;           try     {       if( description == null )         description = "";                    forumFactory =          ForumFactory.getInstance(ForumHelper.getLJJiveAdminAuthorization());              if (forumFactory != null)         newForum = forumFactory.createForum( name, description );    }    catch( UnauthorizedException ue ) {       System.out.println("Error in createForum: " + ue.toString());    }    catch( ForumAlreadyExistsException fae ) {       System.out.println("Error in createForum: " + fae.toString());    }    return newForum; }

小结

Jive 为 Web 群体提供了一个开放源码、100% Java论坛软件包。正如显示的那样,它可以直接应用,也可以修改并扩展以适合各种需要。Jive的开发者是如此的友好、有益、高效。事实上,许多新特性,比如搜索,自从我使用 Jive以来已经被引入。唯一的问题就是花点时间来学习和使用它们。我鼓励你们使用 Jive!




参考资料

  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文.

  • 学习更多关于 Jive知识,并下载代码。

  • 要深入研究 JSP 编码,参看 JSP 技术 --朋友还是敌人?

  • 有关 JSP 的更多技术请参看 developerWorks 提供的教程 JSP 技术入门。

  • 通过 developerWorks 提供的教程 创建 Java HTTP Servlet学习实际编写简单的 HTTP Servlet 的经验。

关于作者

Jay Allen

Jay Allen 是一家大型计算机公司的软件工程师,他在业余时间为lockerjock.com 和其他几个 Web站点工作。可以通过 allenj@us.ibm.com联系 Jay.


原创粉丝点击