jsp之文件的上传和下载
2016-07-18 22:16
281 查看
1.文件的上传
[1] 简介
将本地的文件传输到远程的服务器
上传文件需要通过表单来上传
上传文件实际上就是上传文件的流
[2] 表单的设置
我们使用type为file的input来上传文件,且method为post请求
form中有一个属性enctype
默认值是application/x-www-form-urlencoded,
该值的意思是请求体中的内容将会被URL编码
当上传文件的时候,并不希望请求体被URL编码,所以我们要修改该值
在文件上传时enctype的值应该设置为multipart/form-data
multipart/form-data:多部件的表单数据,当表单enctype设置为该值时,
表单中的数据将会分为多个部件上传到服务器
当多部件表单的形式上传文件时,表单的请求体将会被分成多个部分,
一个表单项对应了一个部件,多个部件使用类似于
—————————–7df232f2e07a4 这样的分割符分割
当表单设置为多部件表单时,那么request.getParameter()这个方法就废了。
[3] FileUpload
当接收是一个多部件表单时,我们需要手动的去解析表单中的内容,但是我们说手动解析太麻烦了。
我们使用commons-fileupload来解析表单
commons-fileupload 依赖于 commons-io , 所以使用时需要同时导入2个jar包
commons-fileupload-1.3.1.jar
commons-io-2.4.jar
核心类:
DiskFileItemFactory
工厂类,用来构建解析器类实例
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload
ServletFileUpload upload = new ServletFileUpload(factory);
- 解析器类,用来解析request,获取表单信息
FileItem
List< FileItem> list=upload.parseRequest(request);
FileUpload会将表单中每一个部件都封装为一个FileItem对象,我们可以通过读取FileItem对象来解析表单信息
方法:
boolean isFormField() –> 判断当前FileItem是否是一个普通表单项,如果是则返回true , 否则返回false
String getFieldName() –> 获取表单的name属性的值
String getString(String encoding) –> 获取表单项的value属性值,也就是我们填写的内容
String getName() –> 获取上传文件的名字
String getContentType() –> 获取上传文件的类型,返回是一个文件的MIME值
long getSize() –> 获取上传文件的大小
void write(File file) –> 将上传文件写入到指定的文件中。
使用步骤:导入第三方jar包
1.创建工厂类实例
2.创建解析器类实例
3.解析request,获取表单信息
[4] 细节
问题1:
部分浏览器选择文件以后,上传的文件的名字,是文件的全路径,具体如下:
C:\Users\zhao\Desktop\day16\图片\企鹅.jpg
这种情况我们需要对文件名进行一个截取的操作
1.判断文件名中是否包含 \
问题2:
当用户上传同名文件时,先上传的文件会被后上传的给替换。
可以来修改一下文件名,我们需要为文件名加上一个唯一的标识
将文件名修改为 唯一标识_文件名
问题3:
如何限制上传文件的大小
单个文件的大小
通过调用解析器ServletFileUpload的setFileSizeMax()方法可以来限制单个文件的大小。
当设置了这个值以后,文件超出范围以后,会在程序抛出异常如下异常:
FileSizeLimitExceededException
我们可以通过捕获该异常的方式来处理文件大小超过限制
catch(FileSizeLimitExceededException e){
//出现该异常,说明单个文件大小超过限制,设置一个错误消息
request.setAttribute(“msg”, “单个文件不要超过50kb”);
//转发到index.jsp
request.getRequestDispatcher(“/index.jsp”).forward(request, response);
}
所有文件的大小
通过setSizeMax()来设置所有上传文件总的大小
当文件超出限制时,会抛出如下异常
SizeLimitExceededException
我们可以捕获异常并作出相应处理
catch(SizeLimitExceededException e){
//出现该异常,说明文件总大小超过限制,设置一个错误消息
request.setAttribute(“msg”, “文件总大小不要超过150KB”);
//转发到index.jsp
request.getRequestDispatcher(“/index.jsp”).forward(request, response);
}
2.文件的下载(理解)
[1] 简介
从远程服务器将文件下载到本地
一般下载文件我们只需要将文件的地址发送给浏览器即可,
但是当浏览器访问的是一个它可以打开的文件,浏览器会自动打开
如果我们将文件直接放到根目录下的,那么将不能限制文件的下载权限
下载实际上就是将文件以流的形式发送给浏览器
[2] 下载所需要的内容
1.获取到文件的流
被下载的文件的流
2.设置两个响应头
Content-Type –> 被下载的文件的类型,需要设置一个文件的MIME值
Content-Disposition –> 告诉浏览器如何处理文件
设置值为:attachment; filename=文件名
attachment告诉浏览器文件是一个附件,直接下载到本地
filename告诉浏览器文件的名字
[3] 下载相关的两个响应头
1) 文件类型 Content-Type –> 文件的MIME类型
2) 下载文件的信息 Content-Disposition –> attachment; filename=文件名
[4] 乱码问题
文件名字是设置到响应头中,但是我们响应头不支持直接写中文,所以如果文件名为中文,会出现乱码。
所以当向响应头中设置中文需要对文字进行编码
大部分浏览器使用如下代码对文件名编码即可
但是,火狐使用的BASE64进行的编码,上边那种方式他不支持,我们单独处理
第一种方式:
//可以使用如下代码解决乱码问题
第二种方式:
原理:谁问跟谁急
先用gbk给字符解码,然后在使用iso8859-1进行编码
这种方式有点小问题,有一些特殊字符不太支持,但是大部分都好使
3.国际化(I18N)(理解)
[1]国际化简介
国际化指的是一个网站当中国人访问显示中文,外国人访问显示外语。
国际化主要指的支持英语
[2]国际化的原理
我们的国际化操作实际就是在项目提供不同国际化资源文件,ResourceBundle可以根据不同Locale来加载不同的国际资源文件
[3]核心类
java.util.ResourceBundle 用来管理国际化资源文件
java.util.Locale 来表示国家和语言的信息
国际化资源文件:
1.国际化资源文件必须创建到类路径下
2.命名规范: 基础名语言国家.properties
基础名:可以随便起
语言:使用语言
zh,en
国家:所在的国家
CN,US
[4]格式化标签库
国际化日期:
dateStyle
timeStyle
指定日期和时间的风格
可选值:FULL LONG MEDIUM SHORT
[1] 简介
将本地的文件传输到远程的服务器
上传文件需要通过表单来上传
上传文件实际上就是上传文件的流
[2] 表单的设置
我们使用type为file的input来上传文件,且method为post请求
form中有一个属性enctype
默认值是application/x-www-form-urlencoded,
该值的意思是请求体中的内容将会被URL编码
当上传文件的时候,并不希望请求体被URL编码,所以我们要修改该值
在文件上传时enctype的值应该设置为multipart/form-data
multipart/form-data:多部件的表单数据,当表单enctype设置为该值时,
表单中的数据将会分为多个部件上传到服务器
当多部件表单的形式上传文件时,表单的请求体将会被分成多个部分,
一个表单项对应了一个部件,多个部件使用类似于
—————————–7df232f2e07a4 这样的分割符分割
当表单设置为多部件表单时,那么request.getParameter()这个方法就废了。
[3] FileUpload
当接收是一个多部件表单时,我们需要手动的去解析表单中的内容,但是我们说手动解析太麻烦了。
我们使用commons-fileupload来解析表单
commons-fileupload 依赖于 commons-io , 所以使用时需要同时导入2个jar包
commons-fileupload-1.3.1.jar
commons-io-2.4.jar
核心类:
DiskFileItemFactory
工厂类,用来构建解析器类实例
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload
ServletFileUpload upload = new ServletFileUpload(factory);
- 解析器类,用来解析request,获取表单信息
FileItem
List< FileItem> list=upload.parseRequest(request);
FileUpload会将表单中每一个部件都封装为一个FileItem对象,我们可以通过读取FileItem对象来解析表单信息
方法:
boolean isFormField() –> 判断当前FileItem是否是一个普通表单项,如果是则返回true , 否则返回false
String getFieldName() –> 获取表单的name属性的值
String getString(String encoding) –> 获取表单项的value属性值,也就是我们填写的内容
String getName() –> 获取上传文件的名字
String getContentType() –> 获取上传文件的类型,返回是一个文件的MIME值
long getSize() –> 获取上传文件的大小
void write(File file) –> 将上传文件写入到指定的文件中。
使用步骤:导入第三方jar包
1.创建工厂类实例
2.创建解析器类实例
3.解析request,获取表单信息
[4] 细节
问题1:
部分浏览器选择文件以后,上传的文件的名字,是文件的全路径,具体如下:
C:\Users\zhao\Desktop\day16\图片\企鹅.jpg
这种情况我们需要对文件名进行一个截取的操作
1.判断文件名中是否包含 \
if(name.contains("\\")){ int p =name.lastIndexOf("\\")+1; name = name.substring(p); }
问题2:
当用户上传同名文件时,先上传的文件会被后上传的给替换。
可以来修改一下文件名,我们需要为文件名加上一个唯一的标识
将文件名修改为 唯一标识_文件名
String prefix = UUID.randomUUID().toString().replace("-", ""); String fileName = prefix+"_"+name;
问题3:
如何限制上传文件的大小
单个文件的大小
通过调用解析器ServletFileUpload的setFileSizeMax()方法可以来限制单个文件的大小。
当设置了这个值以后,文件超出范围以后,会在程序抛出异常如下异常:
FileSizeLimitExceededException
我们可以通过捕获该异常的方式来处理文件大小超过限制
catch(FileSizeLimitExceededException e){
//出现该异常,说明单个文件大小超过限制,设置一个错误消息
request.setAttribute(“msg”, “单个文件不要超过50kb”);
//转发到index.jsp
request.getRequestDispatcher(“/index.jsp”).forward(request, response);
}
所有文件的大小
通过setSizeMax()来设置所有上传文件总的大小
当文件超出限制时,会抛出如下异常
SizeLimitExceededException
我们可以捕获异常并作出相应处理
catch(SizeLimitExceededException e){
//出现该异常,说明文件总大小超过限制,设置一个错误消息
request.setAttribute(“msg”, “文件总大小不要超过150KB”);
//转发到index.jsp
request.getRequestDispatcher(“/index.jsp”).forward(request, response);
}
2.文件的下载(理解)
[1] 简介
从远程服务器将文件下载到本地
一般下载文件我们只需要将文件的地址发送给浏览器即可,
但是当浏览器访问的是一个它可以打开的文件,浏览器会自动打开
如果我们将文件直接放到根目录下的,那么将不能限制文件的下载权限
下载实际上就是将文件以流的形式发送给浏览器
[2] 下载所需要的内容
1.获取到文件的流
被下载的文件的流
2.设置两个响应头
Content-Type –> 被下载的文件的类型,需要设置一个文件的MIME值
Content-Disposition –> 告诉浏览器如何处理文件
设置值为:attachment; filename=文件名
attachment告诉浏览器文件是一个附件,直接下载到本地
filename告诉浏览器文件的名字
[3] 下载相关的两个响应头
1) 文件类型 Content-Type –> 文件的MIME类型
2) 下载文件的信息 Content-Disposition –> attachment; filename=文件名
[4] 乱码问题
文件名字是设置到响应头中,但是我们响应头不支持直接写中文,所以如果文件名为中文,会出现乱码。
所以当向响应头中设置中文需要对文字进行编码
大部分浏览器使用如下代码对文件名编码即可
URLEncoder.encode(fileName, "utf-8");
但是,火狐使用的BASE64进行的编码,上边那种方式他不支持,我们单独处理
fileName = "=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes("utf-8"))+"?=";
第一种方式:
//可以使用如下代码解决乱码问题
//在不同浏览器中需要调用不同代码,为了兼容不同的浏览器,我们需要在编码之前,对浏览器进行一个判断 //获取User-Agent这个请求头 String ua = request.getHeader("User-Agent"); //判断当前浏览器是否为火狐 if(ua.contains("Firefox")){ //是火狐 fileName = "=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes("utf-8"))+"?="; }else{ //对fileName进行URL编码 //encode需要两个参数,第一个被编码的字符串,第二个使用字符集 fileName = URLEncoder.encode(fileName, "utf-8"); }
第二种方式:
原理:谁问跟谁急
fileName = new String(fileName.getBytes("gbk"), "iso8859-1");
先用gbk给字符解码,然后在使用iso8859-1进行编码
这种方式有点小问题,有一些特殊字符不太支持,但是大部分都好使
//获取ServletContext ServletContext servletContext = getServletContext(); //获取文件的真实路径 String realPath = servletContext.getRealPath("/WEB-INF/爱的就是你.mp3"); //获取文件名 String fileName = "爱的就是你.mp3"; 处理文件名的乱码问题...... //获取被下载文件的流 InputStream in = new FileInputStream(realPath); //获取文件的MIME类型 String mimeType = servletContext.getMimeType(realPath); //设置文件的MIME类型 response.setContentType(mimeType); //设置Content-Disposition这个响应头 response.setHeader("Content-Disposition", "attachment; filename="+fileName); //将文件的流发送给浏览器 //获取一个和浏览器对接的输出流,将文件的流发送出去 ServletOutputStream out = response.getOutputStream(); //将输入流写到输出流 IOUtils.copy(in, out); //关闭输入流 in.close();
3.国际化(I18N)(理解)
[1]国际化简介
国际化指的是一个网站当中国人访问显示中文,外国人访问显示外语。
国际化主要指的支持英语
[2]国际化的原理
我们的国际化操作实际就是在项目提供不同国际化资源文件,ResourceBundle可以根据不同Locale来加载不同的国际资源文件
[3]核心类
java.util.ResourceBundle 用来管理国际化资源文件
java.util.Locale 来表示国家和语言的信息
国际化资源文件:
1.国际化资源文件必须创建到类路径下
2.命名规范: 基础名语言国家.properties
基础名:可以随便起
语言:使用语言
zh,en
国家:所在的国家
CN,US
[4]格式化标签库
> 我们可以使用JSTL的fmt标签来进行国际化操作: > 导入JSTL的jar包 > 在页面中引入指定的标签库: <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <fmt:setBundle basename="基础名"/> 指定使用的国际化资源文件的基础名 {setBundle 是全局的,bundle是局部的,只在其标签体内有效。} <fmt:setLocale value="zh_CN"/> 手动指定当前Locale对象 <fmt:message key="" /> 在jsp中引用国际化资源文件中的内容,key的值对应国际化资源文件中的key值。 <fmt:formatDate dateStyle="full" timeStyle="full" value="<%=new Date() %>" type="both"/> <fmt:formatDate value>
国际化日期:
dateStyle
timeStyle
指定日期和时间的风格
可选值:FULL LONG MEDIUM SHORT
相关文章推荐
- 校验身份证号码的有效性【JS】
- JSP
- JSP之JSTl标签
- JS:(JavaScript)
- js表单克隆
- js中函数参数传递
- PipeValid.js 2.0 数据验证
- JSp之EL表达式
- Python全栈开发之14、Javascript
- 【JavaScript】Cookie and Web Storage
- JSP语法基础
- List转JSON异常错误
- JSON 入门 之 JSON 的语法规则(二)
- JavaScript的onunload()方法在关闭页面时不执行
- 使用JSON实现简单的城市级联查询
- Js中setTimeout()和setInterval()方法简介
- JS--switch 语句
- js加载和执行
- JSON 入门 之 JSON与XML 的比较(一)
- js中 string 转 int 注意的问题——parseInt