html上传时支持断点续传,关闭浏览器或刷新浏览器后仍然能够保留进度,同时不会对文件带来影响。
HTML的全称为超文本标记语言,是一种标记语言。它包括一系列标签.通过这些标签可以将网络上的文档格式统一,使分散的Internet资源连接为一个逻辑整体。
首先需要明确,上传这东西不仅仅是只需要前端就能完成的很好的,需要前端后端统一数据格式,从而实现断点续传。(所以,该文适合于全栈工程师,至少是想成为)还有,为什么需要分片,不分片能实现断点续传吗?分片是为了充分利用网络带宽,加快上传速度;不分片也是能够实现断点续传的。详细参考 HTML5文件上传组件深度剖析.
分片上传与断点续传之间没有很直接的关系.
实现断点续传的前提是需要服务器记录某文件的上传进度,那么根据什么判断是不是同一个文件呢?可以利用文件内容求md5码,如果文件过大,求取md5码也是一个很长的过程,所以对于大文件,只能针对某一段数据进行计算,加上服务器对cookie用户信息的判断,得到相对唯一的key。
在前端页面,需要将文件按照一定大小进行分片,一次请求只发送这一小片数据,所以我们可以同时发起多个请求。但一次同时请求的连接数不宜过多,服务器负载过重。对于文件分片 *** 作,H5具有十分强大的File API,直接利用File对象的slice方法即可得到Blob对象。
至于同时传输数据的连接数控制逻辑,就需要花点脑子思考了。前端把数据顺利得传给服务器了,服务器只需要按照数据中给的开始字节位置,与读取到的文件片段数据,写入文件即可
使用Struts2上传文件:
Struts文件上传需要使用File Upload Filter。Filter Upload Filter使用一些默认的规则:
Form中的<s:file name="image"></s:file>标签对应着Action类中的三个属性分别是:上传文件(java.io.File类型),文件名(java.lang.String类型),文件类型(java.lang.String类型,例如:image/jpeg)。命名规约为:
文件:名字与<s:file>标签中的name属性一致,这里为:image
文件名:文件 + FileName,这里为:imageFileName
文件类型:文件 + ContentType,这里为:imageContentType
所以针对上述<s:file name="image"></s:file>表示啊的上传文件的JSP和Action类被别为:
imageUpload.jsp:
[html] view plain copy
<%@ page contentType="text/htmlcharset=UTF-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head><title>Image Upload</title></head>
<body>
<h1> Image Upload Page </h1>
<s:form action="imageUpload" method="post" enctype="multipart/form-data">
<s:file name="image"></s:file>
<s:submit></s:submit>
</s:form>
</body>
</html>
ImageUploadAction.java:
[html] view plain copy
package com.jpleasure
import com.opensymphony.xwork2.ActionSupport
import java.io.File
import java.io.InputStream
import java.io.FileInputStream
import java.io.FileNotFoundException
public class ImageUploadAction extends ActionSupport {
private File image
private String imageFileName
private String imageContentType
public File getImage() {
return image
}
public void setImage(File image) {
this.image = image
}
public String getImageFileName() {
return imageFileName
}
public void setImageFileName(String imageFileName) {
this.imageFileName = imageFileName
}
public String getImageContentType() {
return imageContentType
}
public void setImageContentType(String imageContentType) {
this.imageContentType = imageContentType
}
public String execute() {
if (image != null) {
System.out.println("file name is:" + this.imageFileName)
System.out.println("file content type is:" + this.imageContentType)
System.out.println("file length is:" + this.image.length())
}
return SUCCESS
}
}
Struts.xml配置文件:
[html] view plain copy
<action name="imageUpload" class="com.jpleasure.ImageUploadAction">
<result>/success.jsp</result>
</action>
这样当我们选中上传文件,提交的时候:文件内容会以File类型的方式放在image声明的变量中。文件的名字将会被放在imageFileName命名的变量中,文件的类型被放在imageContentType命名的变量中。
文件下载:
文件下载需要使用一个特殊的Result,stream类型的Result。Stream类型的Result主要用来处理文件下载 *** 作。
处理原理为:所有的下载文件都是将一个二进制的流写入到HttpResponse中去。在Action类中定义一个InputSream类型的二进制流,在Result返回给用户的时候返回给用户。
扩展上述的代码,将上传来的文件直接下载给用户:
ImageUploadAction中需要追加一个InputSream类型的对象,并且指向上传的文件,代码如下,红色部分表示变化:
[html] view plain copy
package com.jpleasure
import com.opensymphony.xwork2.ActionSupport
import java.io.File
import java.io.InputStream
import java.io.FileInputStream
import java.io.FileNotFoundException
public class ImageUploadAction extends ActionSupport {
private File image
private String imageFileName
private String imageContentType
private InputStream imageInputStream = null
public InputStream getImageInputStream() {
return imageInputStream
}
public void setImageInputStream(InputStream imageInputStream) {
this.imageInputStream = imageInputStream
}
public File getImage() {
return image
}
public void setImage(File image) {
this.image = image
}
public String getImageFileName() {
return imageFileName
}
public void setImageFileName(String imageFileName) {
this.imageFileName = imageFileName
}
public String getImageContentType() {
return imageContentType
}
public void setImageContentType(String imageContentType) {
this.imageContentType = imageContentType
}
public String execute() {
if (image != null) {
System.out.println("file name is:" + this.imageFileName)
System.out.println("file content type is:" + this.imageContentType)
System.out.println("file length is:" + this.image.length())
try {
this.imageInputStream = new FileInputStream (image)
} catch (FileNotFoundException e) {
e.printStackTrace()
}
}
return SUCCESS
}
}
配置文件为,红色为变化部分:
[html] view plain copy
<action name="imageUpload" class="com.jpleasure.ImageUploadAction">
<result name="success" type="stream">
<param name="contentType">image/pjpeg</param>
<param name="inputName">imageInputStream</param>
<param name="contentDisposition">attachmentfilename="image.jpg"</param>
<param name="bufferSize">1024</param>
</result>
</action>
ContentType表示下载文件的类型。
InputName表示Action类中用来下载文件的字段的名字。
ContentDisposition用来控制文件下载的一些信息,包括是否打开另存对话框,下载文件名等。
BufferSize表示文件下载时使用的缓冲区的大小。
实际项目开发的考虑:
控制上传文件的类型和最大允许上传文件的size
使用File Upload Intercepter的参数可盈控制上传文件的类型和最大允许上传文件的size。例如:
[html] view plain copy
<struts>
<package name="myPackage" extends="struts-default">
<interceptor-ref name="fileUpload">
<param name="maximumSize">2MB</param>
<param name="allowedTypes">text/html,image/jpeg</param>
</interceptor-ref>
<interceptor-ref name="basicStack"/>
<action name="imageUpload" class="com.jpleasure.ImageUploadAction">
<result name="success" type="stream">
<param name="contentType">image/pjpeg</param>
<param name="inputName">imageInputStream</param>
<param name="contentDisposition">
attachmentfilename="image.jpg"
</param>
<param name="bufferSize">1024</param>
</result>
</action>
</package>
</struts>
上述表示允许上传jpeg和html类型的文件,且最大文件上传size为2MB
显示错误信息:
可以使用如下key表示的message来显示文件上传出错的提示信息:
消息Key 说明
struts.messages.error.uploading 文件无法正常上传时的公共错误
struts.messages.error.file.too.large 文件大小超过最大允许size时的错误提示
struts.messages.error.content.type.not.allowed 文件类型不在上传文件允许类型中的错误提示
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)