图片存储到 sql server (java实现)并用jsp展示

halinlida 贡献于2014-08-12

作者 Jackie lieu  创建于2012-12-05 15:33:00   修改者Jackie lieu  修改于2012-12-05 15:34:00字数7851

文档摘要:第一种情况:java读取写入图片。本想找点代码测试一下在SQLServer中存取图片的方法, 结果狂搜之后才发现,不是基于在jsp中的应用,就是本身过程太复杂,今天,突然看到一篇java实现数据库图片存储的文章,学java好象也有一年了,学jdbc也很长时间了,可是这方面还没写过呢。就参考了网上的几篇文章,写了一个下午。终于写好了。现在把代码贴出来。
关键词:

第一种情况:java读取写入图片。 本想找点代码测试一下在SQL Server中存取图片的方法, 结果狂搜之后才发现,不是基于在jsp中的应用,就是本身过程太复杂,今天,突然看到一篇java实现数据库图片存储的文章,学java好象也有一年了,学jdbc也很长时间了,可是这方面还没写过呢。就参考了网上的几篇文章,写了一个下午。终于写好了。现在把代码贴出来。以供大家参考。 代码绝对可以运行,在我的机器是运行的结果完全正确。 我的机器是jdk1.5+winxp+eclipse package cn; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class PhotoDemo {      /**      * @param args      */     Connection conn=null;     public PhotoDemo() {         try {             String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=master";             Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");             conn= DriverManager.getConnection(url,"sa","xiaoxin");              }         catch(SQLException e) {             e.printStackTrace();         }         catch(ClassNotFoundException ce) {             ce.printStackTrace();         }     }     public void Insert() {         try {             String sql="insert into picture values(?,?)";             PreparedStatement ps=conn.prepareStatement(sql);             File f =new File("E:/PHOTO/baby/1.jpg");                                      FileInputStream input= new FileInputStream(f);             ps.setString(1,"cute");             ps.setBinaryStream(2, input,(int)f.length());             ps.executeUpdate();             ps.close();             input.close();         }         catch(SQLException e) {             e.printStackTrace();         }         catch(IOException ie) {             ie.printStackTrace();         }     }         public void Read() {         try {             String sql="select picture from picture where name=?";             PreparedStatement ps=conn.prepareStatement(sql);             ps.setString(1, "cute");             ResultSet rs=ps.executeQuery();             byte [] b=new byte[10240*8];                         while(rs.next()) {                 InputStream in=rs.getBinaryStream("picture");                 in.read(b);                 File f=new File("D:/3.jpg");                 FileOutputStream out=new FileOutputStream(f);                 out.write(b, 0, b.length);                 out.close();             }                     }         catch(SQLException e) {             e.printStackTrace();         }         catch(IOException ie) {             ie.printStackTrace();         }     }         public static void main(String[] args) {         // TODO Auto-generated method stub         PhotoDemo p=new PhotoDemo();         p.Insert();         p.Read();     } }  其实,很简单的。就是用jdbc取出来,然后用文件输入,输出流来进行操作。 第二中情况:java读取并显示到jsp页面,或者弹出另存为对话框。 使用HTTP Response Header 的 Content-Disposition。 因为听到有同事讨论JSP输出Excel文件的,就是在页面上有一个【导出】按钮,能够将查询结果导出到Excel文件让用户下载。有人说要用POI在后 台生成临时的Excel文件,然后通过读取FileStream写入到OutputStream来解决。其实这个功能不需要这么重型的武器的,虽然很多人 讨厌MS,但是不得不承认MS绝对不是乱盖的,IE和Office产品的几近完美的结合就是一个列子。页面里面的Table很容易就可以导出到Excel 文件,而且格式都能够完好的保存,所以如果要将查询结果导出到Excel,只需将页面的Context-Type修改一下就可以了: <%@ page language="java" contentType="application/vnd.ms-excel"%> 然后请求这个页面的时候,就会出现这样的IE窗口: 看到上面的菜单了么?除了IE的,还有Excel的。而且在点击“文件”->“另存为”的时候,如果选择“Excel工作簿”,那么保存的文件就是真正的转换到Excel文件的存储格式了。 不过,有一个问题是,如果我不希望直接在IE里面打开Excel文件,我希望能够提供那个打开/保存的对话框,应该如何做? 模模糊糊记得很久很久以前用过一个参数,于是乎,google一下吧,找到了,就是这 个Content-Disposition参数,HTTP Response Header的一个参数。但是这个不是标准参数,查看一下HTTP/1.1的规范文档,对于这个参数的解释大意如下: Content-Disposition参数本来是为了在客户端另存文件时提供一个建议的文件名,但是考虑到安全的原因,就从规范中去掉了这个参数。但是由于很多浏览器已经能够支持这个参数,所以只是在规范文档中列出,但是要注意这个不是HTTP/1.1的标准参数。 于是,在页面加入一行代码: <% response.addHeader("Content-Disposition", "attachment;filename=test.xls"); %> 能够看到“文件下载”的对话框了: 测试了一下,其实IE是根据Content-Disposition中filename这个段中文件名的后缀来识别这个文件类型的,所以,如果有很多种文件类型的时候,可以将Content-Type设置为二进制模式的: <%@ page language="java" contentType="application/octet-stream"%> 附Content-Disposition的解释: 19.5.1 Content-Disposition The Content-Disposition response-header field has been proposed as a means for the origin server to suggest a default filename if the user requests that the content is saved to a file. This usage is derived from the definition of Content-Disposition in RFC 1806 [35]. content-disposition = "Content-Disposition" ":" disposition-type *( ";" disposition-parm ) disposition-type = "attachment" | disp-extension-token disposition-parm = filename-parm | disp-extension-parm filename-parm = "filename" "=" quoted-string disp-extension-token = token disp-extension-parm = token "=" ( token | quoted-string ) An example is     Content-Disposition: attachment; filename="fname.ext" The receiving user agent SHOULD NOT respect any directory path information present in the filename-parm parameter, which is the only parameter believed to apply to HTTP implementations at this time. The filename SHOULD be treated as a terminal component only. If this header is used in a response with the application/octet- stream content-type, the implied suggestion is that the user agent should not display the response, but directly enter a `save response as...' dialog. Content-Disposition中文乱码 Response.setHeader(”Content-Disposition”, “attachment; filename=” + fileName+”.xls”); 如果file.Name为中文则乱码。解决办法是 方法1: response.setHeader(”Content-Disposition”, “attachment; filename=” + java.net.URLEncoder.encode(fileName, “UTF-8″)); 下载的程序里有了上面一句,一般在IE6的下载提示框上将正确显示文件的名字,无论是简体中文,还是日文。但是文字只要超过17个字,就不能下载了。 一. 通过原来的方式,也就是先用URLEncoder编码,当中文文字超过17个时,IE6 无法下载文件。这是IE的bug,参见微软的知识库文章 KB816868 。原因可能是IE在处理 Response Header 的时候,对header的长度限制在150字节左右。而一个汉字编码成UTF-8是9个字节,那么17个字便是153个字节,所以会报错。而且不跟后缀也 不对. 方法2: response.setHeader( “Content-Disposition”, “attachment;filename=” + new String( fileName.getBytes(”gb2312″), “ISO8859-1″ ) ); 在确保附件文件名都是简体中文字的情况下,那么这个办法确实是最有效的,不用让客户逐个的升级IE。如果台湾同胞用,把gb2312改成big5就行。但 现在的系统通常都加入了国际化的支持,普遍使用UTF-8。如果文件名中又有简体中文字,又有繁体中文,还有日文。那么乱码便产生了。另外,在上 Firefox (v1.0-en)下载也是乱码。 本文我们来说一下MIME 协议的一个扩展Content-disposition。     我们在开发web系统时有时会有以下需求: · 希望某类或者某已知MIME 类型的文件(比如:*.gif;*.txt;*.htm)能够在访问时弹出“文件下载”对话框 · 希望以原始文件名(上传时的文件名,例如:山东省政府1024号文件.doc)提供下载,但服务器上保存的地址却是其他文件名(如:12519810948091234_asdf.doc) · 希望某文件直接在浏览器上显示而不是弹出文件下载对话框 · ……………………     要解决上述需求就可以使用Content-disposition来解决。第一个需求的解决办法是 Response.AddHeader "content-disposition","attachment; filename=fname.ext" 将上述需求进行归我给出如下例子代码: public static void ToDownload(string serverfilpath,string filename) { FileStream fileStream = new FileStream(serverfilpath, FileMode.Open); long fileSize = fileStream.Length; HttpContext.Current.Response.ContentType = "application/octet-stream"; HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + UTF_FileName(filename) + "\";"); ////attachment --- 作为附件下载 ////inline --- 在线打开 HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString()); byte[] fileBuffer = new byte[fileSize]; fileStream.Read(fileBuffer, 0, (int)fileSize); HttpContext.Current.Response.BinaryWrite(fileBuffer); fileStream.Close(); HttpContext.Current.Response.End(); } public static void ToOpen(string serverfilpath, string filename) { FileStream fileStream = new FileStream(serverfilpath, FileMode.Open); long fileSize = fileStream.Length; HttpContext.Current.Response.ContentType = "application/octet-stream"; HttpContext.Current.Response.AddHeader("Content-Disposition", "inline; filename=\"" + UTF_FileName(filename) + "\";"); HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString()); byte[] fileBuffer = new byte[fileSize]; fileStream.Read(fileBuffer, 0, (int)fileSize); HttpContext.Current.Response.BinaryWrite(fileBuffer); fileStream.Close(); HttpContext.Current.Response.End(); } private static string UTF_FileName(string filename) { return HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8); } 简单的对上述代码做一下解析,ToDownload方法为将一个服务器上的文件(serverfilpath为服务器上的物理地址),以某文件名 (filename)在浏览器上弹出“文件下载”对话框,而ToOpen是将服务器上的某文件以某文件名在浏览器中显示/打开的。注意其中我使用了 UTF_FileName方法,该方法很简单,主要为了解决包含非英文/数字名称的问题,比如说文件名为“衣明志.doc”,使用该方法客户端就不会出现 乱码了。 需要注意以下几个问题: 1. Content-disposition是MIME协议的扩展,由于多方面的安全性考虑没有被标准化,所以可能某些浏览器不支持,比如说IE4.01 2. 我们可以使用程序来使用它,也可以在web服务器(比如IIS)上使用它,只需要在http header上做相应的设置即可 附上一段java读sqlserver的image类型的数据并显示到jsp: [java] view plaincopy 1. @Action("showImage")   2.    public String showImage(){   3.     HttpServletResponse res = ServletActionContext.getResponse();   4.     //res.addHeader("Content-Disposition", "attachment;filename=test.doc");   5.     Long attachmentId = Long.valueOf(ServletActionContext.getRequest().getParameter("attachmentId"));   6.     OutputStream out = null;   7.     try {   8.         Attachment attachment = deviceServ.findAttachmentById(attachmentId);   9.         if(null!=attachment && null!=attachment.getFile()){   10.             out = res.getOutputStream();   11.             byte[] b = new byte[1024];   12.                13.             ByteArrayInputStream inputStream = new ByteArrayInputStream(attachment.getFile());   14.                15.             int n = 0;   16.             while((n=inputStream.read(b)) != -1){   17.                 out.write(b, 0, n);   18.             }   19.             out.flush();   20.                21.             inputStream.close();   22.         }   23.     } catch (HoncombException e) {   24.         e.printStackTrace();   25.     } catch (IOException e) {   26.         e.printStackTrace();   27.     }finally{   28.         if(out!=null){   29.             try {   30.                 out.close();   31.             } catch (IOException e) {   32.                 e.printStackTrace();   33.             }   34.         }   35.     }   36.     return null;   37.    } 

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 3 金币 [ 分享文档获得金币 ] 0 人已下载

下载文档