文件上传
2016-06-24 11:43
148 查看
文件上传:
commons-fileupload-1.2.1.jar
commons-io-2.0.jar
一、原理
文件上传中三个重要的API:
1.org.apache.commons.fileupload.disk.DiskFileItemFactory: 创建 FileItem 实例的工厂
三个重要的方法:
(1)setSizeThreshold(int sizeThreshold):设置阀值的大小,该阀值决定了上传的文件是保存在内存中还是保存在临时文件中。参数为字节。默认值为:Size threshold is 10KB.
(2)setRepository(File repository):指定上传临时目录,默认值为 System.getProperty("java.io.tmpdir")。
(3)DiskFileItemFactory(int sizeThreshold, File repository)。
2.org.apache.commons.fileupload.servlet.ServletFileUpload:处理文件上传的类,将表单的每一个输入项封装为一个 FileItem 对象。
(1)isMultipartContent(HttpServletRequest request): 判断表单上传类型是否以 "multipart/" 开头。
(2)ServletFileUpload(FileItemFactory fileItemFactory):构造方法,传入FileItemFactory实例。
(3)List /* FileItem */ parseRequest(HttpServletRequest request):解析 request 对象,并把表单中的每一个输入项包装成一个 fileItem 项,并返回FileItem的list集合。
(4)setFileSizeMax(long fileSizeMax):设置单个上传文件的最大值,参数为字节。
(5)setSizeMax(long sizeMax):设置上传文件总量的最大值
(5)setHeaderEncoding(java.lang.String encoding):设置编码格式
3.FileItem: keep their content either in memory,for smaller items, or in a temporary file on disk, for larger items.
步骤:
1.创建 DiskFileItemFactory 对象,设置缓冲区大小,和临时文件目录
2.使用 DiskFileItemFactory 对象创建 ServletFileUpload 对象,判断isMultipartContent(req)并设置上传文件的大小限制。
3.使用 ServletFileUpload 的 parseRequest(req) 方法,得到保存所有上传对象的 List FileItem 对象。
4.对 List<FileItem> 对象进行迭代,每迭代一个 FileItem 对象,调用其 isFormField() 方法判断其是否是上传文件。
5.若是上传文件,通过 FileItem 的 getFieldName() 获取字段名,通过 getName() 获取文件名这里需要注意一个问题。
需要注意的问题:
通过 FileItem 的 getName() 方法获取到的是:
IE下:
C:\Users\sovlerpeng\Desktop\2016-06-06_172310.png
Chrome下:
2016-06-06_172310.png
需要对IE下的文件名进行处理。
6.调用 FileItem 的 write(File file) 方法,将缓存的文件写到真实的文件目录里。
细节问题:
1.当上传文件超出设置的阀值大小时,Commons-fileupload 将使用临时文件存储上传数据。
2.文件位置:为防止上传相同文件名的文件,而导致文件被覆盖,所以应该保证上传的文件具有唯一名。
3.为防止单个目录下文件过多,影响文件读写速度,处理上传文件的类型或时间或其他,生成不同的目录,将文件分散存储。
4.文件上传速度
(1) ProgressListener显示上传进度
ProgressListenerprogressListener = new ProgressListener() {
public void update(longpBytesRead, long pContentLength, int pItems) {
System.out.println("到现在为止, " + pBytesRead + " 字节已上传,总大小为 " + pContentLength);
}
};
upload.setProgressListener(progressListener);
(2)以KB为单位显示上传进度
long temp = -1; //temp注意设置为类变量
long ctemp =pBytesRead /1024;
if (mBytes ==ctemp)
return;
temp = mBytes
5.
1字节=8位
1kb = 1024字节
1mb = 1024kb
1gb = 1024mb
1tb = 1024gb
例子:
MultipartUpload
5.类型限制:文件类型限制对应于 org.apache.struts2.interceptor.FileUploadInterceptor 定义的几个属性,Struts2 中对文件类型的限制即对拦截器中对应属性的设置。
(1)总文件大小限制:默认上传文件总大小是在 default.properties 中定义的,默认为2M。如果要更改的话,通过修改常量的方式来修改总文件大小。如:
(2)单个文件大小限制:maximumSize
(3)文件类型限制 :allowedTypes,allowedExtensions
如:
6.自定义错误消息
(1)默认的文件上传错误消息存放在 D:\workspace\idea\nucsoft\struts2_fileupload\webapp\WEB-INF\lib\struts2-core-2.3.15.3.jar\struts-messages.properties 下
(2)自定义错误消息:
添加国际化资源文件:i18n.properties,指定国际化资源文件基名:<constant name="struts.custom.i18n.resources" value="i18n"/>
占位符介绍:
三、SpringMVC 文件上传
1.SpringMVC对文件上传提供了直接的支持,使用 MultipartResolver 实现,具体实现类:CommonsMultipartResolver。
2.Spring 上下文默认没有装配 MultipartResolver,若想支持文件上传,需要装配 MultipartResolver。
当然需要导入:
commons-fileupload-1.2.1.jar
commons-io-2.0.jar
这两个包。
3.单文件上传
表单:
handler 方法:
4.多文件上传
表单:
handler 方法:
5.对于类型限制,我这里提供两种思路。
(1)通过拦截器的方式来过滤,但是不够灵活。
(2)通过读取表中限制类型的方式。
(3)通过配置文件的方式。
6.在生产环境中
在生产环境中,一般会新增一个文件类,用来保存上传成功后的一些信息,如路径、文件名等,保存在数据表中,在使用的时候就非常方便了。
commons-fileupload-1.2.1.jar
commons-io-2.0.jar
一、原理
文件上传中三个重要的API:
1.org.apache.commons.fileupload.disk.DiskFileItemFactory: 创建 FileItem 实例的工厂
三个重要的方法:
(1)setSizeThreshold(int sizeThreshold):设置阀值的大小,该阀值决定了上传的文件是保存在内存中还是保存在临时文件中。参数为字节。默认值为:Size threshold is 10KB.
(2)setRepository(File repository):指定上传临时目录,默认值为 System.getProperty("java.io.tmpdir")。
(3)DiskFileItemFactory(int sizeThreshold, File repository)。
2.org.apache.commons.fileupload.servlet.ServletFileUpload:处理文件上传的类,将表单的每一个输入项封装为一个 FileItem 对象。
(1)isMultipartContent(HttpServletRequest request): 判断表单上传类型是否以 "multipart/" 开头。
(2)ServletFileUpload(FileItemFactory fileItemFactory):构造方法,传入FileItemFactory实例。
(3)List /* FileItem */ parseRequest(HttpServletRequest request):解析 request 对象,并把表单中的每一个输入项包装成一个 fileItem 项,并返回FileItem的list集合。
(4)setFileSizeMax(long fileSizeMax):设置单个上传文件的最大值,参数为字节。
(5)setSizeMax(long sizeMax):设置上传文件总量的最大值
(5)setHeaderEncoding(java.lang.String encoding):设置编码格式
3.FileItem: keep their content either in memory,for smaller items, or in a temporary file on disk, for larger items.
步骤:
1.创建 DiskFileItemFactory 对象,设置缓冲区大小,和临时文件目录
2.使用 DiskFileItemFactory 对象创建 ServletFileUpload 对象,判断isMultipartContent(req)并设置上传文件的大小限制。
3.使用 ServletFileUpload 的 parseRequest(req) 方法,得到保存所有上传对象的 List FileItem 对象。
4.对 List<FileItem> 对象进行迭代,每迭代一个 FileItem 对象,调用其 isFormField() 方法判断其是否是上传文件。
5.若是上传文件,通过 FileItem 的 getFieldName() 获取字段名,通过 getName() 获取文件名这里需要注意一个问题。
需要注意的问题:
通过 FileItem 的 getName() 方法获取到的是:
IE下:
C:\Users\sovlerpeng\Desktop\2016-06-06_172310.png
Chrome下:
2016-06-06_172310.png
需要对IE下的文件名进行处理。
6.调用 FileItem 的 write(File file) 方法,将缓存的文件写到真实的文件目录里。
细节问题:
1.当上传文件超出设置的阀值大小时,Commons-fileupload 将使用临时文件存储上传数据。
2.文件位置:为防止上传相同文件名的文件,而导致文件被覆盖,所以应该保证上传的文件具有唯一名。
3.为防止单个目录下文件过多,影响文件读写速度,处理上传文件的类型或时间或其他,生成不同的目录,将文件分散存储。
4.文件上传速度
(1) ProgressListener显示上传进度
ProgressListenerprogressListener = new ProgressListener() {
public void update(longpBytesRead, long pContentLength, int pItems) {
System.out.println("到现在为止, " + pBytesRead + " 字节已上传,总大小为 " + pContentLength);
}
};
upload.setProgressListener(progressListener);
(2)以KB为单位显示上传进度
long temp = -1; //temp注意设置为类变量
long ctemp =pBytesRead /1024;
if (mBytes ==ctemp)
return;
temp = mBytes
5.
1字节=8位
1kb = 1024字节
1mb = 1024kb
1gb = 1024mb
1tb = 1024gb
例子:
/** * @author solverpeng * @create 2016-07-12-15:33 */ public class MultipartUpload extends ActionSupport implements ServletContextAware { private List<File> logo; private List<String> logoContentType; private List<String> logoFileName; private ServletContext context; private String fileDesc; public List<File> getLogo() { return logo; } public void setLogo(List<File> logo) { this.logo = logo; } public List<String> getLogoContentType() { return logoContentType; } public void setLogoContentType(List<String> logoContentType) { this.logoContentType = logoContentType; } public List<String> getLogoFileName() { return logoFileName; } public void setLogoFileName(List<String> logoFileName) { this.logoFileName = logoFileName; } public String getFileDesc() { return fileDesc; } public void setFileDesc(String fileDesc) { this.fileDesc = fileDesc; } @Override public String execute() throws Exception { FileInputStream in = null; FileOutputStream out = null; String realPath = context.getRealPath("/WEB-INF/upload") + "/" + System.currentTimeMillis(); String targetPath = ""; for(int i = 0; i < logo.size(); i++) { in = new FileInputStream(logo.get(i)); targetPath = realPath + logoFileName.get(i); out = new FileOutputStream(targetPath); byte[] b = new byte[1024]; int len = 0; while((len = in.read(b)) != -1) { out.write(b, 0, len); } out.close(); in.close(); } return SUCCESS; } @Override public void setServletContext(ServletContext context) { this.context = context; } }
MultipartUpload
5.类型限制:文件类型限制对应于 org.apache.struts2.interceptor.FileUploadInterceptor 定义的几个属性,Struts2 中对文件类型的限制即对拦截器中对应属性的设置。
(1)总文件大小限制:默认上传文件总大小是在 default.properties 中定义的,默认为2M。如果要更改的话,通过修改常量的方式来修改总文件大小。如:
<constant name="struts.multipart.maxSize" value="5242880"/><!-- 改为5M -->
(2)单个文件大小限制:maximumSize
(3)文件类型限制 :allowedTypes,allowedExtensions
如:
<interceptors> <interceptor-stack name="myStack"> <interceptor-ref name="defaultStack"> <param name="fileUpload.maximumSize">5242880</param> <!-- 单个文件总大小 --> <param name="fileUpload.allowedTypes">image/jpeg,application/pdf</param> <!-- 允许的类型 --> <param name="fileUpload.allowedExtensions">pdf</param><!-- 运行的后缀 --> </interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="myStack"/>
6.自定义错误消息
(1)默认的文件上传错误消息存放在 D:\workspace\idea\nucsoft\struts2_fileupload\webapp\WEB-INF\lib\struts2-core-2.3.15.3.jar\struts-messages.properties 下
(2)自定义错误消息:
添加国际化资源文件:i18n.properties,指定国际化资源文件基名:<constant name="struts.custom.i18n.resources" value="i18n"/>
struts.messages.error.file.too.large=The file is to large to be uploaded: {0} "{1}" "{2}" {3} struts.messages.error.content.type.not.allowed=Content-Type not allowed: {0} "{1}" "{2}" {3} struts.messages.error.file.extension.not.allowed=File extension not allowed: {0} "{1}" "{2}" {3} struts.messages.upload.error.SizeLimitExceededException=Request exceeded allowed size limit! Max size allowed is: {0} but request was: {1}! struts.messages.upload.error.IOException=Error uploading: {0}!
占位符介绍:
0:当前文件上传域的name值 1:文件名 2:临时文件名 3:文件类型
三、SpringMVC 文件上传
1.SpringMVC对文件上传提供了直接的支持,使用 MultipartResolver 实现,具体实现类:CommonsMultipartResolver。
2.Spring 上下文默认没有装配 MultipartResolver,若想支持文件上传,需要装配 MultipartResolver。
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"> <property name="defaultEncoding" value="UTF-8"/> <property name="maxUploadSize" value="5343880"/> </bean>
当然需要导入:
commons-fileupload-1.2.1.jar
commons-io-2.0.jar
这两个包。
3.单文件上传
表单:
<form action="testUpload" enctype="multipart/form-data" method="post"> Desc: <input type="text" name="desc"/> File: <input type="file" name="file"/> <input type="submit" value="Submit" /> </form>
handler 方法:
@RequestMapping("/testUpload") public String upload(@RequestParam("desc") String desc, @RequestParam("file")MultipartFile file, HttpServletRequest request) throws IOException { System.out.println(desc); uploadFile(file, request); return "success"; }
private void uploadFile(MultipartFile file, HttpServletRequest request) throws IOException { if(!file.isEmpty()) { String targetPath = request.getSession().getServletContext().getRealPath("/")+ "upload/" + file.getOriginalFilename(); file.transferTo(new File(targetPath)); } }
4.多文件上传
表单:
<form action="testUpload2" enctype="multipart/form-data" method="post"> Desc: <input type="text" name="desc"/> File1: <input type="file" name="file"/> File2: <input type="file" name="file"/> File3: <input type="file" name="file"/> <input type="submit" name="Submit"> </form>
handler 方法:
@RequestMapping("/testUpload2") public String upload(@RequestParam("desc") String desc, @RequestParam("file") MultipartFile[] files, HttpServletRequest request) throws IOException { System.out.println(desc); for(MultipartFile file : files) { uploadFile(file, request); } return "success"; }
5.对于类型限制,我这里提供两种思路。
(1)通过拦截器的方式来过滤,但是不够灵活。
(2)通过读取表中限制类型的方式。
(3)通过配置文件的方式。
6.在生产环境中
在生产环境中,一般会新增一个文件类,用来保存上传成功后的一些信息,如路径、文件名等,保存在数据表中,在使用的时候就非常方便了。
相关文章推荐
- Material Design Ripple 标签的简单使用
- a
- 安装oracle即时客户端
- iterm终端高亮
- MVVM初尝试--UITableView数据Manager思路分享
- 不以预测为目的的大数据都是耍流氓
- 程序猿的笑话!
- spark操作hbase
- iOS MPMoviePlayerController(已废弃)入门使用(模仿keep未登录)&广告动画开场效果
- ArrayList练习(带答案)
- bootstrapvalidator+bootstrap-select select无法校验问题解决方法
- 解决inline-block上下不对齐
- IOS系列- CALayer
- 安装oracle即时客户端
- Nginx开发从入门到精通-基础篇
- C#双缓冲实现方法(可防止闪屏)
- 使用Jacob合并多个word文档生成一个word文档
- ASCII码表
- 使用POI读写word docx文件(笔记记录)
- C++11新特性之新类型与初始化