1 基本上传
在HTML元素input里面有一个file类型。
<input type="file">
那么当文件选择完成之后则应该随着表单一起提交到服务器上,那么此时的服务器可以采用二进制的方式进行内容的接收,但是这样的接收处理的难度太大了,所以为了简化这样的操作,往往会在进行上传的时候使用一些第三方的组件,常见的组件有两种:SmartUpload组件、FileUpload组件。
但是如果你现在并没有使用框架进行开发,那么强烈不建议使用FileUpload组件,推荐使用SmartUpload组件。SmartUpload组件是以一个*.jar
文件的形式出现的,所以在项目里面如果要使用这个组件就需要将*.jar
文件拷贝到WEB-INF/lib目录下。
如果要想使用SmartUpload组件开发那么需要注意以下的几个问题:
(1)要进行文件上传的表单必须进行封装;
<form action="upload.jsp" method="post" enctype="multipart/form-data">
选择文件: <input type="file" name="file" id="file">
<input type="submit" value="submit">
</form>
(2)随后在接收上传的页面里面按照如下的步骤操作:
|————第一步:实例化SmartUpload类对象;
|————第二步:初始化上传环境;
|————第三步:接收所有的上传数据;
|————第四步:进行文件保存。
范例:定义upload.jsp文件
<%
//第一步:实例化SmartUpload类对象;
SmartUpload smart = new SmartUpload();
//第二步:初始化上传环境;
smart.initialize(config, request, response);
//第三步:接收所有的上传数据;
smart.upload();
//第四步:进行文件保存。
smart.save(getServletContext().getRealPath("/") + "/upload");
%>
这个时候就可以很轻松的实现文件的上传操作了,但是上传之后的保存在upload目录下的文件名称就是原始的图片名称。
2 上传加强
使用save()
方法保存上传文件的时候会使用文件的原始名称进行保存,这样一来就有可能发生文件覆盖的情况,所以在任何的上传操作过程之中,绝对不会直接使用原始文件名称进行保存,所以需要针对于上传的文件进行重命名。
实际上最稳妥的命名方式就是使用IP+时间戳+三位随机数
。但是这样做太麻烦了,所以在java.util包里面提供有一个UUID的类,这个类就是根据时间戳生成一个几乎不会重复的名称。
public static void main(String[] args) {
UUID uuid = UUID.randomUUID();
System.out.println(uuid.toString());
}
如果只是存在有文件名称根本就不能够进行开发操作,还需要知道文件的后缀,那么这些信息要想取得就必须通过SmartUpload取得。这个类定义有如下的方法:
(1)取得所有的上传文件对象:public SmartFiles getFiles()
;
当取得了SmartFiles类对象后可以进行如下的操作:
(1)取得上传文件的个数:public int getCount()
;
(2)取得上传文件的大小:public long getSize()
;
(3)根据索引取得每一个上传文件:public SmartFile getFile(int index)
;
//取得上传文件个数
int count = smart.getFiles().getCount();
//取得上传文件大小
long size = smart.getFiles().getSize();
通过代码的演示可以发现,getSize()方法可以判断是否有文件上传。如果有上传,返回的数据是大于0的。
取得的SmartFile表示每一个上传文件,也就是说每一个上传文件的信息都在这个对象里面保存了。此类中的方法如下:
(1)取得上传文件的MIME类型:public String getContentType()
;
(2)取得上传文件的大小:public int getSize()
;
(3)取得上传文件的扩展名:public String getFileExt()
;
for(int i = 0; i < smart.getFiles().getCount(); i++){
%>
<h2><%=smart.getFiles().getFile(i).getFileExt() %>、<%=smart.getFiles().getFile(i).getContentType() %>、<%=smart.getFiles().getFile(i).getSize() %></h2>
<%
}
%>
那么通过此过程就应该清楚了,如果在日后进行文件上传的时候允许传递的只能够是图片信息。
在SmartFile类里面提供有一个文件保存的操作功能:public void saveAs(String path)
;
范例:批量上传
//存储文件
if(smart.getFiles().getSize() > 0){
for(int i = 0; i < smart.getFiles().getCount(); i++){
if(smart.getFiles().getFile(i).getContentType().contains("image") && smart.getFiles().getFile(i).getSize() > 0){
String fileName = UUID.randomUUID().toString() + "." + smart.getFiles().getFile(i).getFileExt();
String filePath = getServletContext().getRealPath("/") + java.io.File.separator +"upload" + java.io.File.separator + fileName;
smart.getFiles().getFile(i).saveAs(filePath);
}
}
}
以后只要是上传操作其结构都一样,但是一定要记住了,如果你现在只有一个文件上传。
3 混合表单
以上的所有代码所完成的只是进行了文件的上传,但是在很多时候一个表单进行操作的过程之中往往还可能提交有其它的附属信息。一旦表单封装了,那么request.getParameter()
、request.getParameterValues()
、request.getParameterNames()
三个方法就无效了。
范例:定义表单
<form action="upload.jsp" method="post" enctype="multipart/form-data">
学生姓名: <input type="text" name="name" id="name"><br>
学生照片: <input type="file" name="file" id="file"><br>
<input type="submit" value="submit">
<input type="reset" value="reset">
</form>
此时由于表单在上传的过程之中进行了封装,所有的数据不会再以文本的形式传递了,都是以二进制数据流的形式完成的,所以来讲request的三个接收参数的方法就无效了,为此在SmartUpload类里面提供有一个支持的方法:
(1)取得SmartRequest对象:public SmartRequest getRequest()
;这个方法一定要在接收完成后使用。
在SmartRequest对象里面模拟了request对象的操作提供有三个方法:
(1)取得单个参数:public String getParameter(String param)
;
(1)取得一组参数:public String[] getParameterValues(String param)
;
(1)取得所有参数名称:public Enumeration getParameterNames()
;
范例:改善页面,实现预览
<html>
<head>
<meta charset="UTF-8">
<title>Upload</title>
<style type="text/css">
#preview, .img, img{
width: 200px;
height: 200px;
}
#preview{
border: 1px solid #000;
}
</style>
<script type="text/javascript">
function preview(file){
var prevDiv = document.getElementById("preview");
if(file.files && file.files[0]){
var reader = new FileReader();
reader.onload = function(evt){
prevDiv.innerHTML = '<img src="' + evt.target.result + '" />';
}
reader.readAsDataURL(file.files[0]);
}else{
prevDiv.innerHTML = '<div class="img" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src=\'' + file.value + '\'"><div>';
}
}
</script>
</head>
<body>
<form action="upload.jsp" method="post" enctype="multipart/form-data">
学生姓名: <input type="text" name="name" id="name"><br>
学生照片: <input type="file" name="file" id="file" onchange="preview(this)"><div id="preview"></div><br>
<input type="submit" value="submit">
<input type="reset" value="reset">
</form>
</body>
</html>
以后编写上传也会采用同样的预览方式完成的。