利用WM L和JSP技术开发WAP OPAC检索平台——以Melinets系统为例

2012-02-15 10:00侯新宇
图书馆研究 2012年2期
关键词:字符浏览器代码

侯新宇

(中国传媒大学图书馆,北京 100024)

1 前言

WAP作为一项全球性的网络通信协议,使移动互联网有了一个通行的标准,把互联网上HTML语言的信息转换成用WML(Wireless Markup Language)描述的信息,显示在移动电话的显示屏上。基于WAP技术的图书馆OPAC(Online Public Access Catalogue)系统,可以利用现有OPAC系统与数据库接口对数据进行检索操作,无需单独建立数据库,保证了检索数据的时效性、精确性,无冗余数据。

2 需求分析

中国传媒大学图书馆(以下简称我馆)因书库面积狭小,无法放置足够的检索终端,在借阅繁忙时段,检索终端前读者人数激增,读者需要花费较长的时间才能借阅所需图书。为了方便读者检索馆藏文献,节省读者检索时间,我馆基于北京邮电大学Melinets自动化业务管理系统,使用JSP脚本语言,结合WML标记语言构建了WAP OPAC检索平台,读者可以手机为检索终端,直接进入开架书库,随时随地进行检索,提高了检索效率.

3 基本WML语言

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编码格式,与页面显示语言保持一致,否则浏览器显示时也会显示为乱码。

4 WML语言中的参数传递

〈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,这样就可以正常的进行页面之间的参数传送了。

5 JSP实现SQL语句检索

〈?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流量。

6 存储过程的调用

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〉

7 结束语

通过上述代码编写,一个简单的WAP OPAC检索站点已经建立。它拥有书刊检索和读者信息查询、续借等常用功能,但还需完善。2011年9月试运行以来,极大地缓解了我馆检索终端不足的现状,目前已很少出现排队等待检索的情况。

猜你喜欢
字符浏览器代码
字符代表几
一种USB接口字符液晶控制器设计
图片轻松变身ASCⅡ艺术画
微软发布新Edge浏览器预览版下载换装Chrome内核
反浏览器指纹追踪
HBM电子称与西门子S7-200系列PLC自由口通讯
创世代码
创世代码
创世代码
创世代码