分享
 
 
 

JSP+Servlet二进制图像的动态显示

王朝java/jsp·作者佚名  2006-12-16
窄屏简体版  字體: |||超大  

数据库应用程序,特别是基于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, N''IsUserTable'') = 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=''1''align=''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环境下调试通过。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有