Jsp+Servlet 来实现文件上传
在日常的开发中,为了提高开发的效率,我们通常使用组件和框架来进行开发。
一般使用 FileUpload / Smartupload 组件
二、SmartUpload 上传组件
SmartUpload 上传组件使用简单,可以轻松的实现上传文件类型的限制,也可以
轻易的取得上传文件的名称、后缀、大小等。
导入 lib 包
上传单个文件
要想进行上传,必须使用 HTML 中的 file 控件,且必须使用 enctype 进行
分装,表示将表单按照二进制的方式提交。即所有的操作表单此时不再是分别提
交,而是将所有内容都按照二进制的方式提交。
<form action="smartUploadServlet.do" method="post" enctype="multipart/form-data">
<input type="file" name="myfile" />
<input type="submit" value="上传" />
</form>
SmartUploadServlet:
public class SmartUploadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//设置上传文件保存路径
String filePath = getServletContext().getRealPath("/") + "upload";
File file = new File(filePath);
if (!file.exists()) {
file.mkdir();
}
//实例化上传组件
SmartUpload su = new SmartUpload();
//初始化 SmartUpload
su.initialize(getServletConfig(), req, resp);
//设置上传文件对象 10M
su.setMaxFileSize(1024*1024*10);
//设置所有文件大小 100M
su.setTotalMaxFileSize(1024*1024*100);
//设置允许上传文件类型
su.setAllowedFilesList("txt,jpg,gif,png");
String result = "上传成功!";
try {
//设置禁止上传文件类型
su.setDeniedFilesList("rar,jsp,js");
//上传文件
su.upload();
//保存文件
su.save(filePath);
} catch (Exception e) {
result = "上传失败!";
e.printStackTrace();
}
req.setAttribute("smartResult", result);
req.getRequestDispatcher("index.jsp").forward(req, resp);
}
}
配置 web.xml
<servlet>
<servlet-name>SmartUploadServlet</servlet-name>
<servlet-class>com.meng.servlet.SmartUploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SmartUploadServlet</servlet-name>
<url-pattern>/smartUploadServlet.do</url-pattern>
</servlet-mapping>
混合表单
如 果 要 上 传 文 件 , 表 单 则 必 须 封 装 。 但 是 当 一 个 表 单 使 用 了
enctype=“multipart/form-data”
封装后,其他的非表单控件的
内容就无法通过 request 内置对象取得,此时必须通过 SmartUpload 类中提供的
getRequest()方法取得全部的请求参数。
<form action="" method="post" enctype="multipart/form-data">
<input type="text" name="name" />
<input type="file" name="pic" />
<input type="submit" value="上传" />
</form>
表单接收方:
SmartUpload smart = new SmartUpload();
smart.initialize(getServletConfig(), req, resp);
smart.upload();
String name = smart.getRequest().getParameter("name"); //接收请求参数
smart.save(filePath);
现在是通过 SmartUpload 完成参数接收的,所以 smart.getRequest()方法一定要
在执行完 upload()方法后才可以使用。
为上传文件自动命名
如果多个用户上传的文件名一样,则会发生覆盖的情况。为了解决这个问题,我
们来为上传文件自动命名。
自动命名可以采用如下格式:
IP 地址+时间戳+三位随机数
定义取得 IP 时间戳的操作类:
package com.meng.util;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
public class IPTimeStamp {
// 定义 SimpleDateFormat 对象
private SimpleDateFormat sdf = null;
// 接收 ip 地址
private String ip = null;
public IPTimeStamp() {
}
public IPTimeStamp(String ip) {
this.ip = ip;
}
/**
* 获得 IP+时间戳+三位随机数
* @return
*/
public String getIPTimeRand() {
StringBuffer buffer = new StringBuffer();
if (this.ip != null) {
String[] s = this.ip.split("\\"); // 进行拆分操作
for (int i = 0; i < s.length; i++) {
buffer.append(this.addZero(s[i], 3)); // 不够三维数字的要补
零
}
}
buffer.append(this.getTimeStamp());
Random r = new Random();
for (int i = 0; i < 3; i++) {
buffer.append(r.nextInt(10));
}
return buffer.toString();
}
/**
* 补 0 操作
* @param str * @param len
* @return
*/
private String addZero(String str, int len) {
StringBuffer s = new StringBuffer();
s.append(str);
while (s.length() < len) {
s.insert(0, "0");
}
return s.toString();
}
/**
* 取得当前系统时间
* @return
*/
public String getDate() {
this.sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
return this.sdf.format(new Date());
}
/**
* 取得时间戳
* @return
*/
public String getTimeStamp() {
this.sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
return this.sdf.format(new Date());
}
}
通过 SmartUpload 获得上传文件的信息
//获取上传的文件
com.jspsmart.upload.File tempFile = su.getFiles().getFile(0);
//获取上传文件的表单当中的 name 值
tempFile.getFieldName();
//获取上传的文件名
tempFile.getFileName();
//获取上传文件的大小
tempFile.getSize();
//获取上传文件的后缀名
tempFile.getFileExt();
//获取上传文件的全名
tempFile.getFilePathName();
批量上传
批量上传很简单,只需修改前台页面中的代码即可。
<form action="smartUploadServlet.do" method="post"
enctype="multipart/form-data">
选择图片:
<input type="file" id="myfile1" name="myfile1">
<input type="file" id="myfile2" name="myfile2">
<input type="file" id="myfile3" name="myfile3">
<input type="submit" value="上传">${smartResult}
</form>
SmartUpload 实现下载
下载:<a href="smartDownloadServlet.do?filename=0.png">下载文件</a>
SmartDownloadServlet:
public class SmartDownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String filename = req.getParameter("filename");
SmartUpload su = new SmartUpload();
su.initialize(getServletConfig(), req, resp);
// 设置响应类型
su.setContentDisposition(null);
try {
su.downloadFile("/upload/" + filename);
} catch (SmartUploadException e) {
e.printStackTrace();
}
}
}
SmartUpload 实现批量下载
一般的操作方式为,将多个文件打包成一个压缩包文件进行下载。
<h2>SmartUpload 批量下载</h2>
<form action="batchDownloadServlet.do" method="post">
<input type="checkbox" id="myfile2" name="filename" value="06.jpg">06.jpg
<input type="checkbox" id="myfile2" name="filename" value="07.jpg">07.jpg
<input type="checkbox" id="myfile3" name="filename" value="10.jpg">10.jpg
<input type="submit" value="下载">
</form>
BatchDownloadServlet
public class BatchDownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("application/x-msdownload");
response.setHeader("Content-disposition", "attachment;
filename=test.rar");
String path = getServletContext().getRealPath("/") + "upload/";
String[] filenames = req.getParameterValues("filename");
ZipOutputStream zos = new
ZipOutputStream(resp.getOutputStream());
for (String filename : filenames) {
File file = new File(path + filename);
zos.putNextEntry(new ZipEntry(filename));
FileInputStream fis = new FileInputStream(file);
byte[] b = new byte[1024];
int n = 0;
while ((n = fis.read(b)) != -1) {
zos.write(b, 0, n);
}
zos.flush();
fis.close();
}
zos.setComment("描述信息");
zos.flush();
zos.close();
}
}
web.xml 配置
<servlet>
<servlet-name>BatchDownloadServlet</servlet-name>
<servlet-class>com.meng.servlet.BatchDownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BatchDownloadServlet</servlet-name>
<url-pattern>/batchDownloadServlet.do</url-pattern>
</servlet-mapping>