• 文件的上传(如何兼容火狐与IE)与国际化的原理


    1.文件的上传
        [1] 简介
            > 将本地的文件上传到服务器中
            > 用户需要通过一个表单将文件上传到服务器中
     
        [2] 表单的设置
            > 上传文件时需要使用input表单项,input的type时file。
            > 上传文件的表单一定要是post请求。
            > 在表单中还有一个属性:
                enctype,使用它来指定如何处理请求体,它的默认值是application/x-www-form-urlencoded。
                他的意思是请求体会被URL编码,而我们上传文件时上传的是文件流,它是不需要被编码的
            > 在上传文件时enctype属性必须设置为:multipart/form-data
                它表示将我们的表单设置为一个多部件的表单,当表单设置为该值时,那么我们的一个表单项会作为一个部件,发送到服务器。
                    当使用多部件表达式,请求体会使用类似这样的-----------------------------7e01ce2921096c分割符来分割。
            > 当表单设置为多部件表单以后,我们的request.getParameter()就废了。       
     
        [3] FileUpload
            > commons-fileupload
            > commons-fileupload是Apache出的一款专门用来处理文件上传的工具,
                使用它可以自动去解析多部件表单。
            > commons-fileupload依赖于commons-io
            > 使用它需要导入两个jar包:
                commons-fileupload-1.3.1.jar
                commons-io-1.4.jar
            > 核心类:
                DiskFileItemFactory
                    - 工厂类,用来构建解析器
                ServletFileUpload
                    - 解析器类,用来解析请求报文
                FileItem
                    - 解析器将解析到的内容封装为FileItem对象
                    - 方法:
                        boolean isFormField() --> 判断当前表单项是否是普通表单项,如果是普通表单项返回true,否则返回false
                        String getContentType() --> 获取文件的类型,返回是一个MIME值
                        String getFieldName() --> 获取表单项的name属性值
                        String getName() --> 获取上传文件的名字
                        long getSize() --> 获取文件的大小(字节)
                        String getString(String encoding) --> 获取用户填写value值,需要传一个字符集
                        void write(File file) --> 将文件写入磁盘中
     
            > 如何使用:
                1.获取工厂类实例
                2.获取解析器类实例
                3.解析请求报文获取FileItem对象
     
        [4] 细节
            >  部分浏览器在上传文件时,文件名使用的是文件的绝对路径。
                而在保存文件时,使用绝对路径会出现问题,文件不能正常写入到服务器中。
            > 所以这种情况我们需要做一些处理:
                C:asdzxcDesktopqweert rrr.jpg
                所以这种文件名,我们需要对它进行截取字符串的操作,从最后一个以前的内容全都不要
     
            > 当我们上传文件时,很有可能多个用户上传同名文件,这样会导致后上传的文件覆盖旧文件,
                我们可以为图片添加一个唯一的标识作为前缀:唯一标识_rrrr.jpg。
                这里我们的唯一标识使用UUID
     
            > 文件大小的限制
                - 限制文件大小的操作,都是通过解析器对象ServletFileUpload来进行
                1.单个文件大小的限制
                    - 限制文件大小为60kb
                        fileUpload.setFileSizeMax(1024*60);
                    - 当上传的文件超过限制,程序会抛出异常:
                        FileSizeLimitExceededException
                    - 我们可以对该异常进行捕获,然后显示一个错误消息   
     
                2.文件总大小的限制
                    - 限制文件总大小为150KB
                        fileUpload.setSizeMax(1024*150);
                    - 当上传文件的总大小超标是,会抛出如下异常:
                        SizeLimitExceededException
                    - 我们可以对该异常进行捕获,然后显示一个错误消息   
     
    2.文件的下载
        [1] 简介
            > 将服务器中的文件下载到本地
            > 下载文件很简单,直接把文件放到服务器中,然后为浏览器提供一个超链接即可,
                但是如果浏览器支持当前文件格式,浏览器会自动打开文件,不会直接下载。
            > 如果将文件直接放到服务器中,当用户下载文件时不会有任何的限制,不能去检查用户的权限。
                所以一般我们下载时我们将文件放到WEB-INF文件夹下,让用户通过访问一个Servlet来进行下载。
     
        [2] 下载所需要的内容
                1.获取到文件的流
                2.设置两个响应头
     
        [3] 下载相关的两个响应头
            1) 文件类型 Content-Type --> 文件的MIME类型   
                - 下载的文件的类型,需要设置一个MIME值
                - 文件的MIME类型可以通过总的web.xml进行查询
                - 我们也可以通过ServletContext的getMimeType()方法来获取文件的MIME类型
     
            2) 下载文件的信息 Content-Disposition --> attachment; filename=文件名
                - Content-Disposition这个头用来告诉浏览器如何处理文件
                - 值 attachment; filename=文件名,这个值就是告诉浏览器我发给你的是一个附件,请你下载
                    filename用来指定文件的名字。
     
            3) 中文乱码问题:
                > 在响应头中不能直接设置中文,如果非得设置,必须对文件名进行url编码。
                    fileName = URLEncoder.encode(fileName, "utf-8");
                    大部分浏览器可以采用以上方式
                > 但是FireFox它是使用Base64进行的编码,所以如果是火狐,使用上述方式,依然不好使。
                    火狐的编码方式:fileName = "=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes())+"?=";
                > 但是火狐的方式IE又不支持了,如果我们需要同时兼容这两款浏览器,在设置编码是必须做一个判断,
                    如果是IE浏览器,则使用 fileName = URLEncoder.encode(fileName, "utf-8");
                        如果是Firefox,则使用 fileName = "=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes())+"?=";
                > 我们可以通过User-Agent的请求头,来判断浏览器的版本,如果头中包含Firefox,则表示他是火狐。
                > 事例代码:
                    //判断浏览器是否是火狐
                    if(ua.contains("Firefox")){
                        //如果是火狐浏览器
                        fileName = "=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes())+"?=";
                    }else{
                        //其他浏览器
                        //对文件名进行编码
                        //encode()需要两个参数,第一个被编码的字符串,第二个是使用的字符集
                        fileName = URLEncoder.encode(fileName, "utf-8");
                    }
     
                > 还有一种方式,不太讲理,谁问跟谁急
                > 先是用gbk为文件名进行编码,再使用iso-8859-1进行解码
                    fileName = new String(fileName.getBytes("gbk"), "iso-8859-1");
                > 这种方式虽然简单,但是有一些个别的字符会出问题。   
     
     
    3.国际化(I18N)
        [1]国际化简介
            > 国际化主要指我们的应用对不同国家和地区的语言的支持。
            > 国际化主要指支持英文。
     
        [2]核心类
            ResourceBundle
                - 负责管理国际化资源文件,根据不同的国家和地区的信息去加载不同的国际化资源文件
     
            Locale
                - locale负责表示国家地区和语言的信息
     
        [3]国际化的原理
            国际化资源文件:   
                > 国际化资源文件实际上就是一个properties文件,它配置的都是一些键值对结构
                > 国际化资源文件要求必须放到类路径下(src)
                > 命名规则:基础名_语言_国家.properties
     
            ResourceBundle会根据不同Locale信息,去加载不同的国际化资源文件,从而达到国际化的目的。
     
     
     
     
        [4]格式化标签库
            > 还可以使用JSTL中fmt标签来完成国际化的操作。
            > 导入fmt标签:
                <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>   
            > 常用标签
                <fmt:setBundle basename="基础名"/>
                <fmt:message key="属性名" />
                <fmt:setLocale value="zh_CN"/>
                <fmt:formatDate value="<%=new Date() %>" type="both" dateStyle="full" timeStyle="full"/>
                    value属性:是被格式化的日期
                    type属性:日期的类型,date只显示日期,time只显示时间,both全都显示
                    dateStyle和timeStyle属性:用来设置日期和时间的风格
                        可选值:full long medium short
            > 占位符:
                在国际化资源文件中可以指定带占位符的信息,占位符从0开始,形式如下:
                    WELCOME {0} TO OUR SITE, TODAY IS {1}
                在页面中使用带占位符的消息,需要在message标签中插入param子标签,
                    param子标签用来指定替换站位符的内容,
                        第一个param会替换所有的{0}
                        第二个会替换所有的{1}
                        以此类推
                例子:
                    <fmt:message key="info">
                        <fmt:param>
                            <span style="color: red;">大师兄</span>
                        </fmt:param>
                        <fmt:param>
                            <span style="color: red;"><fmt:formatDate value="<%=new Date() %>" type="both" dateStyle="full" timeStyle="full"/></span>
                        </fmt:param>
                    </fmt:message>
     

    转载请注明出处!

    http://www.cnblogs.com/libingbin/

    感谢您的阅读。如果文章对您有用,那么请轻轻点个赞,以资鼓励。

  • 相关阅读:
    “阿基里斯与乌龟”的终结性思考
    这个世界本来的样子
    Seven times have I despised my soul 《我曾七次鄙视自己的灵魂》
    Youth is not a time of life, it is a state of mind.
    对于过去所犯的错误,最好的道歉是在将来做正确的事
    使用UltraISO刻录自己的音乐CD步骤
    为什么一个目录里放超过十个Mp4文件会导致资源管理器和播放程序变卡变慢?
    用Perl发送邮件小例子
    用df命令显示磁盘使用量和占用率。
    三个JS函数闭包(closure)例子
  • 原文地址:https://www.cnblogs.com/libingbin/p/5993219.html
Copyright © 2020-2023  润新知