山高岳小,水落石出

blog重建工作基本完成

导航

Blog统计

公告

1.关注java,关注web开发,关注互联网,关注企业信息化

2.关注实时绘制技术,关注光照技术,关注阴影技术

3.关注投资理财,关注企业管理,关注创业项目









文章

收藏

相册

my blog

存档


正在读取评论……

我用oracle的BLOB存储附件文件,并保存了附件名称。我用一个servlet和一个jsp联合起来来处理附件文件的下载,servlet负责将附件文件从数据库中去出来存储到本地文件系统,jsp负责将文件从本地文件系统下载到浏览器。
期间我尝试了网上能够找到的多种方法,问题主要集中在下载那里.下面我列举一下我所遇到的下载问题:
  1. 能够下载执行下载以后的第一个附件下载,后边无法正确下载,只能下载到空文件或者只有一行文本。
  2. 能够正确下载,但是在文件首行添加了额外的一行。
  3. 只能下载到空文件。
我采用的方法:
  1. 采用从response中获得流直接输出。
ServletOutputStream sos = response.getOutputStream();
InputStream pi = resultset.getBinaryStream("DATABLOB");//字段名datablob
byte[] blobbytes = new byte[0x100000]; //照片大小
int bytesRead = 0;         
while ((bytesRead = pi.read(blobbytes)) != -1)    {
          sos.write(blobbytes, 0, bytesRead);
          //System.out.println(""+ (bytecount++));
}        
pi.close(); 
sos.flush();
  1. 采用本地文件流
response.setContentType("application/octet-stream; charset=iso-8859-1");
response.setHeader("Content-disposition", "attachment; filename=\"" + dst_fname + "\"");
FileInputStream fis = null;
 int byteRead;
 out.clear();
 try{
    fis=new FileInputStream(filepath);
    while ((byteRead = fis.read()) != -1) {
    out.write(byteRead);
}
out.flush();
  1. 采用网络URL流
String src_fname = "http://www.javaworld.com.tw/jute/images_zh_TW/bluetitle.gif"; 
  String dst_fname = URLEncoder.encode("bluetitle.gif", "Big5");
  
  response.setContentType("application/octet-stream; charset=iso-8859-1");
  response.setHeader("Content-disposition", "attachment; filename=\"" + dst_fname + "\"");
  
  URL url = new URL(src_fname);
  InputStream is = url.openStream();
  
  DataInputStream fis = null;
  int byteRead;
  
  try{
    fis = new DataInputStream(is);
    while ((byteRead = fis.read()) != -1) {
      out.write(byteRead);
    }
    out.flush();
  }catch(Exception e){
    out.clearBuffer();
    response.setContentType("text/html; charset=big5");
    response.setHeader("Content-disposition", "inline");
    out.println("<HTML><BODY><P>");
    out.println(e.toString());
    out.println("</P></BODY></HTML>");
  }
  if(fis != null){
     fis.close();
  }
  return; // 避免下面多按了 Enter 鍵而輸出多餘的換行字元.
我的具体代码如下:
import org.apache.log4j.Logger;

import java.io.*;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * 把指定完整路径的文件存到tzfb的fj字段,时间关系没有设计成可重用类,只能为该表服务
 * 
 * @author yyh 16:31:26
 *
 * FileImport
 */
public class FileImport {
    /**
     * Logger for this class
     */
    private static final Logger logger = Logger.getLogger(FileImport.class);
   
    private Connection conn;
    private Statement querryStm;
    private Statement updateStm;
   
    private String theLocalFile;
    private String tzid=null;
    private String dwdm=null;
 
    public FileImport() throws SQLException
    {     
        getConnection();
    }
   
    private int getConnection(){
        //获取数据库连接
        IDBOperate idbo=new IDBOperate();
        DBOperate dbo=idbo.getDBOperate();
        this.conn = dbo.getConnection();
        try{
            this.conn.setAutoCommit(false);
        }catch(Exception e){
            logger.warn(dwdm+"-无法连接数据库服务器,附件文件导入失败!");
            e.printStackTrace();
        }
        if(conn==null){
            return -1;
        }
        return 0;
    }
    /**
     * 把指定完整路径的文件存到tzfb的fj字段,时间关系没有设计成可重用类,只能为该表服务
     *
     * Method 'importFile'
     * @param theLocalFolder
     * @param tzid
     * @param dwdm
     * @return
     *             0:正常导入
     *             -1:附件文件导入数据库异常
     *             -2:附件文件导入数据库时IO异常
     *             -3:给定id的通知并不存在
     *             -4:给定附件文件路径不是一个文件
     *             -5:无法获得数据库连接
     *             -6:文件导入时无法建立Statement
     */
    public int importFile(String theLocalFile,String tzid,String dwdm){
        //init
        this.theLocalFile = theLocalFile;
        this.tzid=tzid;
        this.dwdm=dwdm;
       
        if(null==conn){
            if(0!=getConnection())
                return -5;
        }
        int result=0;
        try{
            this.querryStm = this.conn.createStatement();
            this.updateStm = this.conn.createStatement();
        }catch(Exception e){
            logger.warn(dwdm+"-文件导入时无法建立Statement,附件文件导入失败");
            e.printStackTrace();
            return -6;
        }
       
        result=doImport( this.theLocalFile);
       
        if (this.conn != null){
            try{
                this.querryStm.close();
                this.updateStm.close();
                this.conn.close();
            }catch(Exception e){
                System.out.println("数据库连接释放失败");
                e.printStackTrace();
            }
        }
       
        return result;//正常导入
    }
   
    /**
     * 根据文件路径将文件导入到前边指定tzid的通知数据FJ中
     *
     * Method 'goThroughFileTree'
     * @param FolderName
     * @return
     *             0:正常导入
     *             -1:附件文件导入数据库异常
     *             -2:附件文件导入数据库时IO异常
     *             -3:给定id的通知并不存在
     *             -4:给定附件文件路径不是一个文件
     */
    private int doImport(String FolderName)//遍历整个文件树
    {       
        int result=0;
        File currentFile = new File(FolderName);
        if(currentFile.isFile())
        {
            try
            {
                result=doImport(currentFile);
            }
            catch (SQLException e)
            {
                logger.warn(dwdm+"附件文件导入数据库异常,附件文件导入失败");
                e.printStackTrace();
                return -1;
            }
            catch (IOException e)
            {
                logger.warn(dwdm+"-附件文件导入数据库时IO异常,附件文件导入失败");
                e.printStackTrace();
                return -2;
            }  
        }else{
            logger.warn(dwdm+"-给定附件文件路径不是一个文件,附件文件导入失败");
            return -4;
        }
        if(-1==result){
            return -3;
        }
        //如果上述错误都没有发生就返回正确值0
        return 0;
    }
    /**
     * 将附件文件装载进数据库文件
     *
     * Method 'doImport'
     * @param file
     * @return
     *          0:文件正常导入数据库
     *          -1:给定id的通知并不存在
     * @throws SQLException
     * @throws IOException
     */

    private int doImport(File file) throws SQLException, IOException
    {
        String queryString;
        System.out.println("路径---"+file.getPath() + " 文件名---"+file.getName());

        FileInputStream fileIn = new  FileInputStream(file);
       
        queryString ="SELECT DLID FROM tzFB WHERE id ="+tzid;
        System.out.println(queryString);
        ResultSet theRS = this.querryStm.executeQuery(queryString);
       
        if(theRS.next())//假设该id的通知一定存在
        {
            queryString ="SELECT FJ FROM TZFB WHERE id ="+tzid+" FOR UPDATE";
            theRS = this.querryStm.executeQuery(queryString);
            System.out.println(queryString);
        
            if(theRS.next())
            {
                oracle.sql.BLOB blob = (oracle.sql.BLOB)theRS.getBlob("FJ");
               
                BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());
                BufferedInputStream in = new BufferedInputStream(fileIn);
                int c;
                while ((c=in.read())!=-1)
                {
                    out.write(c);
                }                       
                in.close();
                out.close();
                this.conn.commit();
            }
            return 0;
        }
        else{//如果没有这个id的通知,那么则报告错误
            logger.warn(dwdm+"-通知id错误,数据库中没有该id的通知,附件文件导入失败");
            return -1;
        }
    }  
   
    public static void  main(String arg[])
    {
        try
        {
            FileImport thePI = new FileImport();
            thePI.importFile("C:\\tomcat5.5.8\\webapps\\gsmis\\main_images\\button\\000000000.JPG","12","1101'");
        }
        catch (SQLException e)
        {
            System.out.print("导入文件发生错误");
            e.printStackTrace();
        }
    }
   

}

public class ExportAttachmentFile extends LEV1Servlet {

    /**
     * Logger for this class
     */
    private static final Logger logger = Logger.getLogger(ExportAttachmentFile.class);

    private String id=null;
    /**
     * 1.查找当前用户是否是指定id的通知接受者或者发出者,如果不是返回到错误页面
     * 2.下载附件文件
     */
    public void service(HttpServletRequest req, HttpServletResponse res)
        throws ServletException, IOException {
       
        String cxp=req.getContextPath();
       
        HttpSession session=req.getSession(true);
        String dwdm=(String)session.getAttribute("userID");
       
        String fileSeparator = System.getProperty("file.separator");
        ServletContext context=session.getServletContext();
        String dbpath=context.getInitParameter("systemPath");
        String userPath=dbpath+fileSeparator+dwdm;   //like '/opt/tomcat/webapps/wb/db/1101'
       
//        String host = "http://" + req.getServerName() + ":" + req.getServerPort() + "/" + req.getContextPath();
        String host = "http://" + req.getServerName() + ":" + req.getServerPort()  + req.getContextPath();
        String download_url = host+"/db/"+dwdm+"/";
       
        //验证dwdm
        if(null==dwdm){
            logger.warn("xxxxx-未登录时试图下载下载通知附件文件,ip:"+req.getRemoteAddr());   
           
            req.setAttribute("message", "无权下载通知附件文件,请登录系统!");
            forward(req, res, "/pub/failure.jsp");
            return;
        }
        //验证tzid
        id=req.getParameter("tzid");
        if(null==id){
            logger.warn(dwdm+"-下载在附件时未指定通知id!");   
            req.setAttribute("nextPage", cxp+"/index.jsp");
            req.setAttribute("message", "下载错误,请重试或联系客服人员!");
            forward(req, res, "/pub/failure.jsp");
            return;
        }
        //验证用户是否可以下载
        String sql_tzfb="select dlid from tzfb where id="+id;
        String sql_tzfbdx="select count(*) from tzfbdx where tzid="+id+" and dwid='"+dwdm+"'";
        IDBOperate idbo=new IDBOperate();
        DBOperate dbo=idbo.getDBOperate();
        int count=dbo.queryTotalRowCount(sql_tzfbdx);
        if(0==count){//如果不是通知的接受对象
            ResultSet rs=null;
            try{
                rs=dbo.getResultSet(sql_tzfb);
                if(rs.next()){//如果存在该id的通知
                    String dlid=rs.getString("dlid");
                    if(!dlid.equals(dwdm)){//如果还不是通知的发布对象
                        logger.warn(dwdm+"-无权下载该通知附件!tzid="+id);   
                        req.setAttribute("nextPage", cxp+"/form/index.jsp");
                        req.setAttribute("message", "无权下载该通知附件,下载错误,请重试或联系客服人员!");
                        forward(req, res, "/pub/failure.jsp");
                        return;
                    }
                }else{//如果不存在该id的通知
                    logger.warn(dwdm+"-不存在id="+id+"的通知!");   
                    req.setAttribute("nextPage", cxp+"/form/index.jsp");
                    req.setAttribute("message", "不存在的通知,下载错误,请重试或联系客服人员!");
                    forward(req, res, "/pub/failure.jsp");
                    return;
                }
            }catch(Exception e){
                logger.warn(dwdm+"-验证用户下载通知附件权限时候数据库异常,下载失败!");
                e.printStackTrace();
                return;
            }
        }
        //通过验证
        String QerrySting="select * from tzfb where id="+id;
        try{
            Connection conn = dbo.getConnection();
            Statement stat = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
            ResultSet rs = stat.executeQuery(QerrySting);
            if(rs.next()){
                String filename=rs.getString("FJWJMC");;
                download_url=download_url+filename;//下载地址
                File file = new File(userPath + fileSeparator + filename);//下载到下载附件的该用户的本地路径上
                OutputStream fout = new FileOutputStream(file);
                //ServletOutputStream sos = res.getOutputStream();
               
                oracle.sql.BLOB blob=(oracle.sql.BLOB)((OracleResultSet)rs).getBLOB("FJ");
                  InputStream pi = rs.getBinaryStream("FJ");//字段名FJ
                  //InputStream pii=blob.getBinaryStream();   
                  int blobsize = (int)blob.length();//?????这里可能将来不用
                  System.out.println("-----------blobsize-----------"+blobsize);
                     
                  byte[] blobbytes = new byte[blobsize]; //照片大小0x100000
                  int bytesRead = 0;          
                     
                  while ((bytesRead = pi.read(blobbytes)) != -1)
                  {
                      //sos.write(blobbytes, 0, bytesRead);
                      fout.write(blobbytes, 0, bytesRead);
                  }
                 
                  pi.close();
                  //sos.flush();
                  fout.flush();
                  conn.close();
                  System.out.println("download_url--"+download_url);

                  session.setAttribute("filename", filename);
                  forward(req,res,"/com/downloadAttachmentFile.jsp");
                  //res.sendRedirect(download_url);
            }
        }catch(Exception e){
            logger.warn(dwdm+"-通知附件下载异常");
            req.setAttribute("nextPage", cxp+"/form/index.jsp");
            req.setAttribute("message", "下载异常,请重试或联系客服人员!");
            forward(req, res, "/pub/failure.jsp");
            return;
        }
    }
}
downloadAttachmentFile.jap:
<%@ page language="java" contentType="text/html; charset=GB2312"  pageEncoding="GB2312"  import="java.util.*, java.io.*, java.net.*"%>
<%
  String filename = (String) session.getAttribute("filename");
  String dst_fname = URLEncoder.encode(filename, "GB2312");
 
  String dwdm=(String)session.getAttribute("userID");
 
  ServletContext context=session.getServletContext();
  String dbpath=context.getInitParameter("systemPath");
  String fileSeparator = System.getProperty("file.separator");
  String filepath=dbpath+fileSeparator+dwdm+fileSeparator+filename;
 
  response.setContentType("application/octet-stream; charset=iso-8859-1");
  response.setHeader("Content-disposition", "attachment; filename=\"" + dst_fname + "\"");
 
  FileInputStream fis = null;
  int byteRead;
  out.clear();
  try{
    fis=new FileInputStream(filepath);
    while ((byteRead = fis.read()) != -1) {
      out.write(byteRead);
    }
    out.flush();
  }catch(Exception e){
    out.clearBuffer();
    response.setContentType("text/html; charset=GB2312");
    response.setHeader("Content-disposition", "inline");
    out.println("<HTML><BODY><P>");
    out.println(e.toString());
    out.println("</P></BODY></HTML>");
  }
  if(fis != null){
     fis.close();
  }
  return; // 避免下面多按了 Enter 键而输出多余的换行字元.
%>


Trackback: http://tb.donews.net/TrackBack.aspx?PostId=553888


[点击此处收藏本文]  发表于2005年09月14日 6:08 PM




正在读取评论……
大名
网址
验证码
评论