技术积累系列(一)------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

猜你喜欢

转载自blog.csdn.net/qq_21786329/article/details/81353718