侯新宇
(中國傳媒大學圖書館,北京 100024)
WAP作為一項全球性的網絡通信協議,使移動互聯網有了一個通行的標準,把互聯網上HTML語言的信息轉換成用WML(Wireless Markup Language)描述的信息,顯示在移動電話的顯示屏上。基于WAP技術的圖書館OPAC(Online Public Access Catalogue)系統,可以利用現有OPAC系統與數據庫接口對數據進行檢索操作,無需單獨建立數據庫,保證了檢索數據的時效性、精確性,無冗余數據。
中國傳媒大學圖書館(以下簡稱我館)因書庫面積狹小,無法放置足夠的檢索終端,在借閱繁忙時段,檢索終端前讀者人數激增,讀者需要花費較長的時間才能借閱所需圖書。為了方便讀者檢索館藏文獻,節省讀者檢索時間,我館基于北京郵電大學Melinets自動化業務管理系統,使用JSP腳本語言,結合WML標記語言構建了WAP OPAC檢索平臺,讀者可以手機為檢索終端,直接進入開架書庫,隨時隨地進行檢索,提高了檢索效率.
WML1.1規范標準對于標記格式的使用十分嚴格。一些智能手機平臺上安裝的第三方瀏覽器,如UC、Opera等手機瀏覽器雖然可以過濾一些腳本及頁面顯示錯誤,但為了保證在非智能及智能手機平臺上的兼容性,我們應確保頁面編寫要嚴格使用規范的WML1.1標記。
〈?xml version="1.0"encoding="UTF-8"?〉
〈!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml"〉〈wml〉
〈card id="index"title="WAP OPAC For CUC Library"〉
〈p〉
歡迎訪問中國傳媒大學圖書館〈br/〉WAP OPAC 檢索系統! 〈br/〉〈br/〉
〈a href="search.wml"〉書刊檢索〈/a〉〈br/〉〈br/〉
〈a href="reader.wml"〉讀者信息〈/a〉〈br/〉〈br/〉
中國傳媒大學圖書館 版權所有All Rights Reserved
〈/p〉
〈/card〉
〈/wml〉
上面的代碼保存為index.wml,就是一個最簡單的WML腳本,在WML語言中,〈?xml version="1.0"encoding="UTF-8"?〉〈!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml"〉是必須出現在*.wml文件(包括使用JSP腳本語言編寫的*.jsp文件)前兩行的標記中,否則瀏覽器就會報錯。
〈wml〉〈/wml〉則像 html語言中〈body〉〈/body〉一樣,在其中編寫代碼。〈card〉〈/card〉標記則是WML語言特有的標記,每個手機上顯示的內容都是這個標記中編寫的代碼內容。一個wml文件中可以擁有多個〈card〉〈/card〉標記。
手機默認只顯示第一個標記中的內容,使用〈ahref="#cardID"〉go〈/a〉超鏈接標記實現在多個〈card〉〈/card〉標記之間跳轉,實現多個頁面的顯示內容。
encoding="UTF-8"標記表示此文件使用UTF-8編碼顯示,此標記也可以不寫或寫成"GB2312",對于有多語種圖書的圖書館應使用UTF-8編碼顯示,確保小語種字符的正確顯示。在保存*.wml和*.jsp文件時也應將其文件保存為UTF-8編碼格式,與頁面顯示語言保持一致,否則瀏覽器顯示時也會顯示為亂碼。
〈p〉
檢索詞: 〈input type="text"name="content"value=""/〉
〈anchor〉
〈go href="result.jsp"method="post"acceptcharset="UTF-8"〉
〈postfield name = "search_content"value = "$(content)"/〉
〈/go〉
查詢
〈/anchor〉
〈/p〉
上面的代碼是search.wml文件中的一段。用戶在輸入檢索詞內容并點擊“查詢”后,系統將輸入框中的文本命名為search_content,并將內容傳送給result.jsp文件,這樣就完成了一個簡單的參數傳遞過程。在result.jsp文件中使用如下語句進行參數獲取:
request.setCharacterEncoding("UTF-8");
String search_content= request.getParameter("search_content");
search.wml文件用 accept-charset="UTF-8"設置以UTF-8編碼傳送參數,那么在result.jsp文件中也要將接收參數先設置接收編碼為UTF-8,這樣就可以正常的進行頁面之間的參數傳送了。
〈?xml version="1.0"encoding="UTF-8"?〉〈!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml"〉
〈%@page contentType="text/vnd.wap.wml;
charset=UTF-8"language="java"%〉
〈%@page import="java.sql.*"%〉
〈wml〉
〈card title="檢索結果"〉〈p〉
〈%
Class.forName("com.sybase.jdbc2.jdbc.SybDriver");//裝載 JDBC 驅動程序
String url="jdbc:sybase:Tds:IP:PORT/
melinets";//設置數據庫連接字符串
Connection conn=DriverManager.
getConnection(url,"username","password");//連接數據庫
request.setCharacterEncoding("UTF-8");//設置參數編碼是UTF-8格式
String search_content=request.get
Parameter("search_content").toUpperCase();//獲取檢索內容,并將小寫字母全部換成大寫
String strSelect= "select rec_ctrl_id,title,authors,publisher,pubdate_date";
String strFrom = "from manager.index_title";String strWhere;
strWhere="where title_abs like%"+search_content+"%";//index_title表中title_abs字段存儲的都是已經轉換為大寫的字符
strOrder= "order by pubdate_date desc ";
String strSql=strSelect+strFrom+strWhere+strOrder;//SQL語句
ResultSet main_bibli_Rs=main_bibli_Stmt.executeQuery(strSql);//結果集對象
while{main_bibli_Rs.next()}{
String main_bibli_rec_ctrl_id=main_bibli_Rs.getString("rec_ctrl_id");
String main_bibli_title=main_bibli_Rs.get-String("title");
String main_bibli_authors=main_bibli_Rs.get-String("authors");
String main_bibli_publisher=main_bibli_Rs.getString("publisher");
main_bibli_title = main_bibli_title.replaceAll{"([u0000-u001F]|&|〈|〉)",""};//替換掉手機瀏覽器中不支持的不可見字符,和wml中的保留字符如“&”、“〈”、“〉”等。
main_bibli_authors=main_bibli_authors.
replaceAll{"([u0000-u001F]|&|〈|〉)",""};
main_bibli_publisher=main_bibli_
publisher.replaceAll{"([u0000-u001F]|&|〈|〉)",""};
%〉
〈%=main_bibli_title%〉〈br/〉
〈%=main_bibli_authors%〉〈br/〉
〈%=main_bibli_publisher%〉
〈% =main_bibli_Rs.getString("pubdate_date").substring(0,4)%〉〈br/〉
〈anchor〉
〈go href="detail.jsp"method="
post"accept-charset="UTF-8"〉
〈postfield name="sid"value="〈%=main_bibli_rec_ctrl_id%〉"/〉
〈/go〉
查看館藏信息
〈/anchor〉
〈%
main_bibli_Rs.close();
main_bibli_Stmt.close();
conn.close();
}%〉
〈/p〉〈/card〉
〈/wml〉
上面的代碼是result.jsp文件中的一段。文件在接收到search.wml傳送過來的檢索內容后,對數據庫進行檢索查詢,并輸出檢索結果,配合WML標記語言,實現手機瀏覽器的內容顯示。由于WML1.1規范對于字符顯示比較嚴格,雖然UC、QQ瀏覽器等第三方瀏覽器可以自動將一些不可見字符過濾,但對于非智能手機,瀏覽器在接收到這些不可見字符后會出現錯誤提示,無法正確顯示網頁,所以要對從數據庫中提取的內容進行過濾,replaceAll{"([u0000-u001F]|&|〈|〉)",""}函數就是使用正則表達式將所有不可見字符使用十六進制方式將其讀取并進行過濾,對于“&”、“〈”、“〉”等這些WML中的保留字符,可以使用replace("&","&")函數將其轉換為可以顯示的轉義字符,其他類似字符這里就不再贅述。
由于篇幅所限,上述代碼中沒有對檢索結果進行分頁顯示,對于符合WML1.1規范的非智能手機,單個wml文件大小不能超過255 KB。如果超過這個限制,手機會自動截斷頁面文件,從而造成了頁面中缺少〈/card〉或〈/wml〉等結尾標記,導致頁面無法正常顯示而報錯。所以,必須使用分頁顯示技術,且每頁顯示記錄數不宜過多。
手機屏幕比普通顯示器要小,并且分辨率不高。因此,在一個頁面中不宜顯示過多數據。檢索結果應當簡單明了,可顯示題名、著者、出版社、出版年等一些重要信息,讀者點擊查看館藏信息頁面detail.jsp時再顯示圖書的詳細信息。這樣一方面可以減少服務器負擔,加快檢索速度;另一方面可以減少手機GPRS流量。
Melinets系統在sybase數據庫端編寫了大量存儲過程,如續借、預約等。我們在進行這些操作時調用這些編寫好的存儲過程即可,如circul.up_renewal就是續借操作的存儲過程。將相應的參數傳遞給存儲過程,執行存儲過程,即可完成續借操作,下面的代碼就是一個簡單的調用續借存儲過程,完成圖書續借操作。
〈?xml version="1.0"encoding="UTF-8"?〉〈!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml"〉
〈%@page contentType="text/vnd.wap.wml;
charset=UTF-8"language="java"%〉
〈%@include file="include/conn.jsp"%〉
〈wml〉
〈card title="讀者信息 -WAP OPAC For CUC Library"〉〈p〉
〈%
request.setCharacterEncoding("UTF-8");//設置參數編碼是UTF-8格式,或者用下面的字符轉換方法轉換編碼
String input_barcode=request.get
Parameter("username");//讀取用戶名
String input_pwd=request.get
Parameter("userpwd");//讀取密碼
String book_barcode=request.get
Parameter("book_barcode");//讀取圖書條碼
String library_id = "A";//圖書所在館
String note = "";//流通備注
String holdtype = "";//預約類型
String userid = "wap";//操作員代碼
StringstrProc= "{callcircul.up_renewal(?,?,?,?,?,?,?,?,?,?,?)}";//存儲過程語句
CallableStatementCStmt= conn.prepareCall(strProc);//準備可調用語句對象
CStmt.setString(1,library_id);//設置輸入參數
CStmt.setString(2,book_barcode);
CStmt.setString(3,note);
CStmt.setString(4,holdtype);
CStmt.setString(5,userid);
CStmt.registerOutParameter(6,java.sql.Types.IN TEGER);//登記輸出參數
CStmt.registerOutParameter(7,java.sql.Types.DATE);
CStmt.registerOutParameter (8,java.sql.Types.INTEGER);
CStmt.registerOutParameter(9,java.sql.Types.IN TEGER);
CStmt.registerOutParameter(10,java.sql.Types.VA RCHAR);
CStmt.registerOutParameter (11,java.sql.Types.INTEGER);
CStmt.executeUpdate();//執行該存儲過程并返回結果集
String strMsg=CStmt.getString(10);
int strRetu=CStmt.getInt(11);
if(strRetu == 0){//續借成功
%〉
續借成功! 〈br/〉
〈%=strMsg%〉〈br/〉
〈%
}
else{//續借失敗
%〉
續借失敗! 〈br/〉
〈%=strMsg%〉〈br/〉
〈%
}
CStmt.close();
conn.close();
%〉
〈/p〉〈/card〉
〈/wml〉
通過上述代碼編寫,一個簡單的WAP OPAC檢索站點已經建立。它擁有書刊檢索和讀者信息查詢、續借等常用功能,但還需完善。2011年9月試運行以來,極大地緩解了我館檢索終端不足的現狀,目前已很少出現排隊等待檢索的情況。