技術積累系列(一)------Java實現文件的上傳和下載

1.初步學習實現方式

(1)這裏是第一次實驗寫的代碼,將文件的上傳和下載寫成了一個工具類,可以直接調用。

package com.huangjian.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.Logger;

import com.huangjian.common.util.JdbcTools;
import com.mysql.jdbc.PreparedStatement;


/**
 * @desc: APEXSOFT_PROJECT
 * @author: 黃堅
 */
public class FileHandler {
    private static final Logger logger= Logger.getLogger(FileHandler.class);//log大家可以自己配置也可以不配置
    private static final String downPath ="C:/Users/huangjian/Desktop/hj/";//這裏改寫成自己下載的目錄結構
    /**
     *  上傳文件到db方法
    */
    public static String upLoadFile(String id,String path){
        File file=new File(path);
        // 獲取文件名稱
        String fileName = file.getName();
        // 獲取時間
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
        String date = format.format(new Date()); 
        Connection con = null;
        PreparedStatement ps = null;
        try {
            con = JdbcTools.getConnection();
            //獲取輸入流
            FileInputStream inputStream=new FileInputStream(file);
            String sql = "INSERT INTO oa_worddoctable(ID,FFileName,FFileSize,FFileData,FState,FUser,FTime) VALUES(?,?,?,?,'0',?,?)";
            ps = (PreparedStatement) con.prepareStatement(sql);
            ps.setBigDecimal(1, new BigDecimal(id));
            ps.setString(2, fileName);
            ps.setBigDecimal(3, new BigDecimal((int)file.length()));
            ps.setBinaryStream(4, inputStream,(int)file.length());  
            ps.setString(5, "-100");
            ps.setString(6,date);
            ps.executeUpdate();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            logger.error(e);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            logger.error(e);
        }finally {
            JdbcTools.release(con, ps);
        }       
        return null;    
    }
    /**
     *  下載文件方法
    */
    @SuppressWarnings("resource")
    public static String downFile(String id){
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            con = JdbcTools.getConnection();
            // 從數據庫中讀出要還原文件的二進制碼,這裏我讀的是數據庫爲id的文件
            String sqlString = "select * from oa_worddoctable where ID="+id;
            ps = (PreparedStatement) con.prepareStatement(sqlString);       
            rs = ps.executeQuery();
            byte[] Buffer = new byte[4096];
            if (rs.next()) {
                // 下載保存到本地文件
                File file = new File(downPath+new String(rs.getBytes("FFilename")));
                if (!file.exists()) {
                    try {
                        file.createNewFile();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                FileOutputStream outputStream = new FileOutputStream(file);
                // 取字段用getBinaryStream()
                InputStream iStream = rs.getBinaryStream("FFileData");
                int size = 0;
                while ((size = iStream.read(Buffer)) != -1) {
                    System.out.println(size);
                    outputStream.write(Buffer, 0, size);
                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            logger.error(e);
        }finally{
            JdbcTools.release(rs, con, ps);
        }
        return null;    
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("test上傳" );
        FileHandler.upLoadFile("150", "自己的測試目錄");
        System.out.println("test下載");
        FileHandler.downFile("151");
    }
}

這樣就能完成簡單的上傳下載的功能啦,對初步學習很有幫助!

2.深入後實現方式

(1)由於項目使用了structs,所以這裏類的風格是structs。
首先是下載

package com.dz.action;

import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.apex.form.DataAccess;
import com.apex.form.SystemConfig;
import oracle.jdbc.OracleTypes;
import oracle.sql.BLOB;

/**
 * @desc: APEXSOFT_PROJECT
 * @author: 黃堅
 */
public class AppDownloadAction extends DispatchAction {
    private static final Logger LG = Logger.getLogger(AppDownloadAction.class);

    @SuppressWarnings("resource")
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        LG.info("開始下載文件...");
        String id = request.getParameter("id");//
        CallableStatement cstmt = null;
        Connection con = null;
        ResultSet rs = null;
        InputStream in = null;
        OutputStream outp = null;// 不要關閉
        BufferedOutputStream bof = null;
        String filenamedisplay = request.getParameter("fileName");// 下載時默認的文件名
        try {
            con = DataAccess.getDataSource().getConnection();
            String databaseType = SystemConfig.INSTANCE.getDatabaseType();
            if (databaseType.equals("SQLSERVER")) {
                cstmt = con.prepareCall("{call sp_OA_WordDocDownload (?)}");
                cstmt.setString(1, id);// --結果串語句
                rs = cstmt.executeQuery();
                if (rs.next()) {
                    Blob blob = (Blob) rs.getBlob(1);// 備註:oracle 的blob轉換有區別
                    in = blob.getBinaryStream();// ****獲得流****
                }
            } else if (databaseType.equals("ORACLE")) {
                cstmt = con.prepareCall("{call sp_OA_WordDocDownload (?,?)}");
                cstmt.registerOutParameter(1, OracleTypes.BLOB);
                cstmt.setInt(2, Integer.parseInt(id));//
                cstmt.execute();
                BLOB blob = (BLOB) cstmt.getObject(1);
                in = blob.getBinaryStream();// ****獲得流****
            }
            if (databaseType.equals("MYSQL")) {
                cstmt = con.prepareCall("{call sp_OA_WordDocDownload (?)}");
                cstmt.setString(1, id);// --結果串語句
                rs = cstmt.executeQuery();
                if (rs.next()) {
                    Blob blob = (Blob) rs.getBlob(1);// 備註:MYSQL的blob轉換有區別
                    in = blob.getBinaryStream();// ****獲得流****
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (rs != null)
                rs.close();
            if (cstmt != null)
                cstmt.close();
            if (con != null)
                con.close();
        }
        response.reset();// 可以加也可以不加
        response.setContentType("application/x-download;charset=gb2312");// 設置爲下載application/x-download

        if (filenamedisplay == null) {
            filenamedisplay = "附件";
        }
        filenamedisplay = URLEncoder.encode(filenamedisplay, "UTF-8");// 處理中午亂碼
        response.addHeader("Content-Disposition",
                "attachment;filename=" + filenamedisplay);
        try {
            outp = response.getOutputStream();
            bof = new BufferedOutputStream(outp);
            byte[] b = new byte[1024];
            int i = 0;
            while ((i = in.read(b)) > 0) {
                bof.write(b, 0, i);
                bof.flush();
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (in != null) {
                in.close();
            }
        }
    }

}

(2)上傳文件

package com.dz.action;

import java.io.File;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.apex.form.DataAccess;
import com.apex.form.User;
import com.apex.form.UserContext;

/**
 * @desc: APEXSOFT_PROJECT
 * @author: 黃堅
 */
public class AppUploadAction extends DispatchAction {
    private static final Logger LG = Logger.getLogger(AppUploadAction.class);

    @SuppressWarnings({"static-access", "unchecked"})
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        LG.info("開始保存簽名文件...");
        InputStream is = null;
        String fileName = null;
        BigDecimal userId = BigDecimal.valueOf(-1);
        User user = UserContext.getContext().getUser();
        if(user != null){
            int uid = Integer.parseInt(user.getId());
            userId= new BigDecimal(uid);
        }

        Map<String,String> props = new HashMap<String,String>();
        try {
            //使用Apache文件上傳組件處理文件上傳步驟:
            //1、創建一個DiskFileItemFactory工廠
            DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
            //2、創建一個文件上傳解析器
            ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);
            //解決上傳文件名的中文亂碼
            fileUpload.setHeaderEncoding("UTF-8");
            //3、判斷提交上來的數據是否是上傳表單的數據
            if(!fileUpload.isMultipartContent(request)){
                //按照傳統方式獲取數據
                LG.error("文件不是表單數據,保存失敗");
                return null;
            }
            //4、使用ServletFileUpload解析器解析上傳數據,解析結果返回的是一個List<FileItem>集合,每一個FileItem對應一個Form表單的輸入項
            List<FileItem> list = fileUpload.parseRequest(request);
            for (FileItem item : list) {
                //如果fileitem中封裝的是普通輸入項的數據
                if(item.isFormField()){
                    String name = item.getFieldName();
                    //解決普通輸入項的數據的中文亂碼問題
                    String value = item.getString("UTF-8");
                    props.put(name, value);
                }else{
                    //如果fileitem中封裝的是上傳文件,得到上傳的文件名稱,
                    fileName = item.getName();
                    if(fileName==null||fileName.trim().equals("")){
                        LG.error("文件名缺省,上傳失敗");
                        continue;
                    }
                    //處理獲取到的上傳文件的文件名的路徑部分,只保留文件名部分
                    fileName = fileName.substring(fileName.lastIndexOf(File.separator)+1);
                    //獲取item中的上傳文件的輸入流
                    is = item.getInputStream();
                }
            }
            LG.info("fileName:" +fileName +" ,props:" + props.toString());
            saveDocAppToDb(userId+"",props.get("id"),fileName,is);
            LG.info("入庫成功!");
            return null;
        } catch (FileUploadException e) {
            LG.error("發生異常,入庫失敗!");
            e.printStackTrace();
            return null;
        }finally{
            //關閉輸入流
            if(is != null){
                is.close();
            }
        }
    }

    private void saveDocAppToDb(String userId,String docid,String fileName, InputStream inStream)
            throws Exception {
        Connection conn = null;
        String strSql = "";
        PreparedStatement ps = null;
        try {

            if ((docid == null) || (docid.length() == 0)) {
               LG.error("文檔id缺失,不做入庫處理");
               return;
            } 
            Date dTime = new Date();
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String saveTime = df.format(dTime);
            strSql = "update OA_WordDocTable set FFilename=?,FFilesize=?,FFiledata=?,FUser=?,FTime=? where id="
                    + docid;
            conn = DataAccess.getDataSource().getConnection();
            ps = conn.prepareStatement(strSql);
            ps.setString(1, fileName);
            ps.setInt(2, inStream.available());
            ps.setBinaryStream(3, inStream, inStream.available());
            ps.setString(4,userId);
            ps.setString(5,saveTime);
            ps.executeUpdate();
            ps.close();
        } catch (Exception e) {
            LG.error("入庫失敗!");
            e.printStackTrace();
            return;
        } finally {
            if (ps != null) {
                ps.close();
            }
            if (inStream != null) {
                inStream.close();
            }
        }

    }

}

(3)附加一個上傳圖片的小例子

package com.dz.action;

import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.dz.common.util.JdbcUtil;

/**
 * @desc: APEXSOFT_PROJECT
 * @author: 黃堅
 */
public class DownImageAction extends DispatchAction {
    private static final Logger LG = Logger.getLogger(DownImageAction.class);

    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        String id = request.getParameter("id");
        String column = request.getParameter("column");
        String table = request.getParameter("table");
        CallableStatement cstmt = null;
        Connection con = null;
        ResultSet rs = null;
        InputStream in = null;
        DataOutputStream fos = null;
        OutputStream outp = null;// 不要關閉
        try {
            con = JdbcUtil.getDataSource(true).getConnection();
            cstmt = con.prepareCall("select "+column+" from "+table+" where id ="+id);
            rs = cstmt.executeQuery();
            if (rs.next()) {
                Blob blob = (Blob) rs.getBlob(1);// 備註:oracle 的blob轉換有區別
                in = blob.getBinaryStream();// ****獲得流****
            }

        } catch (Exception e) {
            LG.error(e);
            e.printStackTrace();
            return null;
        } finally {
            if (rs != null)
                rs.close();
            if (cstmt != null)
                cstmt.close();
            if (con != null)
                con.close();
        }
        response.reset();// 可以加也可以不加
        response.addHeader("Content-Disposition",
                "inline;filename=123.jpg");
        response.addHeader("Content-Encoding",
                "identity");
        response.setContentType("image/jpeg");

        try {
            outp = response.getOutputStream();
            fos = new DataOutputStream(outp);
            byte[] b = new byte[in.available()];
            int i = 0;
            while ((i = in.read(b)) > 0) {
                fos.write(b, 0, i);
                fos.flush();
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (in != null) {
                in.close();
            }
        }
    }

}

具體代碼可以查看我的git倉庫https://gitee.com/huangziyi/StructsTest.git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章