• (十)文件上传与下载


    •   文件上传的几种方式:

    1.   上传到服务器的文件夹中。(不重要的文件),一般在数据库中只存文件的路径和文件名。
    2.    上传到数据库的字段中。(重要的文件),在字段中以二进制的形式存储。

    一、上传到服务器的文件夹中。

    • 前提:

    • index.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
        <%@ taglib prefix="s"  uri="/struts-tags"  %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <% String path=request.getContextPath(); %>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
            <h2>上传到文件夹</h2>
    <form action="uploadAction/upload!upload_toFolder" enctype="multipart/form-data" method="post">
        <table border="1" width="50%" height="50%">
        
        <tr>
            <td>ID:</td>
            <td><s:textfield name="id"></s:textfield></td>
        </tr>    
        <tr>    
            <td>文件:</td>
            <td><s:file name="file" ></s:file></td>
        </tr>    
        <tr>
            <td><s:submit value="提交"></s:submit></td>
        </tr>    
        
    </table>
    </form>
    
            <h2>上传到服务器</h2>
    <form action="uploadAction/upload!upload_to_table" enctype="multipart/form-data" method="post">
        <table border="1" width="50%" height="50%">
        
        <tr>
            <td>ID:</td>
            <td><s:textfield name="id"></s:textfield></td>
        </tr>    
        <tr>    
            <td>文件:</td>
            <td><s:file name="file" ></s:file></td>
        </tr>    
        <tr>
            <td><s:submit value="提交"></s:submit></td>
        </tr>    
        
    </table>
    </form>
    </body>
    </html>
    • struts.xml
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
    
    <struts>
    
          <constant name="struts.i18n.encoding" value="UTF-8"></constant>
        <constant name="struts.multipart.maxSize" value="209715200"></constant>
        <constant name="struts.action.extension" value="action,,"></constant>
        <constant name="struts.enable.DynamicMethodInvocation" value="true" />
        <constant name="struts.devMode" value="true" />
        <constant name="struts.i18n.reload" value="true"></constant>
        <constant name="struts.ui.theme" value="simple" />
        <constant name="struts.configuration.xml.reload" value="true"></constant>
        <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
        <constant name="struts.handle.exception" value="true"></constant>
    
        <package name="default" namespace="/uploadAction" extends="struts-default">
            <action name="upload" class="action.FileUpload">
                <result name="list">/list.jsp</result>
            </action>
        </package>
     
         <package name="download" namespace="/download" extends="struts-default" >
             <action name="downloadAction" class="action.DownLoadAction">
                     <result name="down_for_struts" type="stream">
                         <param name="bufferSize">10240</param>
                        <param name="contentType">
                            application/octet-stream
                        </param>
                        <param name="contentDisposition">
                            attachment;filename=${encode_filename}   <!-- ${} OGNL表达式,只用于xml文件中获取广义值栈的值 -->
                        </param>
                        <param name="contentCharSet">ISO-8859-1</param>
                        <param name="inputName">fileInput</param>
                     </result>
             </action>
         
         </package>
     
    </struts>
    • FileUpload 。java
    package action;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.InputStream;
    import java.sql.Connection;
    
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.ResultSetHandler;
    import org.apache.commons.dbutils.handlers.MapHandler;
    import org.apache.commons.dbutils.handlers.MapListHandler;
    import org.apache.commons.io.FileUtils;
    
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.util.ValueStack;
    
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.util.List;
    import java.util.Map;
    
    import DBUtils.DButil;
    import Global.Global;
    import actionUtil.BaseAction;
    
    public class FileUpload extends BaseAction {
    
        private static final long serialVersionUID = 1L;
        /* ============================================== */
        private int id; // 用于接收表单中的id
        private File file; // 用于接收表单的文件
        private String fileFileName; // 控件名称+FileName 用于获取上传文件的名。
        private String fileContentType; // 控件名称+ContentType 用于获取文件的类型,比如txt、word等
        
        private String fileName="";
        private String filePath="";
    
        public String getFileContentType() {
            return fileContentType;
        }
        public void setFileContentType(String fileContentType) {
            this.fileContentType = fileContentType;
        }
        public String getFileFileName() {
            return fileFileName;
        }
        public void setFileFileName(String fileFileName) {
            this.fileFileName = fileFileName;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public File getFile() {
            return file;
        }
        public void setFile(File file) {
            this.file = file;
        }
    
        /* ============================================== */
        @Override
        public String execute() {
    
            return "success";
        }
    
        /**
         * 文件上传到服务器中的文件夹里。
         * 1. 当用户成功上传文件或者上传失败的时候会有javaScript的alert提示,那么这个方法的返回值只能是null,否则脚本将无法运行。
         * @return
         */
        public String upload_toFolder() {
                
            if(fileFileName!=null && !fileFileName.equals("")){
                //如果文件名不为null或者不为空,说明用户有上传文件,需要处理文件上传
                fileName=this.getFileFileName();
                boolean isuploaderror=true;
                String errorMsg="";  //错误消息
                try {
                    String uploadpath=this.context.getRealPath("/upload"); //获取存放用户文件的文件夹路径
                    File destFile=new File(uploadpath+"/"+this.fileFileName); //存放到文件夹里的用户上传文件
                    FileUtils.copyFile(file, destFile); //FileUtils文件工具类的copyFile可以一个文件的拷贝到另一个文件。
                    filePath=fileName;
                
                    isuploaderror=false;
                } catch (Exception e) {
                    e.printStackTrace();
                    errorMsg=e.getMessage();
                } 
                
                if(isuploaderror == true){
                    //说明上传错误,数据库不能记录
                    Global.WebErrorMsg(response, errorMsg);
                    
                }else{
                    //上传正确,记录到数据库
                    String sql="insert into file(id,filename,filepath) values('"+this.id+"','"+this.fileFileName+"','"+filePath+"')";
                boolean flag=false;
                
                try {
                    flag = DButil.uptData(sql);
                } catch (Exception e) {
                    errorMsg=e.getMessage();  //如果上传错误,就把错误消息赋给errorMsg,前提是try里面的uptData方法定义里把异常抛出且uptData方法里的catch块里有把throw e即把异常对象抛出,否则这里的e.getMessage()就没有异常消息内容。                    
                    e.printStackTrace();
                }
            
                    if(flag==true){
                        //文件数据成功存入数据库
                        String ListURL=request.getContextPath()+"/uploadAction/upload!list"; //跳转到显示全部文件记录的页面
                        out.print("<script lang='javascript'>");
                        out.println("alert('文件数据存入成功')");
                        out.println("window.location.href='"+ListURL+"'");
                        out.print("</script>");
                    }else{
                        //文件数据存入数据库失败,返回上一页。
                        Global.WebErrorMsg(response, errorMsg);
                    }                    
                }        
            }    
            return null;   
        }
        
        /**
         * 以二进制形式上传到数据库的字段中。
         * 前提:
         * 1. jdk 1.6 以上版本。
         * 2. 必须要用prepare的Statement语句,否则操作不成功。
         * 3. 当用户成功上传文件或者上传失败的时候会有javaScript的alert提示,那么这个方法的返回值只能是null,否则脚本将无法运行。
         * @return
         */
        public String upload_to_table() {
            InputStream inputStream=null;
            if(fileFileName!=null && !fileFileName.equals("")){
                //如果文件名不为null或者不为空,说明用户有上传文件,需要处理文件上传
                fileName=this.getFileFileName();
                String errorMsg="";  //错误消息
                try {
                    inputStream=new FileInputStream(this.file);
                } catch (FileNotFoundException e1) {
                    e1.printStackTrace();
                }
                    //上传正确,记录到数据库
                    String sql="insert into file(id,filename,filedata) values(?,?,?)";
                boolean flag=false;
                Connection conn=null;
                PreparedStatement pstat=null;
                try {
                    conn=DButil.getConn();
                    conn.setAutoCommit(false);  //当用户上传数据的时候禁止事务的自动提交
                    pstat= conn.prepareStatement(sql);
                    pstat.setInt(1, this.id);
                    pstat.setString(2, this.fileFileName);
                    pstat.setBinaryStream(3, inputStream);
                    pstat.executeUpdate();
                    flag=true;
                    conn.commit();    //提交事务
        
                } catch (Exception e) {
                    try {
                        conn.rollback();//有异常就回滚事务。
                    } catch (SQLException e1) {
                
                        e1.printStackTrace();
                    }   
                    flag=false;
                    errorMsg=e.getMessage();  //如果上传错误,就把错误消息赋给errorMsg,前提是try里面的uptData方法定义里把异常抛出且uptData方法里的catch块里有把throw e即把异常对象抛出,否则这里的e.getMessage()就没有异常消息内容。                    
                    e.printStackTrace();
                }    
                    if(flag==true){
                        //文件数据成功存入数据库
                        String ListURL=request.getContextPath()+"/uploadAction/upload!list"; //跳转到显示全部文件记录的页面
                        out.print("<script lang='javascript'>");
                        out.println("alert('文件数据存入成功')");
                        out.println("window.location.href='"+ListURL+"'");
                        out.print("</script>");
                    }else{
                        //文件数据存入数据库失败,返回上一页。
                        Global.WebErrorMsg(response, errorMsg);
                    }
                }    
            return null;   
        }
        
        
        /**
         *生成文件数据库中所有文件的列表,以提供用户下载 
         * @return
         */
        
        public String list() throws Exception {
            //导入commons-dbutils-1.3.jar 使用里面的查询类实现快速查询
            QueryRunner run=new QueryRunner();
            
            String sql="select id,filename,filepath from file ";
            Connection    conn=DButil.getConn();
            List<Map<String, Object>> fileList =run.query(conn, sql, new MapListHandler());
            ActionContext actionContext=ActionContext.getContext();
            ValueStack valueStack=actionContext.getValueStack();
            
            valueStack.set("map", fileList);    
            return "list";
        }
    
    }
    • list.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
        <%@ taglib prefix="s" uri="/struts-tags"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <%String path=request.getContextPath(); %>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <s:debug></s:debug>
            <table border="1" width="100%">
                <tr>
                    <th>id</th>
                    <th>文件名</th>
                    <th>文件路径</th>
                    <th colspan="3">操作</th>
                </tr>
                
                <s:iterator value="map"  var="file" >
                <tr>
                    <td><s:property value="#file.id" /></td>
                    <td><s:property value="#file.filename" /></td>
                    <td><s:property value="#file.filepath" /></td>
                    <td><s:if test="#file.filepath!=null && #file.filename!='' ">
                    <a href="<%=path%>/download/downloadAction!from_folder?id=<s:property value="#file.id" />">从文件夹下载</a>
                    </s:if>&nbsp;
                    </td>
                    <td>
                    <s:if test="#file.filename!='' &&(#file.filepath==null || #file.filepath=='' )">
                    <a href="<%=path%>/download/downloadAction!from_table?id=<s:property value="#file.id" />">从数据库下载</a>
                    </s:if>
                    </td>
                    <td><s:if test="#file.filepath!=null && #file.filename!='' ">
                    <a href="<%=path%>/download/downloadAction!from_struts?id=<s:property value="#file.id" />">从struts下载</a>
                    </s:if>&nbsp;</td>
                </tr>
                </s:iterator>
            </table>
    </body>
    </html>
    • DownLoadAction 。java
    package action;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.util.Map;
    
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.MapHandler;
    import org.apache.commons.io.IOUtils;
    
    import DBUtils.DButil;
    import actionUtil.BaseAction;
    
    public class DownLoadAction extends BaseAction {
    
        @Override
        public String execute() throws Exception {
    
            return null;
        }
    
        /**
         * 从文件夹中下载文件 步骤: 1. 从数据库中根据客户端传来的id用找到这个文件 2. 定义response对象为二进制输出流 3.
         * 把文件的输入流拷贝到response输出流中。 注意:
         * 
         * @return
         */
        public String from_folder() throws Exception {
            int id = Integer.parseInt(request.getParameter("id"));
            String sql = "select filename,filepath from file where id='" + id + "'";
            Connection conn = null;
            String upload = context.getRealPath("/upload"); // 拿到存放文件的上传文件夹的路径
            String filepath = "";
            String filename = "";
            try {
                conn = DButil.getConn();
                QueryRunner run = new QueryRunner();
                Map<String, Object> map = run.query(conn, sql, new MapHandler());
                if (map != null) {
                    filename = (String) map.get("filename");
                    filepath = (String) map.get("filepath");
    
                    File file = new File(upload + "/" + filepath); // 拿到用户想要下载的文件
    
                    if (file.exists() == true) {
                        // 文件夹中有这个文件
                        InputStream fileinput = new FileInputStream(file); // 拿到用户想下载文件的输入流
    
                        /*
                         * 本类的response对象是BaseAction类中的response对象。这个对象定义了this.
                         * response.setContentType("text/html");
                         * 如果我们要想response返回的是文件流那么必修对这个对象进行重新定义。
                         */
                        response.reset();
                        response.setContentType("application/octet-stream"); // 表示输出的类型是流的数据类型。会弹出下载的窗口
                        String enco_filename = new String(filename.getBytes("GBK"), "ISO-8859-1"); // 设定下载窗口中显示文件名
                        response.setHeader("Content-Disposition", "attachment; filename="" + enco_filename + """);
                        OutputStream fileout = response.getOutputStream(); // 拿到response的输出流
                        // 文件输入流与response输出流的拷贝
                        int i = 0;
                        byte[] byteArray = new byte[10240];
                        while ((i = fileinput.read(byteArray)) != -1) {
                            fileout.write(byteArray, 0, i);
                            out.flush();
                        }
    
                        fileout.close(); // 输入输出流的关闭
                        fileinput.close();
                    } else {
                        // 文件夹中没有这个文件
                        throw new RuntimeException("下载的文件不存在。");
                    }
    
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                DButil.close(conn, null, null);
    
            }
    
            return null;
        }
    
        /**
         * 从数据库中下载文件
         * 
         * @return
         */
    
        public String from_table() {
            int id = Integer.parseInt(request.getParameter("id"));
            String sql = "select filename,filedata from file where id='" + id + "'";
            Connection conn = null;
            Statement stat = null;
            ResultSet rs = null;
            String filename = "";
            try {
                conn = DButil.getConn();
                stat = conn.createStatement();
                rs = stat.executeQuery(sql);
                
                if (rs.next()) {
                    filename = rs.getString("filename");
                    String enco_filename = new String(filename.getBytes("GBK"), "ISO-8859-1"); // 设定下载窗口中显示文件名
                    InputStream input = rs.getBinaryStream("filedata");
    
                    if (input != null) {
                        /*
                         * 本类的response对象是BaseAction类中的response对象。这个对象定义了this.
                         * response.setContentType("text/html");
                         * 如果我们要想response返回的是文件流那么必修对这个对象进行重新定义。
                         */
    
                        response.reset();
                        response.setContentType("application/octet-stream"); // 表示输出的类型是流的数据类型。会弹出下载的窗口
                        response.setHeader("Content-Disposition", "attachment; filename="" + enco_filename + """);
    
                        OutputStream fileout = response.getOutputStream(); // 拿到response的输出流
                        // 文件输入流与response输出流的拷贝
                        int i = 0;
                        byte[] byteArray = new byte[10240];
                        while ((i = input.read(byteArray)) != -1) {
                            fileout.write(byteArray, 0, i);
                            out.flush();
                        }
    
                        fileout.close(); // 输入输出流的关闭
                        input.close();
    
                    }
    
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                DButil.close(conn, null, null);
    
            }
    
            return null;
        }
    
        /**
         * 1.以struts方式下载文件,与从文件夹下载类似,
         * 2.用户需要的文件不是以response方式返回而是以return到struts.xml中的result这个result以stream的方法返回结果<result name="down_for_struts" type="stream">
         * 3.在result中配置参数,即下载文件的相关信息。
         * 4.在开发中一般用从文件夹或者从服务器字段下载,而不用struts下载,因为如果文件名中含有空格那么这种方法无法显示空格以后的内容。
         * 5.如果在result中需要使用到action中的变量比如文件名、文件输入流等,需要把这些变量设为成员变量且定义getset方法
         * @return
         */
        private InputStream fileInput;
        private String encode_filename;
    
    
        public InputStream getFileInput() {
            return fileInput;
        }
    
        public void setFileInput(InputStream fileInput) {
            this.fileInput = fileInput;
        }
    
        public String getEncode_filename() {
            return encode_filename;
        }
    
        public void setEncode_filename(String encode_filename) {
            this.encode_filename = encode_filename;
        }
    
        public String from_struts() {
            int id = Integer.parseInt(request.getParameter("id"));
            String sql = "select filename,filepath from file where id='" + id + "'";
            Connection conn = null;
            String upload = context.getRealPath("/upload"); // 拿到存放文件的上传文件夹的路径
            String filepath = "";
            String filename = "";
            try {
                conn = DButil.getConn();
                QueryRunner run = new QueryRunner();
                Map<String, Object> map = run.query(conn, sql, new MapHandler());
                if (map != null) {
                    filename = (String) map.get("filename");
                    filepath = (String) map.get("filepath");
    
                    File file = new File(upload + "/" + filepath); // 拿到用户想要下载的文件
    
                    if (file.exists() == true) {
                        // 文件夹中有这个文件
                
                        encode_filename = new String(filename.getBytes("GBK"), "ISO-8859-1"); // 设定下载窗口中显示文件名
                        response.reset();
                        this.fileInput=new FileInputStream(file);
                    
                        } 
                    } else {
                        // 文件夹中没有这个文件
                        throw new RuntimeException("下载的文件不存在。");
                    }
    
                }
             catch (Exception e) {
                e.printStackTrace();
            }
    
            return "down_for_struts";
        }
    }
    • BaseAction.java
    package actionUtil;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import org.apache.struts2.interceptor.ServletRequestAware;
    import org.apache.struts2.interceptor.ServletResponseAware;
    import org.apache.struts2.util.ServletContextAware;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public abstract class BaseAction extends ActionSupport implements
            ServletRequestAware, ServletResponseAware, ServletContextAware {
        protected HttpServletRequest request;
        protected HttpServletResponse response;
        protected ServletContext context;
        protected HttpSession session;
        protected PrintWriter out;
    
        public void setServletRequest(HttpServletRequest request) {
            this.request = request;
            if (this.request != null) {
                this.session = this.request.getSession();
            }
        }
    
        public void setServletResponse(HttpServletResponse response) {
            this.response = response;
            if (this.response != null) {
                try {
                    this.response.setContentType("text/html");
                    this.out = this.response.getWriter();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public void setServletContext(ServletContext context) {
            this.context = context;
        }
    
        public abstract String execute() throws Exception;
    }
    • DButil.java
    package DBUtils;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    
    public class DButil {
            
        private static final String DRIVER="com.mysql.jdbc.Driver"; 
        private static final String USER="root"; 
        private static final String PASSWD=""; 
        private static final String URL="jdbc:mysql://127.0.0.1:3306/user?useUnicode=true&characterEncoding=UTF-8"; 
        
        
        static{
        try{
            Class.forName(DRIVER);
            
        }catch(Exception e){
            throw new RuntimeException("无法加载驱动包");
        }
            
        }
        
        
        public static Connection getConn() {
            Connection conn=null;
            try {
                conn=DriverManager.getConnection(URL,USER,PASSWD);
    
            } catch (SQLException e) {
    
                e.printStackTrace();
            }
            return conn;
        }
        
        
        public static boolean uptData(String sql) throws Exception {
            Connection conn = null;
            Statement stmt = null;
            boolean flag = false;
            try {
                conn = DButil.getConn();
                stmt = conn.createStatement();
                stmt.executeUpdate(sql.toString());
                flag = true;
            } catch (Exception e) {
                flag = false;
                e.printStackTrace();
                throw e;
            } finally {
                DButil.close(conn, stmt, null);
            }
            return flag;
        }
        
        
        public static void close(Connection conn,Statement stat,ResultSet rs){
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(stat!=null){
                try {
                    stat.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
    
        }
    }
    }
    • Global.java
    package Global;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class Global {
        public static void WebErrorMsg(HttpServletResponse resonse,String errorMsg)  {
            PrintWriter out;
            try {
                out = resonse.getWriter();
                out.print("<head>");
                out.print("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
                out.print("</head>");
    
                out.print("<script lang='javascript'>");
                out.println("window.alert("数据操作出现错误!原因 = " + errorMsg + "");");
                out.print("window.history.back();");
                out.print("</script>");
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }    

    结果:

  • 相关阅读:
    python基础语法_9-2函数式编程
    python基础语法_9-1闭包 装饰器补充
    python基础语法_9-0函数概念
    python基础语法_8循环语句
    python基础语法_7运算符
    python基础语法_3面向对象
    python基础语法_2基本数据类型
    python基础语法_python中的布尔类型详解
    用户需求分析
    结对编程-词频统计(北航暑期软工培训) 郑琪 李泓毅
  • 原文地址:https://www.cnblogs.com/shyroke/p/6592260.html
Copyright © 2020-2023  润新知