前言
表单上传文件是最基本的上传文件方式,虽然现在有很多优秀的上传插件,如:webuploader、uploadify等,但我们还是说一下表单上传。
具体内容
1.jsp页面form表单
<form name="myform" action="<%=path%>/upload" method="post" enctype="multipart/form-data">
<input type="text" name="userName" value="" />
<input type="text" name="age" value="" />
<input type="file" name="userFile" />
<input type="submit" value="提交" />
</form>
- action便是要提交到java的路径,利用submit提交即可,当然也可以这么写,首先给form起名
name="myform"
,然后利用button按钮点击事件onClick="doSearch()"
方法提交,js代码如下
function doSearch(){
document.myform.action=path + "/upload";
document.myform.target="_self";
document.myform.submit();
}
- enctype属性
1、application/x-www-form-urlencoded:这是默认编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的值处理成url编码方式。
2、multipart/form-data:这种编码方式的表单会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定的文件内容也封装到请求参数里。
3、text/plain:这种方式主要适用于直接通过表单发送邮件的方式。
2.后端java处理上传文件的架包有3种:
- commons-fileupload上传组件
- COS上传组件
- SmartUpload组件
我们只将讲commons-fileupload上传组件,这个组件需要架包commons-fileupload-1.3.3.jar和commons-io-2.5.jar,java代码如下
// 判断enctype属性是否为multipart/form-data
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
DiskFileItemFactory factory = new DiskFileItemFactory();
// 当上传文件太大时,因为虚拟机能使用的内存是有限的,所以此时要通过临时文件来实现上传文件的保存
// 此方法是设置是否使用临时文件的临界值(单位:字节)
factory.setSizeThreshold(1024*1024);//1M
// 与上一个结合使用,设置临时文件的路径(绝对路径)
factory.setRepository(new File(request.getSession().getServletContext().getRealPath("")));
Map<String,Object> map =new HashMap<String,Object>();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(1024*1024);// 设置上传内容的大小限制(单位:字节)
List<?> items = upload.parseRequest(request);
Iterator<?> iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {//如果是普通表单字段
String name = item.getFieldName();
String value = item.getString();
map.put(name, value);
} else { //如果是文件字段
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();//可以用来判断文件大小
if (fileName!=null) {
File fullFile=new File(item.getName());
File savedFile=new File(request.getSession().getServletContext().getRealPath(""),fullFile.getName());
item.write(savedFile);
} else {
InputStream uploadedStream = item.getInputStream();
uploadedStream.close();
}
}
}
从代码中可以看出代码循环了表单元素,利用item.isFormField()判断是否是普通字段,普通字段放到了Map里,文件利用架包上传,上传地址为 request.getSession().getServletContext().getRealPath("")
这个是获取项目绝对路径,这个路径不是新建项目时workspace里项目路径,而是项目编译后的路径,可以打印看一下。
结语
如果只是上传文件而没有其它元素也可以通过字节流实现文件上传,如下:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
java.io.InputStream in= request.getInputStream();
java.io.FileOutputStream out= new java.io.FileOutputStream("d:\\out.txt");
byte[] buffer = new byte[8192];
int count = 0;
while((count = in.read(buffer)) >0){
out.write(buffer, 0, count);
}
out.close();
}