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

    版权声明:本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    HDU 1069 Monkey and Banana
    HDU 1029 Ignatius and the Princess IV
    HDU 1024 Max Sum Plus Plus
    Gym100923H Por Costel and the Match
    Codeforces 682C Alyona and the Tree
    Codeforces 449B Jzzhu and Cities
    Codeforces (ccpc-wannafly camp day2) L. Por Costel and the Semipalindromes
    Codeforces 598D (ccpc-wannafly camp day1) Igor In the Museum
    Codeforces 1167c(ccpc wannafly camp day1) News Distribution 并查集模板
    快乐数问题
  • 原文地址:https://www.cnblogs.com/husam/p/7943755.html
Copyright © 2011-2022 走看看