開發一個系統登入的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?