4.3.構造生成XML的servlet 這一步的主要實現是從數據表中提取符合要求的記錄生成嵌套的XML,servlet的源碼是XMLServlet.java,選用oracle作數據庫服務器。 對數據庫記錄處理的過程基本上類似于XSL模版的處理: 先查找layer的值為0的記錄,對該記錄進行分析,分析是否具有下級節點,這是通過該記錄的href是否為空來進行分支處理的,href為空時,通過id的輸入參數進行遞歸查找,請參見XMLServlet.java源碼。
/*RowSet是ResultSet的增強類,具有可序列化的特點,所以代替ResultSet來作為可以放入SessionBean的結果集類型*/ import javax.sql.RowSet; /*com.sitechasia.ejb.*包含需要的SessionBean的遠程接口類*/ import com.sitechasia.ejb.*; public class XMLServlet extends HttpServlet { PrintWriter out; private static ResultEdit re; private Object ref; boolean flag=true; private Handle handle=null; private static String HostIP = null; private static String HostPort = null;
private static final String CONTENT_TYPEX = "text/xml"; private static final String CONTENT_TYPEH = "text/html"; /*不同的顯示頁面使用的XSL模版不一樣,在這里先定義調用的XSL模版名稱*/ private static final String CONTENT_XSLT = "<?xml-stylesheet type=\"text/xsl\" href=\"/xsl/treefunc.xsl\"?>"; private static final String CONTENT_XSLC = "<?xml-stylesheet type=\"text/xsl\" href=\"xmltreexsl.xsl\"?>";
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try{ /*獲得客戶端的session,判斷該session里面是否含有SessionBean的句柄和其他相關內容,依據判斷結果進行分支處理*/ HttpSession session=request.getSession();
if( session.getAttribute("ResultEditHandle")==null) { flag=false; } else { flag=true; /*獲得保存在Session中SessionBean的句柄*/ handle=(Handle)session.getAttribute("ResultEditHandle"); /*從獲得的句柄得到SessionBean的EJB實例*/ re =(ResultEdit)handle.getEJBObject(); } /*session中含有SessionBean的分支處理*/ if (flag){ /*從SessionBean的實例中得到可序列化的結果集RowSet*/ RowSet rs = re.getRowSet(); response.setContentType(CONTENT_TYPEX); out = response.getWriter(); out.println("<?xml version=\"1.0\" encoding=\"gb2312\" ?>"); /*通過判斷Servlet是否帶有request參數,來判斷使用哪種模版*/ if (request.getParameterValues("clickId")==null){ out.println(CONTENT_XSLT); } else { out.println(CONTENT_XSLC); } out.println("<project>"); /**使用遞歸算法按層次把結果集中的記錄排列,這里沒有使用結果集的各個字段名稱來指定數據的取值,而是通過結果集的字段序號來取得相應的數據值的,所以需要把提交表單中查詢語句按照這里規定的字段序號來書寫,這樣可以使有不同字段名稱的不同的結果集按照一定順序書寫后,都可以用來生成XML樹,在這里規定了字段序號的相對應的名稱,在4.2.的數據表的結構定義中有詳細描述,下面指出代碼中指定的序號對應的模版字段名稱: id 1 表示序號,是節點的唯一標識; layer 2 層,頂層是從0開始計算,依此類推; name 3 節點的名稱,也可以是節點的唯一識別標識; value 4 節點在瀏覽器中顯示的名稱,為用戶提供一個快速查看 father 5 父節點的id值,除開layer為0的節點該值為0; herf 6 鏈接對象,當一個節點是樹葉時,存在相應的鏈接,樹杈節點該值為空 target 7 鏈接對象顯示的目標窗口,樹杈節點該值亦為空 */ while(rs.next()){ if (rs.getString(2).equals("0")){ if(rs.getString("herf")==null){ out.println("<node>"); out.println("<id>"+rs.getString(1)+"</id>"); out.println("<layer>"+rs.getString(2)+"</layer>"); out.println("<name>"+rs.getString(3)+"</name>"); out.println("<value>"+(rs.getString(4))+"</value>"); out.println("<father>"+rs.getString(5)+"</father>"); out.println("<href></href>"); out.println("<target></target>"); childnode(rs.getString(1)); out.println("</node>"); } else { out.println("<node>"); out.println("<id>"+rs.getString(1)+"</id>"); … } } } out.println("</project>"); rs.close(); } else { response.setContentType(CONTENT_TYPEH); out = response.getWriter(); out.println("<html><head><title>no EJB message</title><META HTTP-EQUIV='Refresh' CONTENT='2;url=/RefreshPost.html'/></head>"); out.println("<body>"); out.println("<p><p><p><center>Refresh...... return RefreshPost.html</center></p></p></p></body></html>"); } } catch(Exception e){ System.out.println("errror:"+e.getMessage()); e.printStackTrace(); } }
/**Clean up resources */ public void destroy() { } /**方法childnode(String father)是一個遞歸調用的方法,用來生成帶有樹層次關系的XML*/ public void childnode(String father){ try{ RowSet rs = re.getRowSet(); while(rs.next()){ if (rs.getString(5).equals(father)){ if(rs.getString("herf")==null){ out.println("<node>"); out.println("<id>"+rs.getString(1)+"</id>"); … childnode(rs.getString(1)); out.println("</node>"); } else{ out.println("<node>"); … out.println("</node>"); } } } rs.close(); } catch(Exception e){ System.out.println(e.getMessage()); e.printStackTrace(); } } }
|