js+jstl+servlet实现文件上传、列表展示及文件下载的代码详解
文件上传
1.upload.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>insert title here</title>
</head>
<body>
<form action="upload" method="post" enctype="multipart/form-data">
侠侣称谓:<input type="text" name="cpname" placeholder="阁下名讳是?"><br>
侠士:<input type="file" name="male"><br>
巾帼:<input type="file" name="female"><br>
<input type="submit">
</form>
</body>
</html>
1.2 将表单中的input分装到一个类中,uploadinfo类,方便在后续操作表单中通过input上传的数据、文件
package com.qfedu.pojo;
public class uploadinfo {
private string idcard;
private string zheng;
private string fan;
public string getidcard() {
return idcard;
}
public void setidcard(string idcard) {
this.idcard = idcard;
}
public string getzheng() {
return zheng;
}
public void setzheng(string zheng) {
this.zheng = zheng;
}
public string getfan() {
return fan;
}
public void setfan(string fan) {
this.fan = fan;
}
}
客户端发起上传请求到达uploadservlet,处理文件
2.uploadservlet.java
@webservlet("/upload")
public class uploadservlet extends httpservlet{
//创建一个将前端上传的数据作为变量的对象,可以用通过该对象的set、get方法修改和获取上传的数据
private uploadinfo uploadinfo = new uploadinfo();
@override
protected void dopost(httpservletrequest req, httpservletresponse resp) throws servletexception, ioexception {
/*
1获取表单中的文件对象
2把文件保存在服务器的文件夹中
*/
// diskfileitemfactory用来设置临时存储目录和缓冲区大小
diskfileitemfactory dfif = new diskfileitemfactory();
//以字节为单位设置内存缓冲大小
dfif.setsizethreshold(1024*1024*5);
//设置临时存储目录,允许和最终文件保存在同一目录
file temp = new file("d:/ppt/upload");
//指定文件保存目录时,先判断该目录是否存在,不存在时需创建该目录
if (temp.exists()) {
temp.mkdir();
}
//设置临时保存目录
dfif.setrepository(temp);
// servletfileupload提供了对请求的解析,和请求大小限制的相关功能
servletfileupload sf = new servletfileupload(dfif);
//设置上传的一个文件的大小限制
sf.setfilesizemax(1024*1024*5);
//设置表单中所有input加起来的上传大小
sf.setsizemax(1024*1024*10);
try {
//解析请求,返回的是form表单中所有带有name属性的input的数据的封装对象list集合
list<fileitem> list = sf.parserequest(req);
//遍历list,获取到上传的数据
for (fileitem fileitem : list) {
//判断上传的是否是普通文本表单
if(fileitem.isformfield()) {
//是普通文本表单,则将其上传编码格式设为utf-8,解决中文乱码问题
//现在获取到的是字节,所以获取表单内容不使用getparameter
string value = fileitem.getstring("utf-8");
system.out.println(value);
//将获取到的文件名通过set方法设置给当前文件
if ("cpname".equals(fileitem.getfieldname())) {
uploadinfo.setcpname(value);
}
} else {
//获取到包括后缀的文件名
string filename = fileitem.getname();
//获取到后缀名在完整文件名中的位置
int lastindex = filename.lastindexof(".");
//获取到 “.后缀名”
string sufname = filename.substring(lastindex);
//随机生成一个不重复的文件名
string finalname = uuid.randomuuid().tostring().replace("-", "") + sufname;
//不是普通文本而是一个文件 ,这时可以执行上传,但需要判断用户是否已经选择文件
//选择文件了,将文件写入到指定文件夹中
if (filename != null && filename.length() > 0) {
//write用于把文件写入到服务器指定的文件中
fileitem.write(new file("d:/ppt/upload/" + finalname));
//获得fileitem对应的表单的name属性的值
string filedname = fileitem.getfieldname();
//将获取到的文件名通过set方法设置给当前文件
if ("male".equals(filedname)) {
uploadinfo.setmale(finalname);
}
//将获取到的文件名通过set方法设置给当前文件
if ("female".equals(filedname)) {
uploadinfo.setfemale(finalname);
}
} else {
//未选择文件,返回选择文件界面重新选择文件
resp.sendredirect("/firstupload/upload.html");
return;
}
}
}
string sql = "insert into couple values(null,?,?,?)";
arraylist<object> datas = new arraylist<object>();
datas.add(uploadinfo.getcpname());
datas.add(uploadinfo.getmale());
datas.add(uploadinfo.getfemale());
//将文件名传输到 之后在展示界面通过通过 url?文件名 方式下载文件
ddutils.update(sql, datas);
//重定向到listservlet
resp.sendredirect("/firstupload/list");
} catch (exception e) {
e.printstacktrace();
resp.sendredirect("/firstupload/error.html");
}
}
}
在uploadservlet中将从前端获取到的数据文件存放到数据库中,然后重定向到listservlet中,从数据库获取到文件并渲染到list.前端进行展示
3.listservlet.java
@webservlet("/list")
public class listservlet extends httpservlet {
@override
protected void doget(httpservletrequest req, httpservletresponse resp) throws servletexception, ioexception {
//从数据库中获取文件信息
string sql = "select * from upload";
try {
list<hashmap<string, object>> datas = ddutils.query(sql, null);
req.setattribute("datas", datas);
//转发到web-inf/list.jsp
req.getrequestdispatcher("web-inf/list.jsp").forward(req, resp);
} catch (classnotfoundexception | sqlexception e) {
e.printstacktrace();
}
}}
从listservlet中渲染数据到list.jsp进行展示
4.list.jsp
<%@ page language="java" contenttype="text/html; charset=utf-8"
pageencoding="utf-8"%>
<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core"%>
<!doctype html public "-//w3c//dtd html 4.01 transitional//en" "https://www.w3.org/tr/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>insert title here</title>
</head>
<body>
<ul>
//${datas} 获取到的datas数据集合 uploadinfo为当前对象
<c:foreach items="${datas}" var="uploadinfo">
//<a href="download?name=${uploadinfo.zheng}"> 发送请求到downloadservlet,获取对应文件
<li>${uploadinfo.idcard}|<a href="download?name=${uploadinfo.zheng}">${uploadinfo.zheng }</a>|
<a href="download?name=${uploadinfo.fan}">${uploadinfo.fan }</a></li>
</c:foreach>
</ul>
</body>
</html>
文件下载
5.downloadservlet.java
@webservlet("/download")
public class downloadservlet extends httpservlet {
@override
protected void doget(httpservletrequest req, httpservletresponse resp) throws servletexception, ioexception {
// 获取前端传入的需要下载的文件名字
string name = req.getparameter("name");
file file = new file("z:/win/files/" + name);
resp.setcontenttype("application/octet-stream");
// 设置文件名字,我们只需要修改filename=后面的文件名,其他是固定的字符串
// 文件下载的时候如果文件的名字是中文,会出现乱码
resp.setheader("content-disposition", "attachment;filename=" + urlencoder.encode(file.getname(), "utf-8"));
// 把文件转成字节输出
resp.getoutputstream().write(fileutils.readfiletobytearray(file));
}