文件的上传、文件的下载、I18N国际化

本文介绍如何使用Apache FileUpload组件实现文件上传,包括文件名处理、类型与大小限制,并提供文件下载功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:文件上传

01.文件上传准备

1):上传控件所在的<form>表单的method,必须POST:

        因为GET方式的数据大小不能超过2kb,而POST没有大小限制.

2):上传控件得使用typefile的类型.<input type="file" name="headImg"/>

3):表单的编码方式必须是二进制编码.<form enctype="multipart/form-data">

        注意:使用二进制的编码之后form enctype="multipart/form-data">,在Servlet中再也不能通过request.getParameter方法来获取参数了,设置编码也没有效果

02.基于Apache FileUpload组件文件上传操作

依赖的jar:

    1):commons-fileupload-1.2.2.jar

    2):commons-io-1.4.jar

参考文档:

    commons-fileupload-1.2.2\site\index.html

hello world版本,建议自己看着文档写一遍

@WebServlet("/upload")
public class UploadServlet extends HttpServlet{

    private static final long serialVersionUID = 1L;

    protected void service(HttpServletRequest req, HttpServletResponse resp){
        //解析和检查请求:请求方式是否是POST,请求编码是否是enctype="multipart/form-data"
        boolean isMultipart = ServletFileUpload.isMultipartContent(req);
        if(!isMultipart){
            return;
        }
        //1:创建FileItemFactory对象
        //FileItemFactory是用来创建FileItem对象的.
        //FileItem对象:form表单中的表单控件的封装
        try {
        FileItemFactory factory = new DiskFileItemFactory();
        //2:创建文件上传处理器
        ServletFileUpload upload = new ServletFileUpload(factory);
        //3:解析请求
            List<FileItem> items = upload.parseRequest(req);

            for (FileItem item : items) {
                String fieldName = item.getFieldName();//获取表单控件的name属性值(参数名)
                if(item.isFormField()){
                    //普通表单控件
                    String value = item.getString("UTF-8");//获取当前普通表单控件的参数值
                    System.out.println(fieldName+"--"+value);
                }else{
                    //表单上传控件
                    System.out.println(fieldName+"+"+item.getName());
                    item.write(new File("D:/",item.getName()));//把二进制数据写到哪一个文件中
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

03.上传文件的名称处理

1):文件名处理:

        IE6问题:通过FileItem.getName方法获取上传文件的名称,此时会带有路径:

        其他浏览器:outman.png.  IE6:C:/123/outman.png.

        使用FilenameUtils.getName(path);

        上传文件名称:给上传的文件起唯一的名称:UUID.

        String fileName = UUID.randomUUID().toString()+"."+FilenameUtils.getExtension(item.getName());

        上传文件的保存路径:一般的,把上传文件保存到应用里面.

2):缓存大小和临时目录:

        超过多少就不直接存放与内存了(缓存大小):默认值是10KB.

        不放在内存,会放在哪个位置(临时目录):默认Tomcat根/temp目录.不建议修改

        DiskFileItemFactory factory = new DiskFileItemFactory();
        //设置缓存大小
        factory.setSizeThreshold(20*1024);
        //设置临时目录
        factory.setRepository(repository);

3):文件类型约束:  

    //获取当前上传文件的MIME类型

    String mimeType = super.getServletContext().getMimeType(item.getName());

servlet代码:

        //允许接受的图片类型
        private static final String ALLOWED_IMAGE_TYPE="png;gif;jpg;jpeg";

        //上传文件的拓展名
        String ext = FilenameUtils.getExtension(item.getName());
        String[] allowedImageType = ALLOWED_IMAGE_TYPE.split(";");      
        //当前上下文的类型不在图片允许的格式之内
        if(!Arrays.asList(allowedImageType).contains(ext)){
                req.setAttribute("errorMsq","亲,请上传图片文件");
                req.getRequestDispatcher("/input.jsp").forward(req,resp);
                return ;//结束方法
        }

jsp的代码:

        <span style="color: red;">${errorMsg}</span>

4)抽取文件上传工具方法.

    @WebServlet("/upload")
    public class UploadServlet extends HttpServlet{
        private static final long serialVersionUID = 1L;
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            try {
                FileUtil.upload(req);
            } catch (LogicException e) {
                String errorMsge = e.getMessage();
                req.setAttribute("errorMsg", errorMsge);
                req.getRequestDispatcher("/input.jsp").forward(req, resp);
            }
        }
    }


    public class FileUtil {
        //允许接收的图片类型
            private static final String ALLOWED_IMAGE_TYPE = "gif;jpq;jpeg";
            public static void upload(HttpServletRequest req) {     
            try{
                    ......
                    if (!list.contains(ext)) {
                            throw new LogicException("亲!请上传正确的图片格式!");
                    }
                    ......
            } catch (LogicException e) {
                throw e;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
5):上传文件大小约束:

    情况1: 单个文件超过指定的大小.           upload.setFileSizeMax(1024 * 1024 * 2);

    情况2: 该次请求的全部数据超过指定的大小   upload.setSizeMax(1024*1024*3)

    catch (FileSizeLimitExceededException e) {
    throw new LogicException("亲,单个文件大小不能超过2M",e);
    } catch (SizeLimitExceededException e) {
        throw new LogicException("亲,该次请求的大小不能超过3M",e);
    } catch (LogicException e) {
        throw e;//继续抛出异常给调用者(UploadServlet)
    } catch (Exception e) {
        e.printStackTrace();
    }
6):使用Map封装请求信息(拓展):

    @Data
    public class User {
        private String username;
        private String email;
        private String imageUrl;//图片保存的路径:/upload/123.png       JSP: <img src="${user.imageUrl}"/> 
        private String imageName;//图片的原始名称
    }

    @Data
    public class CFiled {

        private String imageUrl;
        private String imageName;
    }

    @WebServlet("/upload")
    public class UploadServlet extends HttpServlet{
        private static final long serialVersionUID = 1L;
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            try {

                User user = new User();
                HashMap<String,String> map = new HashMap<>();
                HashMap<String,CFiled> binaryMap = new HashMap<>();
                FileUtil.upload(req,map,binaryMap);
                user.setEmail(map.get("email"));
                user.setUsername(map.get("username"));
                user.setImageName(binaryMap.get("headimg").getImageName());
                user.setImageUrl(binaryMap.get("headimg").getImageUrl());
                System.out.println(map);
                System.out.println(binaryMap);
                System.out.println(user);
                req.setAttribute("u", user);
                req.getRequestDispatcher("/show.jsp").forward(req, resp);

            } catch (LogicException e) {
                String errorMsge = e.getMessage();
                req.setAttribute("errorMsg", errorMsge);
                req.getRequestDispatcher("/input.jsp").forward(req, resp);
            }
        }
    }

    public class FileUtil {
    private static final String ALLOWED_IMAGE_TYPE = "png;gif;jpq;jpeg";
    public static void upload(HttpServletRequest req, HashMap<String,String> map, HashMap<String,CFiled> binarytMap) {
        boolean isMultipart = ServletFileUpload.isMultipartContent(req);
        if (!isMultipart) {
            return;
        }
        try {
            DiskFileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setFileSizeMax(1024 * 1024 * 2);//2M
            upload.setSizeMax(1024*1024*3);//3M
            List<FileItem> items = upload.parseRequest(req);
            for (FileItem item : items) {
                String fieldName = item.getFieldName();//获取表单控件的name属性值(参数名)
                if (item.isFormField()) {
                    //普通表单控件
                    String value = item.getString("UTF-8");//获取当前普通表单控件的参数值
                    map.put(fieldName, value);
                } else {
                    //--------------------------------------------
                    //上传文件的拓展名
                    String ext = FilenameUtils.getExtension(item.getName());
                    String[] allowedImageType = ALLOWED_IMAGE_TYPE.split(";");
                    List<String> list = Arrays.asList(allowedImageType);
                    if (!list.contains(ext)) {
                        throw new LogicException("亲!请上传正确的图片格式!");
                    }
                    //--------------------------------------------
                    //表单上传控件
                    System.out.println("上传文件的名称:" + FilenameUtils.getName(item.getName()));
                    String fileName = UUID.randomUUID().toString() + "." + FilenameUtils.getExtension(item.getName());
                    String dir = req.getServletContext().getRealPath("/upload");
                    item.write(new File(dir, fileName));//把二进制数据写到哪一个文件中
                    CFiled CFiled = new CFiled();
                    CFiled.setImageName(FilenameUtils.getName(item.getName()));
                    CFiled.setImageUrl("/upload/"+fileName);
                    binarytMap.put(fieldName,CFiled);
                }
            }
        } catch (FileSizeLimitExceededException e) {
            throw new LogicException("亲,单个文件大小不能超过2M",e);
        } catch (SizeLimitExceededException e) {
            throw new LogicException("亲,该次请求的大小不能超过3M",e);
        } catch (LogicException e) {
            throw e;//继续抛出异常给调用者(UploadServlet)
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

二:文件的下载

IE和非IE的文件名乱码处理:

list.jsp文件:

        <h3>下载资源列表</h3>
        <a href="/down?filename=butter.rar">butter.rar</a><br/>
        <a href="/down?filename=超人superman.rar">超人Superman</a>

Servlet文件:

        @WebServlet("/down")
        public class DownloadServlet extends HttpServlet{

            private static final long serialVersionUID = 1L;
            protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                //0:权限检查/积分检查
                //1:获取被下载的资源文件名称
                String fileName = req.getParameter("filename");
                if(fileName!=null && !"".equals(fileName.trim())){
                    fileName = new String(fileName.getBytes("ISO-8859-1"),"utf-8");
                    System.out.println(fileName);
                }
                //2:从服务器中找到被下载资源的绝对路径
                String realPath = super.getServletContext().getRealPath("/WEB-INF/download/"+fileName);
                //=======================================
                //①:告诉浏览器不要直接打开文件,而是弹出下载框,保存文件
                resp.setContentType("application/x-msdownload");
                //②:设置下载文件的建议保存名称
                String userAgent = req.getHeader("User-Agent");
                if(userAgent.contains("like")){
                    //IE
                    fileName = URLEncoder.encode(fileName,"UTF-8");
                }else{
                    //非IE
                    fileName = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
                }
                resp.setHeader("Content-Disposition","attachment;filename="+fileName); 
                //=======================================
                //3:磁盘中的文件读取到--->程序中来--->浏览器(拷贝操作)
                Files.copy(Paths.get(realPath), resp.getOutputStream());
            }
        }

三: I18N国际化

04.国际化了解上

        软件的本地化,一个软件在某个国家或地区使用时,采用该国家或地区的语言,数字,货币,日期等习惯.

软件的国际化:软件开发时,让它能支持多个国家和地区的本地化应用.使得应用软件能够适应多个地区的语言和

文化习俗的习惯.随用户区域信息而变化的数据称为本地信息敏感数据.例如数字,货币等数据.应用程序的国际

化就是在应用软件的设计阶段,使软件能够支持多个国家和地区的使用习惯.

05.国际化了解下

        @Test
    public void test1() throws Exception {
        System.out.println(Locale.CHINA);
        System.out.println(Locale.US);
        System.out.println(Locale.FRANCE);
        System.out.println(Locale.TAIWAN);
    }

    @Test
    public void testFormat() throws Exception {
        System.out.println(new Date());
        String format = DateFormat.getInstance().format(new Date());
        System.out.println(format);
    }
    //¥123,456,789.89
    //123?456?789,89 €
    //?123,456,789.89
    //$123,456,789.89
    @Test
    public void testNumberFormat() throws Exception {
        Double money = 123456789.89;
        NumberFormat format = NumberFormat.getCurrencyInstance(Locale.US);
        System.out.println(format.format(money));
    }
    public static void main(String[] args) {
            String pattern = "我是{3},你是{5},他是{4},她是{2},它是{1}";
            String str = MessageFormat.format(pattern, "A","B","C","D","E");
            System.out.println(str);
        }

    @Test
    public void testSql() throws Exception {
        String sql = "SELECT * FROM {0} {1}";
        String ret = MessageFormat.format(sql, "product","WHERE productName LIKE = ?");
        System.out.println(ret);
    }
    public static void main(String[] args) {
        //ResourceBundle可以获取资源文件,获取其中的信息
        ResourceBundle rb = ResourceBundle.getBundle("app",Locale.CHINA);
        String username = rb.getString("username");
        String company = rb.getString("company");
        System.out.println(username+"---->"+company);
    }

知识点:

    1):基于Apache 的fileUploaed组件完成文件的上传操作.
    2):文件上传做控制:
            1):文件名处理.
            2):上传文件的类型约束.
            3):上传文件的大小限制.
    3):文件下载操作.
    -----------------------------------------------
    任务:
        1):高级查询和分页查询,巩固,加强.
        2):去淘宝,去京东体验购物车.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值