zoukankan      html  css  js  c++  java
  • Struts1.3——文件上传和下载

    1.Struts文件上传

    在Web开发中,会经常涉及到文件的上传和下载,比如在注册账户的时候,我们需要上传自己的头像等。 
    我们可以利用Struts很方便地实现文件的上传。

    1.1 开发步骤

    现在,假设我们要在注册的时候上传自己的头像。新建项目名称为StrutsFileUpAndDown,并引入Struts1.3

    (1)首先,写注册的JSP页面register.jsp 
    它的body内容如下:

    <body>
        <h1>注册用户</h1>
        <% --如果表单有文件控件,则需要重新指定表单的编码方式 --%>
        <form enctype="multipart/form-data" action="/StrutsFileUpAndDown/register.do" method="post">
            名字:<input type="text" name="name" /><br> 
            头像:<input type="file" name="photo" /><br> 
            <input type="submit" value="注册" />
        </form>
    </body>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 这里使用普通的HTML标签来写表单。一定要注意加上form的enctype属性,并且内容为”multipart/form-data”
    • 这里必须使用post方法提交,get方法会出错
    • action的地址刚开始的时候可以先空着,后面有了Action之后,再补上去。这里我的Action的path为”/register”

    (2)添加对应的ActionForm,名字为UserForm

    public class UserForm extends ActionForm {
        private String name = null;
        private FormFile photo = null;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public FormFile getPhoto() {
            return photo;
        }
        public void setPhoto(FormFile photo) {
            this.photo = photo;
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 要知道的是,JSP中的文件控件对应的是FormFile对象,该对象由Struts框架提供。

    (2)添加对应的Action,名字为RegisterAction,并配置path为/register 
    最关键的地方就在于Action是怎么写的,我们点击注册之后,是由Action来处理这个逻辑的,文件也就是通过这个Action传上来的。

    • 首先我们要得到UserForm中的内容:
    UserForm userForm = (UserForm) form;
    String username = userForm.getName();
    FormFile formFile = userForm.getPhoto();
    • 1
    • 2
    • 3
    • 接着,我们保存文件,FormFile对象有getInputStream()方法可以得到文件的输入流。此时我们还需要一个输出流OutputStream,用于将输入流拿到的东西通过输出流保存到服务器的磁盘。但要注意输出流的输出路径是Tomcat下的绝对路径
    // 文件名称
    String fileName = formFile.getFileName();
    // 获取输入流
    InputStream is = formFile.getInputStream();
    // 得到一个输出流
    // 首先得到file文件夹上传到Tomcat服务器后的绝对路径
    String path = request.getServletContext().getRealPath("file");
    OutputStream os = new FileOutputStream(path + "\" + fileName);
    // 读取文件并写出到服务器file文件夹下
    int len = 0;
    // 做一个缓存
    byte[] bytes = new byte[1024];
    // 循环处理
    while ((len = is.read(bytes)) > 0) {
        // 读一点,写一点
        os.write(bytes, 0, len);
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    当然,这整个过程要处理异常。如果不出错的话,我们就可以将文件上传给服务器了。

    【注意,这里省略一些简单的配置步骤】

    1.2 改进

    (1)问题1:中文乱码的处理,如果用户上传的文件是中文名称会出现乱码

    此时,过滤器可以很好地解决这个问题。只需要加上一个过滤器,将request的编码设置为utf-8即可。

    public class EncodingFilter implements Filter {
        @Override
        public void destroy() {
    
        }
    
        @Override
        public void doFilter(ServletRequest arg0, ServletResponse arg1,
                FilterChain arg2) throws IOException, ServletException {
            arg0.setCharacterEncoding("utf-8");
            arg2.doFilter(arg0, arg1);
        }
    
        @Override
        public void init(FilterConfig arg0) throws ServletException {
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    配置如下:

    <filter>
        <filter-name>EncodingFilter</filter-name>
        <filter-class>com.gavin.filter.EncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>EncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    (2)问题2:这里我们保存在服务器的文件名称是用户上传的名称,那么如果有两个用户上传的文件名称一样就会出现覆盖的情况,所以我们要在服务器端进行文件名的处理

    这里,我们不再使用用户上传的文件的名称。那么又怎么样才能保证文件名的唯一呢?

    • 1.一种方法是以当前的时间(年+月+日+时+分+秒+毫秒)作为文件的名称
    • 2.另外,可以直接使用java.util.UUID类,UUID不会重复,这种方法最为简单。
    String uuid = UUID.randomUUID().toString();
    • 1
    • 3.当然,使用UUID之后,还要加上原来文件的后缀才行,所以干脆写一个工具类:
    public class MyTools {
        /**
         * 得到文件后缀
         * @param fileName
         * @return
         */
        public static String getFileSuffix(String fileName) {
            return fileName.substring(fileName.lastIndexOf("."));
        }
    
        /**
         * 得到UUID
         * @return
         */
        public static String getUUID(){
            String uuid = UUID.randomUUID().toString();
            return uuid;
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    (3)问题3:如果用户上传的不是图片怎么办?如果用户上传的图片太大了怎么办?

    所以这里我们要进行文件的限制,要进行文件的类型和大小的限制,如果不符合要求,则跳转至一个错误页面并给出提示: 
    这里我限制文件的大小上限为10MB,如下:

    if (fileSize > 10 * 1024 * 1024) {
        request.setAttribute("error", "文件大小不能超过10MB!");
        return mapping.findForward("error");
    }
    
    if(!formFile.getContentType().startsWith("image/")){
        request.setAttribute("error", "文件格式有错,请检查!");
        return mapping.findForward("error");
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    【注意】文件的类型是不是图片,不是通过后缀名来判断的,要调用FormFile的方法,具体的文件类型你可以查看Tomcat安装目录下的conf文件夹下的web.xml文件中的配置。

    所以,最后,一个完整的RegisterAction是这样的:

    public class RegisterAction extends Action {
        public ActionForward execute(ActionMapping mapping, ActionForm form,
                HttpServletRequest request, HttpServletResponse response) {
            UserForm userForm = (UserForm) form;
            String username = userForm.getName();
            FormFile formFile = userForm.getPhoto();
    
            // 通过FormFile我们可以获取关于用户上传文件的各种信息,比如大小,名字等
            String fileName = formFile.getFileName();
            int fileSize = formFile.getFileSize();
    
            if (fileSize > 10 * 1024 * 1024) {
                request.setAttribute("error", "文件大小不能超过10MB!");
                return mapping.findForward("error");
            }
    
            if(!formFile.getContentType().startsWith("image/")){
                request.setAttribute("error", "文件格式有错,请检查!");
                return mapping.findForward("error");
            }
    
            InputStream is = null;
            OutputStream os = null;
            String uuid = MyTools.getUUID();
            String suffix = MyTools.getFileSuffix(fileName);
            String newFileName = uuid + suffix;
            try {
                is = formFile.getInputStream();
                String path = request.getServletContext().getRealPath("file");
                System.out.println(path);
                os = new FileOutputStream(path + "\" + newFileName);
                int len = 0;
                byte[] bytes = new byte[1024];
                while ((len = is.read(bytes)) > 0) {
                    os.write(bytes, 0, len);
                }
    
                //这里省略保存数据库的操作
                //逻辑上的正常跳转,这里也省略
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (os != null) {
                        os.close();
                    }
                    if (is != null) {
                        is.close();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
            request.setAttribute("error", "注册出错!");
            return mapping.findForward("error");
        }
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    2.Struts文件下载

    文件下载,我们在介绍原生Servlet的时候已经介绍过,可以参考【Servlet——使用http响应头Content-Disposition下载文件的示例】

    当然,那时候我们是把下载的业务逻辑写在一个Servlet中,这里其实也没有什么不同,只不过我们要将业务逻辑写在一个Struts的Action中,并且该Action不需要配置相应的表单。

    当我们点击下载的超链接时,让它请求这个Action即可。并且最后让该Action跳转至原来的页面:

    return mapping.findForward("goback");
    • 1

    goback

    版权声明:本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    sql月,年,统计报表sql报表
    Sql server在cmd下的使用
    c# 批量处理数据录入
    vmware安装64位系统“此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态”的问题
    以太坊去中心化淘宝智能合约案例
    智能合约入门
    智能资产构建去中心化的资产管理系统
    以太坊搭建联盟链
    web 前端
    EasyUI+bootsrtap混合前端框架
  • 原文地址:https://www.cnblogs.com/husam/p/7943755.html
Copyright © 2011-2022 走看看