开发一个系统登录的portlet 北京东华合创数码科技公司郑文平 内容简介: 我们用ibm自带的开发工具WSAD(已安装portlet toolkit包),开发一个Portlet,实现以下功能: l 用户不想通过点击系统右上角的“登录”按钮后切换到系统的登录页面,而是从首页山直接登录。这个portlet就实现了这个功能,用户可以从首页上输入用户名和密码并提交,登录成功后读取该用户在OA服务器上的邮件系统,并返回个人邮件信息、欢迎信息,转入并显示在指定页面; l 用户不能从Portal系统原登录页面登录。即:如果用户验证失败,系统会转向自带的登录页面,我们修改那个文件,使之强行定位到该Portlet所在的页面。系统将显示为该登录portlet,而非系统自带的登录页面; l 用户可以通过Url_Mapping功能,从这个portlet直接进入到指定的任意逻辑、物理页面,也可以进入到虚拟门户允许的首页。 其数据流转是这样的:
[开发过程] 1、首先编写这个类,用来读取OA系统中任一用户的邮件系统: package youjiantishi; import java.util.*; import java.io.*; import javax.mail.*; import javax.mail.event.*; import javax.mail.internet.*; import javax.activation.*; public class msgOAshow { static String protocol; static String host = null; static String user = null; static String password = null; static String mbox = null; static String url = null; static int port = -1; static boolean verbose = false; static boolean debug = false; static boolean showStructure = false; static boolean showMessage = false; static boolean showAlert = false; static boolean saveAttachments = false; static int attnum = 1; static int dhcc_totalmsg=0; static int dhcc_newmsg=0; public int get_total() { return dhcc_totalmsg; } public int get_new() { return dhcc_newmsg; } public msgOAshow() { java.io.InputStream inputstream = getClass().getResourceAsStream("mailaddress.properties"); Properties properties = new Properties(); try { properties.load(inputstream); } catch(Exception exception) { System.err.println("Can not read the properties file. Make sure db.properties is in the CLASSPATH"); return; } host = properties.getProperty("address", "localhost"); protocol=properties.getProperty("protocol", "pop3"); mbox=properties.getProperty("mbox", "INBOX"); } public static int getEmailMain(String argv[]) { int msgnum = -1; int optind; user=argv[0]; password=argv[1]; try { // Get a Properties object Properties props = System.getProperties(); // Get a Session object Session session = Session.getInstance(props, null); session.setDebug(debug); // Get a Store object Store store = null; if (url != null) { URLName urln = new URLName(url); store = session.getStore(urln); if (showAlert) { store.addStoreListener( new StoreListener() { public void notification(StoreEvent e) { String s; if (e.getMessageType() == StoreEvent.ALERT) s = "ALERT: "; else s = "NOTICE: "; //System.out.println(s + e.getMessage()); } }); } store.connect(); } else { if (protocol != null) store = session.getStore(protocol); else store = session.getStore(); // Connect if (host != null || user != null || password != null) store.connect(host, port, user, password); else store.connect(); } // Open the Folder Folder folder = store.getDefaultFolder(); if (folder == null) { //System.out.println("No default folder"); //System.exit(1); return -1; } if (mbox == null) mbox = "INBOX"; folder = folder.getFolder(mbox); if (folder == null) { //System.out.println("Invalid folder"); //System.exit(1); return -1; } // try to open read/write and if that fails try read-only try { folder.open(Folder.READ_WRITE); } catch (MessagingException ex) { folder.open(Folder.READ_ONLY); } int totalMessages = folder.getMessageCount(); if (totalMessages == 0) { //System.out.println("Empty folder"); folder.close( false); store.close(); dhcc_totalmsg=0; dhcc_newmsg=0; return 0; //System.exit(1); } int newMessages = folder.getNewMessageCount(); System.out.println("Total messages = " + totalMessages); System.out.println("New messages = " + newMessages); //System.out.println("-------------------------------"); dhcc_totalmsg=totalMessages; dhcc_newmsg=newMessages; folder.close( false); store.close(); } catch (Exception ex) { System.out.println("Oops, got exception! " + ex.getMessage()); //ex.printStackTrace(); //System.exit(1); return -2; } return 0; } } 2、用WSAD开发一个使用凭证保险库的portlet,最好选用共享保险槽。接下来,在Portlet的View.jsp页面中我们提供用户登录表单(表单源代码略): <wps:if loggedIn="no"> //如果用户没有登录,我们显示为登录表单:
该表单接收到用户名和密码后,提交到ChenkLogin.jsp文件。 <wps:if loggedIn="yes"> //当用户登录后,调用这个类读取OA系统: <jsp:useBean id="msgOAshow" scope="page" class="youjiantishi.msgOAshow"/> <% String MyName=(String)(session.getAttribute("userid")); String MyPass=(String)session.getAttribute("password"); String argv[]=new String[2]; argv[0]=MyName; argv[1]=MyPass; boolean b_flag=false; int i=msgOAshow.getEmailMain(argv); if (i!=0) { //out.println("读取用户时发生错误!"); b_flag=true; } else { b_flag=false; } %> 然后,将读到的内容显示出来(源代码略),并添加欢迎信息:
图:获取该用户的邮箱信息,并显示出来。 我们在这个jsp页面上显示出该用户的邮箱信息,并显示欢迎该用户的字样。该欢迎信息是这样获取的: l 首先,引入wps标签库: <%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %> 引入该标签库后,我们就可以使用其中的标签了,比如上面用到的: <wps:if loggedIn="no"> //当用户没有登录时。 </wps:if> l 我们引入欢迎标签:welcome: <wps:text key="welcome" bundle="nls.engine"> <wps:textParam><wps:user attribute="givenName"/></wps:textParam> </wps:text> 我们必须在wps包内找到名字为nsl.engine的标签文件,并添加或者修改键值为welcome的标签,并设置成我们要求的格式。这部分具体开发内容同于一般的标签开发,这里不再赘述。有兴趣的朋友可以自己查找资料研究,也可以与作者讨论。 3、新建checklogin.jsp,用来将用户信息提交到portal系统,实现单点登录。 l 新建一个表单,用来将用户信息提交到Portal系统的登陆action。 <form method="POST" action=´/wps/portal/!ut/p/.cmd/li´ name="LoginPage"> // <table width="196" height="150" cellspacing="0"> <tr> <% String username=request.getParameter("userid"); String password=request.getParameter("password"); %> <td> <input name="userid" type="hidden" value="<%=username%>"> </td> <td> <input name="password" type="hidden" value="<%=password%>"> </td> </tr> </ta ble> </form> 这个表单用来将提取到的用户信息,提交到portal系统的login系统。其中这里的action我们先使用了编译后的代码,如果您重装了Portal系统,您必须更改此portlet的选项,以符合portal系统登陆要求。读到这里,如果您是一个标签方面的高手,您可能已经猜到了更好的解决方案。是的,将这个portelt切换到配置模式,不如直接引入wps相应地标签库,使用一个简单的标签,就可以用键值将之写死,这些内容实现起来比较麻烦,笔者将在以后的相关文章中详细介绍,有兴趣的朋友,可以关注我的专栏。 l 其他该注意的问题: 到这里该Portlet可以算是开发完了,这里提醒开发者机电该注意的问题: 1)Portal系统的action处理完用户登录后,会返回提交者,即:checklogin.jsp。这是我们所不希望的,因为系统一旦返回到checklogin,checklogin会再次提交!是的,您已经想到了,这会生成一个死循环,计算机的声卡会发出啪啪啪的声音,就是这个原因造成的。解决这个问题,实际上非常简单,我们可以在session里设置一个开关,如果checklogin没有提交过,就打开这个开关,让系统提交;一旦提交过了,就把这个开关关死,死循环的问题就OK了。参考代码如下: if (my_flagid==null) my_flagid=""; if (my_flagid.equals("0")) { session.setAttribute("b_getPortaPass","1"); ……. 2)如果登录成功,我们可以将location转向到myportal的任何页面, 如果登录不成功,系统会向用户要session,也就是用户信息,所以默认会返回到Portal系统自带的login页面,我们可以在.war/screen/html目录下找到login.jsp文件,并用javascript将location强行切换到我们自己开发的首页,也就是单点登录Portlet所在的页面。从而拒绝了系统登录。OK?