首页 > 代码库 > java web(四)文件上传与下载
java web(四)文件上传与下载
一、文件上传原理
1、在TCP/IP中,最早出现的文件上传机制是FTP ,它是将文件由客户端发送到服务器的标准机制;但是在jsp使用过程中不能使用FTP方法上传文件,这是由jsp运行机制所决定。
通过为表单元素设置 method="post" enctype="multipart/form-data" 属性 ,让表单提交的数据以二进制编码的方式提交,在接受此请求的Servlet中用二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传。
2、表单enctype属相
1>application/x-www-form-urlencoded
默认编码方式,只处理表单域里的value属性值,采用这种编码方式的表单域中的值处理成URL编码方式。
2>multipart/form-data
这种编码方式的表单会以二进制流的方式处理表单数据, 这种编码方式会把文件域指定的文件内容也封装到请求参数中。
3>text/plain
这种方式主要适用于直接通过表单发送邮件的方式。
二、SmartUpload上传组件的使用
SmartUpload组件使用简单,可以轻松的实现上传文件类型的限制,也可以轻易地取得上传文件的名称、后缀、大小。 使用该组件需要导入jar包,我用的是 jspsmartupload.jar。
1、上传单个文件
upload.htm
<html>
<head>
<title>文件上传</title>
</head>
<body>
<form action="upload.jsp" method="post" enctype="multipart/form-data">
请选择文件:<input type="file" name="pic">
<input type="submit" value="http://www.mamicode.com/上传">
</form>
</body>
</html>
upload.jsp
<%@ page contentType="text/html" pageEncoding="utf-8"%>
<%@ page import="com.jspsmart.upload.*"%>
<html>
<head>
<title>文件上传2</title>
</head>
<body>
<%
SmartUpload smart=new SmartUpload();
smart.initialize(pageContext);
smart.upload();
smart.save("upload");
%>
</body>
</html>
这里要注意在jsp页面引入导入jar包中的类文件:上面是com.jspsmart.upload.*,为什么这样写,可以用360压缩打开jar包文件如下:
upload表示上传文件的保存文件夹,该文件夹要在跟目录手动建立。上传结果如下:
2、混合表单
如果要上传文件,表单必须封装,但是表单使用了enctype 封装后其他非文件类的表单控件无法通过request内置对象取得,此时必须通过SmartUpload类的getRequest()方法取得全部请求参数。
upload2.htm
<html>
<head>
<title>文件上传</title>
</head>
<body>
<form action="upload2.jsp" method="post" enctype="multipart/form-data">
姓名:<input type="text" name="uname"><br>
照片:<input type="file" name="pic"><br>
<input type="submit" value="http://www.mamicode.com/上传">
<input type="reset" value="http://www.mamicode.com/重置">
</form>
</body>
</html>
upload2.jsp
<%@ page contentType="text/html" pageEncoding="utf-8"%>
<%@ page import="com.jspsmart.upload.*"%>
<html>
<head>
<title>文件上传2</title>
</head>
<body>
<%
SmartUpload smart=new SmartUpload(); //实例化SmartUpload上传组件
smart.initialize(pageContext); //初始化上传操作
smart.upload(); //上传准备
String name=smart.getRequest().getParameter("uname"); //接受请求参数
smart.save("upload"); //将上传文件保存在upload文件夹中
%>
<h2>姓名:<%=name%></h2>
<h2>request=:<%=request.getParameter("uname")%></h2>
</body>
</html>
3、为上传文件自动命名
主要为了防止重名情况下发生覆盖文件。以下例子中文件命名采用 IP地址+时间戳+三位随机数
upload3.htm
<html>
<head>
<title>文件上传</title>
</head>
<body>
<form action="upload3.jsp" method="post" enctype="multipart/form-data">
姓名:<input type="text" name="uname"><br>
照片:<input type="file" name="pic"><br>
<input type="submit" value="http://www.mamicode.com/上传">
<input type="reset" value="http://www.mamicode.com/重置">
</form>
</body>
</html>
upload3.jsp
<%@ page contentType="text/html" pageEncoding="utf-8"%>
<%@ page import="com.jspsmart.upload.*"%>
<%@ page import="kk.upload3.IPTimeStamp"%>
<html>
<head>
<title>文件上传3</title>
</head>
<body>
<%
request.setCharacterEncoding("utf-8");
//实例化SmartUpload上传组件
SmartUpload smart=new SmartUpload();
//初始化上传操作
smart.initialize(pageContext);
//上传准备
smart.upload();
//接受请求参数
String name=smart.getRequest().getParameter("uname");
IPTimeStamp its=new IPTimeStamp(request.getRemoteAddr());
//取得文件后缀名
String ext=smart.getFiles().getFile(0).getFileExt();
//拼凑文件名称
String fileName=its.getIPTimeRand()+"."+ext;
System.out.println("文件名称及后缀==>"+fileName);
//保存文件
smart.getFiles().getFile(0).saveAs(getServletContext().getRealPath("/")
+"upload"+java.io.File.separator+fileName);
//./表示当前目录;../表示源文件所在目录的上一级目录;../../表示源文件所在目录的上上级目录,以此类推
%>
<%=getServletContext().getRealPath("/")+"upload"+java.io.File.separator+fileName %>
<h2>姓名:<%=name%></h2>
<img src="http://www.mamicode.com/upload/">
</body>
</html>
IPTimeStamp.java
package kk.upload3;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
public class IPTimeStamp{
private SimpleDateFormat sdf=null;
private String ip=null;
public IPTimeStamp(){
}
public IPTimeStamp(String ip){
this.ip=ip;
//System.out.println("ip="+ip);
}
//得到IP地址+时间戳+三位随机数
public String getIPTimeRand(){
StringBuffer buf=new StringBuffer();
if(this.ip!=null){
/*
* 进行拆分操作
* 在java中 \代表转义字符 \n \t 等,而 \\ 代表一个反斜杠 而.代表一个元字符
* 要表示一个.就需要用 要用\.
* 所以"\\." 在实际编译中 就代表 .
* */
String s[]=this.ip.split("\\.");
for(int i=0;i<s.length;i++){
//不够三位数字补0
buf.append(this.addZero(s[i],3));
}
}
//取得时间戳
buf.append(this.getTimeStamp());
Random r=new Random();
for(int i=0;i<3;i++){
buf.append(r.nextInt(10));
}
System.out.println("文件前缀==>"+buf.toString());
return buf.toString();
}
private String addZero(String str,int len){
StringBuffer s=new StringBuffer();
s.append(str);
while(s.length()<len){
s.insert(0,"0");
}
//System.out.println(s);
return s.toString();
}
public String getDate(){
this.sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
return this.sdf.format(new Date());
}
public String getTimeStamp(){
this.sdf=new SimpleDateFormat("yyyyMMddHHmmssSSS");
return this.sdf.format(new Date());
}
}
运行结果:
问题:限制文件上传类型?
比如验证上传文件后缀的合法性:
//表示只允许后缀为jpg/gif的文件上传。
if(smart.getFiles().getFile(0).getFileName().matches("^\\w+\\.(jpg|gif)$")){
}
4、批量上传
对upload3.jsp文件进行如下更改,其他的都不用改变,
<%@ page contentType="text/html" pageEncoding="utf-8"%>
<%@ page import="com.jspsmart.upload.*"%>
<%@ page import="kk.upload3.IPTimeStamp"%>
<html>
<head>
<title>文件上传3</title>
</head>
<body>
<%
request.setCharacterEncoding("utf-8");
SmartUpload smart=new SmartUpload();
smart.initialize(pageContext);
smart.upload();
String name=smart.getRequest().getParameter("uname");
IPTimeStamp its=new IPTimeStamp(request.getRemoteAddr());
for(int x=0;x<smart.getFiles().getCount();x++){
String ext=smart.getFiles().getFile(x).getFileExt();
String fileName=its.getIPTimeRand()+"."+ext;
smart.getFiles().getFile(x).saveAs(getServletContext().getRealPath("/")
+"upload"+java.io.File.separator+fileName);
}
%>
</body>
</html>
获得上传文件数量:smart.getFiles().getCount()。
三、FileUpload上传组件的使用
java web(四)文件上传与下载