用JSP+Servlet实现二进制图像的动态显示-JSP教程,Java技巧及代码


数据库应用程序,特别是基于web的数据库应用程序,通常会涉及到图片信息的显示。我们知道在html语言当中为了显示静态的图片资料,可以利用如下标记来实现: 
<img src="../image/hello.png" width="100" height="80">,而要显示动态的图片资料,就要采用相关的数据库访问技术来实现。在jsp环境编程中解决办法多种多样,通常是在数据库中保存相应的图片资料的名称,而后在jsp中可以建立相应的数据源,利用数据库访问技术处理图片信息。在静态标记的基础上,略加修改就可以用如下的标记语言实现动态图片资料的显示,即:<img src="../image/"+rs_photo.getstring(photo_fiield) width="100" height="80">。 
以上两种解决方案,主要是将所要显示的图片资料存在特定的目录下进行存取控制。如果图片资料是存储在数据库中的二进制数据,上述方法就不能满足需要了。实际操作中,可以利用jsp+servlet的编程模式来实现图片资料的浏览显示。其基本思想是,用servlet实现图片资料的后台处理,用jsp进行页面表现,具体的编程思想如下所述。 
1.建立后台数据库和数据库应用程序 
假定处理的是某公司的员工信息,那么我们可以建立相应的数据库及数据表对象。假定我们要存取的数据表结构如下所示: 
/****** object: table [dbo].[employee] script date: 2002-7-31 21:42:10 ******/ 
if exists (select * from dbo.sysobjects where id = object_id(n[dbo].[employee]) and objectproperty(id, nisusertable) = 1) 
drop table [dbo].[employee] 
go 
/****** object: table [dbo].[employee] script date: 2002-7-31 21:42:10 ******/ 
create table [dbo].[employee] ( 
[id] [char] (10) collate chinese_prc_ci_as not null , 
[name] [char] (20) collate chinese_prc_ci_as null , 
[sex] [char] (2) collate chinese_prc_ci_as null , 
[birthday] [datetime] null , 
[photo] [image] null , 
[title] [char] (20) collate chinese_prc_ci_as null , 
[department] [char] (30) collate chinese_prc_ci_as null  
) on [primary] textimage_on [primary] 
go 
其中,employee表中的列photo字段用于存储员工的照片信息,则用于存储图像,其数据类型为“image”。接下来我们就可以建立应用程序,向数据库中添加图文信息。基本的操作数据库应用程序相对简单,大家可以利用流行的多种开发工具加以实现,并向数据库中添加若干记录。图1是利用delphi6实现的一种可行存储image的应用解决方案。 


图1 delphi6操作数据库image列

程序实现的关键技术是流式信息存取技术。即为了实现对image列的存取,在程序中采用了数据流读写图片资料。其实现代码主要在数据保存和记录集移动的事件里。程序代码在此就不再详述。可以参阅作者的文章《用delphi6操作sql server 2000的image列存取jpeg图象》 
2.用jbuilder7建立web应用程序 
对于web应用程序的实现方式,我们可以采用jdk 1.4 java环境、apache tomcat 4.0和dreamweaver mx,也可以选择jbuilder7的集成开发环境。下面我们以jbuilder7集成开发环境为例说明web应用程序的具体实现过程。 
2.1 建立数据库连接池访问 
启动jbuilder7后,新建工程readpicfromdb.jpx。在工程中建立数据库连接池对象类,主要包括一个管理类dbconnectionmanager,负责提供与多个连接池对象dbconnectionpool类之间的接口。每一个连接池对象管理一组jdbc连接对象,每一个连接对象可以被任意数量的servlet共享。类dbconnectionpool可以提供以下功能: 
● 从连接池获取(创建)可用连接 
● 把连接返回给连接池 
● 在系统关闭时释放所有资源,关闭所有连接 
类dbconnectionmanager则用于管理多个连接池对象,它提供以下功能: 
● 装载和注册jdbc驱动程序 
● 根据在属性文件中定义的属性创建连接池对象 
● 实现连接池名字与其实例之间的映射。 
● 跟踪客户程序对连接池的引用,保证睚最后一个客户程序结束时安全地关闭所有连接池。 
上述两个类的详细代码,读者可以参阅相关书籍,这里主要给出本例中用到的属性文件db.properties其代码如下所示: 
**********数据库连接池属性文件db.properties*************** 
drivers=sun.jdbc.odbc.jdbcodbcdriver //定义jdbc-odbc桥驱动程序 
logfile=d:\\webapp\\log.txt //定义日志文件存放的位置和名称 
comdb.url=jdbc:odbc:graduweb //定义数据库的jdbc的url 
comdb.maxconn=10 //定义数据库的最大连接数 
comdb.user=sa //指定用于该连接池的数据库帐号 
comdb.password=sa //数据库相应帐号的密码 
**********数据库连接池属性文件db.properties*************** 
最后将编译过的包含数据库连接池类的java类dbconnectionmanager.java 、dbconnectionmanager.class以及上图的db.properties文件一并放在工程文件的web-inf下的classes目录下。 
2.2 编写读取二进制图片的servlet 
从jbuilder7的file菜单里选择新建servlet,并将其命名为getphoto。该servlet的java源代码如下所示: 
***************servlet getphoto.java 的java代码************* 
import javax.servlet.*; 
import javax.servlet.http.*; 
import java.io.*; 
import java.util.*; 
import java.sql.*; 
public class getphoto extends httpservlet { 
private static final string content_type = "image/jpeg"; 
/**initialize global variables*/ 
public void init() throws servletexception { 

/**process the http get request*/ 
public void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { 
//在数据库中照片的id 
string photoid = null; 
try { 
photoid = request.getparameter("photoid"); 

catch(exception e) { 
e.printstacktrace(); 

//连接数据库,自定义的数据库连接池管理类 
dbconnectionmanager connmgr; 
connmgr = dbconnectionmanager.getinstance(); 
connection conn = connmgr.getconnection("comdb"); //属性文件中定义 
//用来存储照片数据的缓冲区 
byte [] buf=null; 
//扩展名可以从数据库得到,这里直接指定为jpeg 
string photoname="jpeg"; 
try{ 
//根据id查找照片 
string searchsql="select photo from employee where id ="+photoid; 
statement stmt = conn.createstatement(); 
resultset rs_photo = stmt.executequery(searchsql); 
//将图片数据读入缓冲区 
if (rs_photo.next()){ 
buf = rs_photo.getbytes(1); 
}else 

buf = new byte[0]; 

}catch (exception e){ 
//throw e; 

finally { 
connmgr.freeconnection("comdb", conn); 

//response.setcontenttype(content_type); 
//告诉浏览器输出的是图片 
response.setcontenttype("image/"+photoname); 
//图片输出的输出流 
outputstream out = response.getoutputstream(); 
//将缓冲区的输入输出到页面 
out.write(buf); 
//输入完毕,清楚缓冲 
out.flush(); 

/**clean up resources*/ 
public void destroy() { 


编译后的servlet getphoto.class也会自动放置在工程文件的web-inf下的classes目录下。 
2.3 jsp实现数据库图文信息浏览 
成功建立好servlet后,下一步要做的工作就是将原先的html标记: 
<img src="../image/"+rs_photo.getstring(photo_fiield) width="100" height="80">加以修改,替换为servlet标记。即可以将下面的标记写于html或jsp中页面中  
<img border="0" src="/servlet/getphoto?photoid=xxx&ts=aaaaa" >  
其中xxx是图片的id,aaaaa是时间戳,用来防止图片不刷新。如果我们要浏览数据库中的所有图文信息,可以加入适当的循环控制。在本文的示例web应用程序中作者加入了简单的表格控制来修饰输出的图文信息。详细的程序代码如下所示: 
***************jsp页面浏览数据库图文信息代码************* 
<%@ page contenttype="text/html; charset=gb2312" language="java" import="java.sql.*" errorpage="" %> 
<jsp:usebean id="comdbbean" scope="page" class="dbbean.conn"/> 
//使用javabean建立页面的数据连接 
<html> 
<head> 
<title>untitled document</title> 
<meta http-equiv="content-type" content="text/html; charset=gb2312"> 
</head> 
<body> 
<% 
int table_num=4; //指定表格每行显示记录的条数 
resultset rs_photo;  
strsql="select * from employee";  
rs_photo =comdbbean.executequery(strsql);  
out.println("<table width=75% border=1align=center>"); 
out.println("<tr>"); 
while(rs_photo.next()) 

string pic01=rs.getstring("id_stud"); 
pic01=""+pic01+""; 
string employeename=rs.getstring("name"); 
//加入表格控制 
out.println("<td>"); 
out.println("<div align=\"center\">"); 
out.println("<p>"); 
out.println("<a 
href=\"inf_ employee_details.jsp?inf_employee_id=pic01\">"); 
out.println("<img 
border=\"0\"src=\"../servlet/getphoto?photoid="+pic01+"&ts=aaaaa\" width=\"100\" height=\"120\" align=\"absmiddle\">"); 
out.println("</a>"); 
out.println("</p>"); 
out.println("<p>"); 
out.println("<a 
href=\"inf_ employee _details.jsp?inf_employee_id=pic01\">"); 
out.println(employeename); 
out.println("</a>"); 
out.println("</p>"); 
out.println("</div>"); 
out.println("</td>" ); 
table_num++; 
if((table_num%4)==0)  
//如果可以被4整除,则进入下一栏,否则继续输出 

out.println("</tr>"); 
out.println("<tr>"); 


out.println(" </table>"); 
}  
rs_photo.close(); //关闭数据集rs_subject 
%> 
</body> 
</html> 
在上例的程序代码示例中,用javabean建立本jsp页面的数据库连接,用servlet进行读取二进制image数据。后面附加了表格修饰输出图文的部分代码。程序运行结果如下图1-6所示。 


图2 jsp页面浏览数据库图文信息结果

以上web应用程序在windows 2000 server+jbuilder 7+sql server 2000+ apache tomcat 4.0环境下调试通过。 

你可能感兴趣的:(用JSP+Servlet实现二进制图像的动态显示-JSP教程,Java技巧及代码)