从数据库中读取并生成图片的Servlet 
(文/邵望)
大体思路 
1)创建ServletOutputStream对象out,用于以字节流的方式输出图像 
2)查询数据库,用getBinaryStream方法返回InputStream对象in 
3)创建byte数组用作缓冲,将in读入buf[],再由out输出 注:下面的例程中数据库连接用了ConnectionPool,以及参数的获得进行了预处理 package net.seasky.music; import javax.servlet.*; 
import javax.servlet.http.*; 
import java.io.*; 
import java.util.*; 
import java.sql.*; 
import net.seasky.util.*; 
import net.seasky.database.DbConnectionManager; public class CoverServlet extends HttpServlet { 
private static final String CONTENT_TYPE = "image/gif"; 
public void init(ServletConfig config) throws ServletException { 
super.init(config); 
} public void doGet(HttpServletRequest request, HttpServletResponse response 
) throws ServletException, IOException { 
response.setContentType(CONTENT_TYPE); 
int albumID; 
ServletOutputStream out = response.getOutputStream(); 
try { 
albumID = ParamManager.getIntParameter(request,"albumID",0); 

catch (Exception e) { 
response.sendRedirect("../ErroePage.jsp"); 
return; 

try { 
InputStream in=this.getCover(albumID); 
int len; 
byte buf[]=new byte[1024]; 
while ((len=in.read(buf,0,1024))!=-1) { 
out.write(buf,0,len); 


catch (IOException ioe) { 
ioe.printStackTrace() ; 

} private InputStream getCover(int albumID) { 
InputStream in=null; 
Connection cn = null; 
PreparedStatement pst = null; 
try { 
cn=DbConnectionManager.getConnection(); 
cn.setCatalog("music"); 
pst=cn.prepareStatement("SELECT img FROM cover where ID =?"); 
pst.setInt(1,albumID); 
ResultSet rs=pst.executeQuery(); 
rs.next() ; 
in=rs.getBinaryStream("img"); 

catch (SQLException sqle) { 
System.err.println("Error in CoverServlet : getCover()-" + sqle); 
sqle.printStackTrace() ; 

finally { 
try { 
pst.close() ; 
cn.close() ; 

catch (Exception e) { 
e.printStackTrace(); 


return in; 
} public void destroy() { 

} 附:
http://www.code-labs.com/project/projectinfo.php?id=44
http://www.yesky.com/20000927/118356.shtml

解决方案 »

  1.   

    谢谢这位朋友的解答,可是做的GUI程序,我想要得到的效果是从oracle数据取出blob数据,显示出来,你的解答方法我不能得到正确的结果啊。苦恼啊,兄台还有别的方法么?
      

  2.   

    xiaofenguser(风雨)强调的是个流的操作,建议楼主区blob使用oracle提供的BLOB来进行操作。BLOB也提供流的操作。
      

  3.   

    我已经试过流操作的了,还是不可以,情况和以前一样,只能读出我自己通过程序写入的gif文件。
    如果我在界面上显示,而是用下面的代码写成文件的话。
      File outFile = new File("C:\\temp\\out.jpg");
      java.io.FileOutputStream fos = new FileOutputStream(outFile);
      fos.write(b);
      fos.close();
    只有用ACDSEE才可以看,就是说,不象正常图片那样,鼠标点一下就可以在旁边看到预览/
    我真的是一点办法也没有了。:(
      

  4.   

    应该是不能显示的啊,你写入的是GIF,但是写到的确实JPG文件,格式不一样的。你用uedit打开你写的JPG文件,看看是不是FF D8开头,FF D9结尾!另外GUI程序没怎么写过,不过我觉得xiaofenguser(风雨)强调的是个流的操作应该可以的!
      

  5.   

    对不起,是我没说清楚。
    我的目的是想读出JPG图象,而数据库里存的有JPG图象也有GIF图象(都是oracle数据库的blob类型),我可以把他们都读出来,不论是用blob还是以流的方式,最终都把数据放到一个byte[]里。然后用转成ImageIcon,在加到lable里。
    现在的问题是,读非常小的GIF就可以显示出来,而JPG不行。这就是我一直困惑的问题。不知道我现在有没有说明白。
      

  6.   

    只要能保证blob的数据正确,那生成的文件扩展名不会有影响的.
    ImageIcon是支持gif和jpeg的。>>>>>>>>
    现在的问题是,读非常小的GIF就可以显示出来,而JPG不行。
    那么大一些的gif能正常显示吗?JLabel lblTest = new JLabel("test");
    Image img = Toolkit.getDefaultToolkit().getImage("d:/top.jpg");
    ImageIcon icon = new ImageIcon(img);
    lblTest.setIcon(icon);
    我试了一下,不管是jpg,还是gif都没有问题,也和文件大小无关你试一试用RandomAccessFile来生成jpg文件
    也许问题是出在
    byte[] b = blob.getBytes(1,(int)(blob.length()));
    这里,b的数据不完全正确
      

  7.   

    你把写到文件后的那个文件(out.jpg)与你写进去的文件比较一下,看看大小、内容是否一样。如果不一样,说明写入程序可能有问题。如果你愿意,可以试着将你的读和写的源程序发给我,我也许能帮你查查。
    我的电子邮件是里[email protected]
      

  8.   

    多谢各位朋友的捧场,问题已经解决了。
    还有一点儿关于blob的小问题,再发新帖子吧,该给大家散分了。
    如果觉得分数不够的话,可以跟我说,我还会给。