之前使用Java处理文件上传需要引用各种库,但在servlet3.0之后java提供了文件上传对象,使用更加简单。
这里提供一个Servlet版本对照:
文件上传API
HttpServletRequest 提供了两个方法用于从请求中解析上传的文件:
Part getPart(String name): 用于获取请求中指定name的文件
Coolection< Part > getParts();获取请求中全部的文件
每一个文件用 javax.servlet.http.Part 对象来表示,该接口提供了很多处理文件的方法
Part API
方法 | 描述 | 返回值 |
---|---|---|
write(String fileName) | 将文件内容写入指定的磁盘位置 | void |
getSize() | 获取上传文件的大小 | long |
getName() | 获取file控件的name属性 | String |
getHeader(String name) | 获取指定请求头 | String |
getHeaderNames() | 获取所有请求头的名称 | String |
getHeaders(String name) | 获取指定header名称的集合数据 | Collection< String > |
getContentType() | 获取文件MIME类型 | String |
getInputStream() | 获取输入流用于检索文件的内容 | InputStream |
delete() | 删除Part数据和临时目录数据,默认会删除 | void |
getSubmittedFileName() | 获取上传文件名Servlet3.1 Tomcat8.0实现 | String |
结合 HttpServletRequest 对象和@MultipartConfig 注解来处理文件上传.
指定缓存大小和临时目录
@MutipartConfig 可以设置 相应参数限制条件,必须声明,否则会报错
参数 | 类型 | 概述 |
---|---|---|
location | String | 指定上传文件的临时目录,默认为"",绝对路径 |
fileSizeThreshold | int | 指定缓存大小,超过会先存入临时目录,默认0 |
maxFileSize | long | 单个上传文件最大大小,默认是-1,表示没有限制,单位:bytes |
maxRequestSize | long | 限制该multipart/form-data请求中数据的大小,默认是-1,表示没有限制,单位:bytes |
FileSize表示上传的单个文件的大小,RequestSize表示一次上传的总的数据量,所以可以在一个表单中一次上传多个文件。
普通表单上传
- enctype 需使用 multipart/form-data类型
- method 需要使用 post 方法提交
- 需要使用 file 控件
html页面
<form action="servlet/TestFileUpLoad" enctype="multipart/form-data" method="post">
<input type="file" accept="" id="upfile" name="upfile">
<input type="submit" value="提交">
</form>
servlet页面
@MultipartConfig(location="D:/", fileSizeThreshold=1024*102,maxFileSize=1024*1024*5, maxRequestSize=1024*1024*5*5)
public class TestFileUpLoad extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
JSONObject jsonReply =new JSONObject();
try {
String fileName=UUID.randomUUID().toString()+".jpg";//名字避免重复使用uuid+后缀
Part part=request.getPart("upfile");
part.write(fileName);
String fileRealName=part.getSubmittedFileName();
jsonReply.put("fileName", fileRealName);
jsonReply.put("success", "ok");
} catch (Exception e) {
e.printStackTrace();
jsonReply.put("error", "error");
}
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
PrintWriter out=response.getWriter();
out.write(jsonReply.toString());
out.close();
}
}
Ajax表单上传
使用jquery的ajax方法实现异步上传
html页面
<input type="file" accept="" id="upfile" name="upfile">
<input type="button" value="提交" onclick="upFile()">
<script type="text/javascript">
function upFile(){
var upfile=$("#upfile")[0].files[0];
var myForm = new FormData();//必须使用FormData表达上传数据
myForm.append("upfile",upfile);
$.ajax({
method:"post",
url:"servlet/TestFileUpLoad",
data:myForm,
processData: false,//禁止类型转换//必须false才会避开jQuery对 formdata 的默认处理
contentType: false,//必须false才会自动加上正确的Content-Type
dataType:"json",
success:function(data){
console.log(data);
},
error:function(err){
console.log("error:"+err);
}
});
}
</script>
servlet页面
@MultipartConfig(maxFileSize=1024*1024*5, maxRequestSize=1024*1024*5*5)
public class TestFileUpLoad extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
JSONObject jsonReply =new JSONObject();
try {
Part part=request.getPart("upfile");
//获取文件后缀名,即文件类型
String realFileName=part.getSubmittedFileName();
String type=realFileName.substring(realFileName.lastIndexOf("."));
String fileName=UUID.randomUUID().toString()+type;
//获取项目下的该文件夹路径,必须先创建文件夹
String path=getServletContext().getRealPath("/file/")+fileName;
part.write(path);
jsonReply.put("fileType", type);
jsonReply.put("success", "ok");
} catch (Exception e) {
e.printStackTrace();
jsonReply.put("error", "error");
}
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
PrintWriter out=response.getWriter();
out.write(jsonReply.toString());
out.close();
}
}
在后台代码做一点改进,文件目录可能在本地测试和服务器有差别,需要动态获取,文件名也需要动态获取,以便增加代码可用性