|
|
|
@ -8,253 +8,153 @@ import org.apache.commons.codec.binary.Base64;
|
|
|
|
|
import org.apache.commons.fileupload.*;
|
|
|
|
|
import org.apache.commons.fileupload.FileUploadBase.InvalidContentTypeException;
|
|
|
|
|
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
|
|
|
|
|
import org.apache.commons.fileupload.util.*;
|
|
|
|
|
import org.apache.commons.fileupload.servlet.*;
|
|
|
|
|
import org.apache.commons.fileupload.util.Streams;
|
|
|
|
|
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
|
|
|
|
import org.apache.commons.fileupload.FileItemIterator;
|
|
|
|
|
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
|
|
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
/**
|
|
|
|
|
* UEditor文件上传辅助类
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// Uploader类是一个UEditor文件上传辅助类,用于处理文件上传的各种操作,包括文件格式检查、大小限制判断、文件保存路径处理以及实际的文件上传逻辑等,
|
|
|
|
|
// 同时支持常规的表单文件上传和接收Base64格式文件上传两种方式,并且会根据上传过程中的不同情况设置相应的状态信息,方便调用者知晓上传结果。
|
|
|
|
|
public class Uploader {
|
|
|
|
|
// 输出文件地址
|
|
|
|
|
|
|
|
|
|
// 用于存储上传文件的输出文件地址,即文件最终保存的相对路径或者完整路径(根据具体使用场景确定),初始值为空字符串,在文件上传成功后会被赋值为实际的保存路径。
|
|
|
|
|
private String url = "";
|
|
|
|
|
// 上传文件名
|
|
|
|
|
// 用于存储上传后的文件名,这个文件名可能是经过处理后生成的新文件名(例如添加随机数、时间戳等以保证文件名的唯一性等情况),初始值为空字符串,上传成功后会被赋予实际的文件名。
|
|
|
|
|
private String fileName = "";
|
|
|
|
|
// 状态
|
|
|
|
|
// 用于表示文件上传的状态,通过设置不同的状态值(从errorInfo这个HashMap中获取对应的状态描述字符串)来反馈上传过程中出现的各种情况,例如成功、文件格式错误、大小超出限制等,初始值为空字符串,会在上传操作过程中根据情况进行更新。
|
|
|
|
|
private String state = "";
|
|
|
|
|
// 文件类型
|
|
|
|
|
// 用于存储文件的类型,一般通过文件扩展名来确定,例如 ".jpg"、".pdf" 等,在文件上传过程中会进行相应的提取和赋值操作,初始值为空字符串。
|
|
|
|
|
private String type = "";
|
|
|
|
|
// 原始文件名
|
|
|
|
|
// 用于存储上传文件的原始文件名,即用户在客户端选择文件时的原始文件名称,方便记录和后续可能的展示等操作,初始值为空字符串,上传时会获取并赋值。
|
|
|
|
|
private String originalName = "";
|
|
|
|
|
// 文件大小
|
|
|
|
|
// 用于存储上传文件的大小,单位为字节,在文件上传完成后会获取并记录文件的实际大小,初始值为0。
|
|
|
|
|
private long size = 0;
|
|
|
|
|
|
|
|
|
|
// 用于接收来自客户端的HTTP请求对象(HttpServletRequest),通过这个对象可以获取上传文件相关的信息(如请求头、请求参数等),在整个文件上传过程中起着关键的信息获取作用,初始值为null,通过构造函数传入。
|
|
|
|
|
private HttpServletRequest request = null;
|
|
|
|
|
// 用于存储文件的标题信息(可能在某些特定的业务场景下使用,例如图片有对应的标题描述等情况),初始值为空字符串,会在处理表单中对应字段时进行赋值。
|
|
|
|
|
private String title = "";
|
|
|
|
|
|
|
|
|
|
// 保存路径
|
|
|
|
|
// 用于指定文件的保存路径,默认值为 "upload",表示文件将会被保存到这个相对路径下(实际的物理路径会根据服务器配置等情况进一步确定),可以通过相应的Setter方法进行修改设置。
|
|
|
|
|
private String savePath = "upload";
|
|
|
|
|
// 文件允许格式
|
|
|
|
|
private String[] allowFiles = { ".rar", ".doc", ".docx", ".zip", ".pdf",".txt", ".swf", ".wmv", ".gif", ".png", ".jpg", ".jpeg", ".bmp" };
|
|
|
|
|
// 文件大小限制,单位KB
|
|
|
|
|
// 用于定义允许上传的文件格式数组,只有文件名后缀符合这个数组中定义的格式的文件才允许被上传,初始包含了常见的一些文件格式,如压缩文件、文档文件、图片文件等类型的后缀名,可通过Setter方法重新设置允许的文件格式。
|
|
|
|
|
private String[] allowFiles = { ".rar", ".doc", ".docx", ".zip", ".pdf", ".txt", ".swf", ".wmv", ".gif", ".png", ".jpg", ".jpeg", ".bmp" };
|
|
|
|
|
// 用于设置文件大小的限制,单位为KB,默认值为10000KB,即10MB,如果上传文件的大小超过这个限制,将会在上传过程中被拦截并设置相应的错误状态,可通过Setter方法调整文件大小限制值。
|
|
|
|
|
private int maxSize = 10000;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 用于存储各种文件上传错误信息的HashMap,键为表示错误类型的字符串(如 "SUCCESS"、"NOFILE" 等),值为对应的详细错误描述字符串,方便根据不同的上传情况设置相应的状态信息并反馈给调用者具体的错误原因。
|
|
|
|
|
private HashMap<String, String> errorInfo = new HashMap<String, String>();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 构造函数,用于初始化Uploader实例并设置相关的错误信息映射
|
|
|
|
|
* 该构造函数接收一个HttpServletRequest对象作为参数,将其赋值给成员变量request,以便后续在文件上传过程中获取请求相关的信息。
|
|
|
|
|
* 同时初始化errorInfo这个HashMap,添加了一系列表示不同上传结果状态(成功或各种错误情况)的键值对,用于后续根据上传过程中的实际情况设置相应的状态信息并返回给调用者详细的反馈。
|
|
|
|
|
*
|
|
|
|
|
* @param request HttpServletRequest对象,代表客户端发送的HTTP请求,包含了文件上传相关的信息,如请求头、请求参数以及上传的文件内容等,是进行文件上传操作的重要数据来源。
|
|
|
|
|
*/
|
|
|
|
|
public Uploader(HttpServletRequest request) {
|
|
|
|
|
this.request = request;
|
|
|
|
|
HashMap<String, String> tmp = this.errorInfo;
|
|
|
|
|
tmp.put("SUCCESS", "SUCCESS"); //默认成功
|
|
|
|
|
tmp.put("NOFILE", "未包含文件上传域");
|
|
|
|
|
tmp.put("TYPE", "不允许的文件格式");
|
|
|
|
|
tmp.put("SIZE", "文件大小超出限制");
|
|
|
|
|
tmp.put("ENTYPE", "请求类型ENTYPE错误");
|
|
|
|
|
tmp.put("REQUEST", "上传请求异常");
|
|
|
|
|
tmp.put("IO", "IO异常");
|
|
|
|
|
tmp.put("DIR", "目录创建失败");
|
|
|
|
|
tmp.put("UNKNOWN", "未知错误");
|
|
|
|
|
|
|
|
|
|
tmp.put("SUCCESS", "SUCCESS"); //默认成功,设置表示上传成功的状态对应的描述信息为 "SUCCESS",方便后续判断和返回结果时使用。
|
|
|
|
|
tmp.put("NOFILE", "未包含文件上传域"); // 设置表示请求中未包含文件上传相关字段的错误状态对应的描述信息,用于在没有文件上传时反馈相应的错误情况。
|
|
|
|
|
tmp.put("TYPE", "不允许的文件格式"); // 设置表示上传文件的格式不符合允许的文件格式列表(allowFiles)的错误状态对应的描述信息,用于文件格式验证不通过时反馈错误原因。
|
|
|
|
|
tmp.put("SIZE", "文件大小超出限制"); // 设置表示上传文件大小超过了设定的最大文件大小限制(maxSize)的错误状态对应的描述信息,用于文件大小超出限制时告知调用者具体错误情况。
|
|
|
|
|
tmp.put("ENTYPE", "请求类型ENTYPE错误"); // 设置表示请求的类型(如Content-Type等相关请求头不符合文件上传要求)出现错误的状态对应的描述信息,用于请求类型不合法时反馈错误情况。
|
|
|
|
|
tmp.put("REQUEST", "上传请求异常"); // 设置表示在文件上传请求处理过程中出现其他未知异常的错误状态对应的描述信息,用于捕获到一般性的请求相关异常时反馈错误原因。
|
|
|
|
|
tmp.put("IO", "IO异常"); // 设置表示在文件输入输出(如读取文件、写入文件等操作)过程中出现I/O异常的错误状态对应的描述信息,用于处理文件读写等操作出现问题时反馈错误情况。
|
|
|
|
|
tmp.put("DIR", "目录创建失败"); // 设置表示在创建文件保存目录(例如根据日期创建子目录等情况)时失败的错误状态对应的描述信息,用于目录创建出现问题时反馈错误原因。
|
|
|
|
|
tmp.put("UNKNOWN", "未知错误"); // 设置表示其他未明确归类的、未知的错误情况对应的错误状态描述信息,用于捕获到意料之外的异常时进行统一的错误反馈。
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 执行文件上传的方法(处理常规表单文件上传)
|
|
|
|
|
* 该方法用于处理通过常规表单形式进行的文件上传操作,首先判断请求是否为多部分表单数据(即是否包含文件上传域),如果不是,则设置相应的错误状态(NOFILE)并返回,不进行后续的上传操作。
|
|
|
|
|
* 若是多部分表单数据,则创建DiskFileItemFactory用于配置文件上传的一些基础设置(如临时文件存储位置等),接着设置文件保存路径、创建ServletFileUpload对象并配置其相关属性(如文件大小限制、请求头编码等),
|
|
|
|
|
* 然后通过迭代器遍历请求中的文件项,对于每个非表单字段的文件项(即真正的上传文件),进行文件格式检查、生成新文件名、获取文件类型、构建文件保存路径等操作,
|
|
|
|
|
* 并将文件内容从输入流复制到输出流实现文件的保存,同时更新文件上传状态、记录文件大小等信息,若遇到文件大小超出限制、请求类型错误、文件上传异常等各种问题,则会相应地设置对应的错误状态并停止后续操作,
|
|
|
|
|
* 对于表单字段(如标题字段等)则进行相应的读取和处理(当前代码中仅处理名为 "pictitle" 的字段作为标题字段),最后若成功上传一个文件(UE中按只处理单张上传的逻辑)则直接退出循环。
|
|
|
|
|
*
|
|
|
|
|
* @throws Exception 由于文件上传过程中涉及到很多可能抛出异常的操作(如文件读写、流操作、文件上传组件相关异常等),所以统一抛出Exception,调用者需要进行相应的异常处理,根据具体的业务需求来决定如何应对不同的异常情况。
|
|
|
|
|
*/
|
|
|
|
|
public void upload() throws Exception {
|
|
|
|
|
// 判断当前请求是否为多部分表单数据(即是否包含文件上传域),通过ServletFileUpload提供的静态方法进行判断,这是进行文件上传操作的前提条件,如果不是多部分表单数据,则不能进行后续的文件上传处理。
|
|
|
|
|
boolean isMultipart = ServletFileUpload.isMultipartContent(this.request);
|
|
|
|
|
if (!isMultipart) {
|
|
|
|
|
// 如果请求不是多部分表单数据,说明没有文件上传相关内容,设置文件上传状态为 "NOFILE"(表示未包含文件上传域),然后直接返回,不再进行后续的文件上传操作流程。
|
|
|
|
|
this.state = this.errorInfo.get("NOFILE");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建一个DiskFileItemFactory对象,它用于配置文件上传过程中的一些基础设置,例如设置临时文件的存储位置等,这里后续会将其与ServletFileUpload结合使用来处理文件上传操作。
|
|
|
|
|
DiskFileItemFactory dff = new DiskFileItemFactory();
|
|
|
|
|
// 获取文件的保存路径,通过调用getFolder方法根据配置的保存路径(this.savePath)以及当前日期生成具体的保存目录路径,确保文件按照日期进行分类保存,同时也处理了目录创建等相关操作。
|
|
|
|
|
String savePath = this.getFolder(this.savePath);
|
|
|
|
|
// 设置DiskFileItemFactory的临时文件存储目录,将其指定为前面获取到的保存路径对应的File对象,这样在文件上传过程中如果需要临时存储文件(例如文件较大时分块处理等情况),会将临时文件存放在这个目录下。
|
|
|
|
|
dff.setRepository(new File(savePath));
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 创建一个ServletFileUpload对象,用于处理文件上传的具体操作,将前面配置好的DiskFileItemFactory对象传入,使其基于配置好的基础设置来进行文件上传相关的处理工作,如解析请求、获取文件项等。
|
|
|
|
|
ServletFileUpload sfu = new ServletFileUpload(dff);
|
|
|
|
|
// 设置文件上传的最大允许大小,通过将以KB为单位的maxSize乘以1024转换为字节单位,限制上传文件的大小不能超过这个设定值,若超过则会抛出SizeLimitExceededException异常进行相应的错误处理。
|
|
|
|
|
sfu.setSizeMax(this.maxSize * 1024);
|
|
|
|
|
// 设置请求头的编码格式为 "utf-8",确保在处理包含中文等特殊字符的文件名等信息时能够正确解析,避免出现乱码问题,保证文件上传过程中字符编码的一致性。
|
|
|
|
|
sfu.setHeaderEncoding("utf-8");
|
|
|
|
|
|
|
|
|
|
// 通过ServletFileUpload的getItemIterator方法获取一个FileItemIterator对象,它用于迭代请求中的文件项(包括上传的文件以及表单中的其他字段信息等),方便后续逐个进行处理。
|
|
|
|
|
FileItemIterator fii = sfu.getItemIterator(this.request);
|
|
|
|
|
while (fii.hasNext()) {
|
|
|
|
|
// 获取下一个文件项,返回的FileItemStream对象可以用于获取文件项的相关信息(如文件名、文件内容流等)以及判断是否为表单字段等操作,是处理文件上传过程中每个文件或字段的关键对象。
|
|
|
|
|
FileItemStream fis = fii.next();
|
|
|
|
|
if (!fis.isFormField()) {
|
|
|
|
|
// 如果当前文件项不是表单字段(即代表是一个真正要上传的文件),则进行以下文件上传相关的处理操作。
|
|
|
|
|
|
|
|
|
|
// 获取上传文件的原始文件名,通过截取文件名中最后一个文件分隔符(根据系统的文件分隔符来获取,通过System.getProperty("file.separator")获取系统对应的文件分隔符)之后的部分作为原始文件名,
|
|
|
|
|
// 去除了文件的路径信息,只保留文件名本身,方便后续处理和记录。
|
|
|
|
|
this.originalName = fis.getName().substring(fis.getName().lastIndexOf(System.getProperty("file.separator")) + 1);
|
|
|
|
|
// 检查文件的格式是否符合允许的文件格式列表(allowFiles),调用checkFileType方法进行检查,如果不符合则设置文件上传状态为 "TYPE"(表示不允许的文件格式),并跳过当前文件的后续上传操作,继续处理下一个文件项(如果有的话)。
|
|
|
|
|
if (!this.checkFileType(this.originalName)) {
|
|
|
|
|
this.state = this.errorInfo.get("TYPE");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成新的文件名,调用getName方法根据原始文件名生成一个带有随机数、时间戳等信息的新文件名,以保证文件名的唯一性和避免文件名冲突等问题,同时将新文件名赋值给fileName成员变量。
|
|
|
|
|
this.fileName = this.getName(this.originalName);
|
|
|
|
|
// 获取文件的类型,通过调用getFileExt方法截取文件名的后缀部分(从最后一个 "." 开始截取到末尾)作为文件类型,例如 ".jpg"、".pdf" 等,并赋值给type成员变量,方便后续记录和使用。
|
|
|
|
|
this.type = this.getFileExt(this.fileName);
|
|
|
|
|
// 构建文件的输出文件地址(即文件最终保存的路径),将保存路径(savePath)和新生成的文件名(fileName)组合起来,形成完整的文件保存路径,赋值给url成员变量,用于后续保存文件时确定保存位置。
|
|
|
|
|
this.url = savePath + "/" + this.fileName;
|
|
|
|
|
|
|
|
|
|
// 创建一个缓冲输入流(BufferedInputStream),用于读取上传文件的内容,通过调用fis.openStream方法打开文件项对应的输入流,并将其包装为缓冲输入流,提高文件读取效率,准备将文件内容读取出来进行保存操作。
|
|
|
|
|
BufferedInputStream in = new BufferedInputStream(fis.openStream());
|
|
|
|
|
// 根据前面构建的文件保存路径创建一个对应的File对象,用于表示要保存的目标文件,方便后续通过文件输出流将读取到的文件内容写入到这个文件中,完成文件的保存操作。
|
|
|
|
|
File file = new File(this.getPhysicalPath(this.url));
|
|
|
|
|
FileOutputStream out = new FileOutputStream( file );
|
|
|
|
|
// 创建一个文件输出流(FileOutputStream),用于将文件内容写入到目标文件中,将前面创建的File对象作为参数传入,初始化文件输出流对象,准备进行文件写入操作。
|
|
|
|
|
FileOutputStream out = new FileOutputStream(file);
|
|
|
|
|
// 创建一个缓冲输出流(BufferedOutputStream),将前面的文件输出流包装起来,进一步提高文件写入的效率和稳定性,通过缓冲机制优化文件输出操作,减少频繁的磁盘I/O操作次数。
|
|
|
|
|
BufferedOutputStream output = new BufferedOutputStream(out);
|
|
|
|
|
// 使用Streams工具类(来自Apache Commons FileUpload组件)的copy方法,将输入流(in,即读取的上传文件内容)中的数据复制到输出流(output,即要写入到目标文件的输出流)中,实现文件的保存操作,
|
|
|
|
|
// 最后一个参数true表示在复制完成后自动关闭输入流和输出流,释放相关资源,确保文件内容正确地从客户端上传并保存到服务器指定的位置。
|
|
|
|
|
Streams.copy(in, output, true);
|
|
|
|
|
this.state=this.errorInfo.get("SUCCESS");
|
|
|
|
|
|
|
|
|
|
// 如果文件上传成功,设置文件上传状态为 "SUCCESS"(表示成功),通过从errorInfo这个HashMap中获取对应的成功状态描述字符串来设置,告知调用者文件上传操作顺利完成。
|
|
|
|
|
this.state = this.errorInfo.get("SUCCESS");
|
|
|
|
|
// 获取并记录上传文件的大小,通过获取保存后的文件的长度(单位为字节),赋值给size成员变量,方便后续获取文件大小信息进行相关的展示或其他业务操作。
|
|
|
|
|
this.size = file.length();
|
|
|
|
|
//UE中只会处理单张上传,完成后即退出
|
|
|
|
|
|
|
|
|
|
// 在UE(UEditor,一种富文本编辑器,推测此处是针对其文件上传逻辑进行的代码编写)中按只处理单张上传的逻辑,所以一旦成功上传一个文件后,就直接退出循环,不再处理后续的文件项(如果还有的话)。
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
// 如果当前文件项是表单字段,则进行以下处理操作(当前代码中仅处理名为 "pictitle" 的字段作为标题字段,对于其他表单字段可以根据业务需求自行扩展处理逻辑)。
|
|
|
|
|
|
|
|
|
|
// 获取表单字段的名称,通过调用fis.getFieldName方法获取字段的名称,用于后续判断是否是需要处理的特定字段(如这里的 "pictitle")。
|
|
|
|
|
String fname = fis.getFieldName();
|
|
|
|
|
//只处理title,其余表单请自行处理
|
|
|
|
|
if(!fname.equals("pictitle")){
|
|
|
|
|
// 判断表单字段名称是否等于 "pictitle",如果不等于,则直接跳过当前字段,继续处理下一个文件项,因为当前代码只关注这个特定的标题字段进行处理。
|
|
|
|
|
if (!fname.equals("pictitle")) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
BufferedInputStream in = new BufferedInputStream(fis.openStream());
|
|
|
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
|
|
|
|
StringBuffer result = new StringBuffer();
|
|
|
|
|
while (reader.ready()) {
|
|
|
|
|
result.append((char)reader.read());
|
|
|
|
|
}
|
|
|
|
|
this.title = new String(result.toString().getBytes(),"utf-8");
|
|
|
|
|
reader.close();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (SizeLimitExceededException e) {
|
|
|
|
|
this.state = this.errorInfo.get("SIZE");
|
|
|
|
|
} catch (InvalidContentTypeException e) {
|
|
|
|
|
this.state = this.errorInfo.get("ENTYPE");
|
|
|
|
|
} catch (FileUploadException e) {
|
|
|
|
|
this.state = this.errorInfo.get("REQUEST");
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
this.state = this.errorInfo.get("UNKNOWN");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 接受并保存以base64格式上传的文件
|
|
|
|
|
* @param fieldName
|
|
|
|
|
*/
|
|
|
|
|
public void uploadBase64(String fieldName){
|
|
|
|
|
String savePath = this.getFolder(this.savePath);
|
|
|
|
|
String base64Data = this.request.getParameter(fieldName);
|
|
|
|
|
this.fileName = this.getName("test.png");
|
|
|
|
|
this.url = savePath + "/" + this.fileName;
|
|
|
|
|
try {
|
|
|
|
|
File outFile = new File(this.getPhysicalPath(this.url));
|
|
|
|
|
OutputStream ro = new FileOutputStream(outFile);
|
|
|
|
|
byte[] b = Base64.decodeBase64(base64Data);
|
|
|
|
|
for (int i = 0; i < b.length; ++i) {
|
|
|
|
|
if (b[i] < 0) {
|
|
|
|
|
b[i] += 256;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ro.write(b);
|
|
|
|
|
ro.flush();
|
|
|
|
|
ro.close();
|
|
|
|
|
this.state=this.errorInfo.get("SUCCESS");
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
this.state = this.errorInfo.get("IO");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 文件类型判断
|
|
|
|
|
*
|
|
|
|
|
* @param fileName
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private boolean checkFileType(String fileName) {
|
|
|
|
|
Iterator<String> type = Arrays.asList(this.allowFiles).iterator();
|
|
|
|
|
while (type.hasNext()) {
|
|
|
|
|
String ext = type.next();
|
|
|
|
|
if (fileName.toLowerCase().endsWith(ext)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取文件扩展名
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
private String getFileExt(String fileName) {
|
|
|
|
|
return fileName.substring(fileName.lastIndexOf("."));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 依据原始文件名生成新文件名
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private String getName(String fileName) {
|
|
|
|
|
Random random = new Random();
|
|
|
|
|
return this.fileName = "" + random.nextInt(10000)
|
|
|
|
|
+ System.currentTimeMillis() + this.getFileExt(fileName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据字符串创建本地目录 并按照日期建立子目录返回
|
|
|
|
|
* @param path
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private String getFolder(String path) {
|
|
|
|
|
SimpleDateFormat formater = new SimpleDateFormat("yyyyMMdd");
|
|
|
|
|
path += "/" + formater.format(new Date());
|
|
|
|
|
File dir = new File(this.getPhysicalPath(path));
|
|
|
|
|
if (!dir.exists()) {
|
|
|
|
|
try {
|
|
|
|
|
dir.mkdirs();
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
this.state = this.errorInfo.get("DIR");
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 根据传入的虚拟路径获取物理路径
|
|
|
|
|
*
|
|
|
|
|
* @param path
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private String getPhysicalPath(String path) {
|
|
|
|
|
String servletPath = this.request.getServletPath();
|
|
|
|
|
String realPath = this.request.getSession().getServletContext()
|
|
|
|
|
.getRealPath(servletPath);
|
|
|
|
|
return new File(realPath).getParent() +"/" +path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setSavePath(String savePath) {
|
|
|
|
|
this.savePath = savePath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setAllowFiles(String[] allowFiles) {
|
|
|
|
|
this.allowFiles = allowFiles;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setMaxSize(int size) {
|
|
|
|
|
this.maxSize = size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public long getSize() {
|
|
|
|
|
return this.size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getUrl() {
|
|
|
|
|
return this.url;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getFileName() {
|
|
|
|
|
return this.fileName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getState() {
|
|
|
|
|
return this.state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getTitle() {
|
|
|
|
|
return this.title;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getType() {
|
|
|
|
|
return this.type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getOriginalName() {
|
|
|
|
|
return this.originalName;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建一个缓冲输入流(BufferedInputStream),用于读取表单字段对应的输入流内容(这里假设表单字段中的内容是以流的形式传递的,例如文本信息等),通过fis.openStream方法打开输入流并包装为缓冲输入流,方便后续读取操作。
|
|
|
|
|
BufferedInputStream in = new BufferedInputStream(fis.openStream());
|
|
|
|
|
// 创建一个BufferedReader对象,将前面的缓冲输入流包装为字符流读取器,通过指定字符编码为 "utf-8"(
|