文章目录
一、单个文件上传
1.1 页面搭建
1.1.1 jsp代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传页面</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/" enctype="multipart/form-data" method="post">
用户名:<input type="text" name="username">
上 传:<input type="file" name="file1">
<input type="submit" value="上传">
</form>
</body>
</html>
1.1.1注意:
- new一个upload.jsp作为文件上传页面,form表单必须用
method="post"
,必须加属性enctype="multipart/form-data"
- new接收请求,并处理文件的Servlet,UploadController.java
- 在Servlet上面要添加两个注解:
@WebServlet(name = "UploadController",value = "/upload")
@MultipartConfig(maxFileSize = 1024*1024*100 ,maxRequestSize = 1024*1024*200)
maxFileSize:单个文件最大的大小
maxRequestSize:在一次请求中,多个文件一共可以多大
1.1.2servlet代码2
1. 获取请求的数据
正确的代码
2. 获取上传文件的路径
3. 文件上传
1.2 代码完善
1.2.1 文件上传之唯一文件名
当上传重名的文件时,为防止文件覆盖的现象的发生,写一个utils类,定义一个NewFileName(String filename)方法为给定的的文件名
赋值一个唯一的名字
import java.util.UUID;
public class UploadUtils {
//使用UUID生成4唯一的标识码,拼接上图片的名字
public static String NewFileName(String filename){
return UUID.randomUUID().toString().replaceAll("-","")+"_"+filename;
}
}
1.2.2 文件上传细节之散列存储
为了不让所有的文件全都上传在upload目录下,每个上传的文件都会随机在upload目录下生成二级、三级目录
目录名称用数字表示,为了便于以后通过filename可以找到该文件的路径,
该二级、三级目录名称是通过filenam.hashCode();再通过与15的&运算计算得出
以后下载该文件的时候,直接调用该方法
String downPatn = UploadUtils.newFilePath(basePath, filename);
就可以通过名称获取路径
import java.io.File;
import java.util.UUID;
public class UploadUtils {
//使用UUID生成4唯一的标识码,拼接上图片的名字
public static String NewFileName(String filename) {
return UUID.randomUUID().toString().replaceAll("-", "") + "_" + filename;
}
//生成二级、三级目录
public static String NewFilePath(String basepath, String filename) {
int hashcode = filename.hashCode();
int path1 = hashcode & 15;
int path2 = (hashcode >> 4) & 15;
String newpath = basepath + "\\" + path1 + "\\" + path2;
File file = new File(newpath);
if (!file.exists()) {
file.mkdirs();
}
return newpath;
}
}
都是1则为1,0和1为0 ,0和0也为0
左移运算符(<<)
1<<4
相当于1乘以2的4次方==>16
32>>4
相当于32除以2的4次方==>2
调用这两个方法
文件上传细节之控制文件类型
完整的代码
@WebServlet(name = "UploadController", value = "/upload")
@MultipartConfig(maxFileSize = 1024 * 1024 * 100, maxRequestSize = 1024 * 1024 * 200)
public class UploadController extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置乱码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//获取请求的数据
String username = request.getParameter("username");
Part part = request.getPart("file1");
//获取上传文件的路径 真实路径
String basepath = request.getServletContext().getRealPath("/WEB-INF/upload");
File file = new File(basepath);
if (!file.exists()) {
file.mkdirs();
}
String primName = part.getSubmittedFileName();
List<String> suffixname = new ArrayList<>();
suffixname.add(".jpg");
suffixname.add(".bmp");
suffixname.add(".png");
String extName = primName.substring(primName.lastIndexOf("."));
if (!suffixname.contains(extName)) {
System.out.println("文件类型错误,请重写选择文件上传!");
return;
}
String newName = UploadUtils.NewFileName(primName);
String newPath = UploadUtils.NewFilePath(basepath, primName);
//文件上传
part.write(newPath + "\\" + newName);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
二、多个文件上传
@WebServlet(name = "MoreUpladController", value = "/moreUpload")
@MultipartConfig(maxRequestSize = 1024 * 1024 * 300, maxFileSize = 1024 * 1024 * 100)
public class MoreUpladController extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
String basePath = request.getServletContext().getRealPath("/WEB-INF/upload");
File file = new File(basePath);
if (!file.exists()) {
file.mkdirs();
}
//获取表单提交的数据
Collection<Part> parts = request.getParts();
for (Part part : parts) {
String filename = part.getSubmittedFileName();
if (filename != null) {
String newName = UploadUtils.NewFileName(filename);
String newPath = UploadUtils.NewFilePath(basePath, filename);
part.write(newPath + "\\" + newName);
} else {
String username = request.getParameter(part.getName());
System.out.println(username);
}
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
三、文件下载
既然是文件下载,就应该把上传的目录下的文件名通过table标签展现给用户看,然后再添加一个a标签,让用户下载
3.1 获取文件列表
3.1.1 FileListUtils遍历当前目录下所有内容
File类中的listFiles()方法,列出目录中的所有内容,返回一个File数组
public class FileListUtils{
public static void Filelist(File file,HashMap<>() fileMap){
File[] files = file.listFiles();
for(File f : files){
if(f.isDirectory()){
Filelist(f,fileMap)
}else{
String uuidname = f.getName();
//获取文件真实上传的名字
//由于上传时加上了uuid_filename,找到"_"的下标就可以截取出
int index = uuidname.indexof("_");
String name = uuidname.substring(index+1);
fileMap.put(uuidname,name);
}
}
}
}
3.1.2FileListController
@WebServlet(value="/fileList")
public class FileListController extends HttpServlet{
protected void doPost(HttpServletRequest request,HttpServletResponse response)throw ServletException,IOException{
request.setCharactetEncoding("utf-8");
response.setContextType("text/html;charset=utf-8);
String basePath = request.getServlentContent.getRealPath("/WEB-INF/upload");
File file = new File(basePath);
//调用FilelistUtil的fileList方法把,当前文件file路径下全部文件的uuidname和name全部以key值和value值存入hashMap
HashMap<String,String> fileMap = new HashMap<>();
FileListUtils.fileList(file,fileMap);
request.setAttribute("fileMap",fileMap);
request.getRequestDispatcher("/list.jsp").forward(request,response);
}
protected void doGet(HttpServletRequest request,HttpServletResponse response)throw ServletException,IOException{
doPost(request,response);
}
}
3.1.3 list.jsp页面代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>文件下载页面</title>
</head>
<body>
<table border="1">
<tr>
<td>文件名</td>
<td>操作</td>
</tr>
<c:forEach items="${fileMap}" var="entry">
<tr>
<td>${entry.value}</td>
<td><a href="${pageContext.request.contextPath}/downLoad?filename=${entry.key}">下载</a></td>
</tr>
</c:forEach>
</table>
</body>
</html>
3.1.4 文件下载DownLoadController
@WebServlet(value="/downLoad")
public class DownLoadController extends HttpServlet(){
protected void doPost(HttpServletRequest request,HttpServletResponse response)throw ServletException,IOException{
//list.jsp页面传来的是uuidname
String filename = request.getParameter("filename");
String basePath = request.getServletContent.getRealPath("/WEB-INF/upload");
//以"_"分割uuid_name为数组{uuid,name}
String realName = filename.spilt("_")[1];
String newPath = UploadUtils.newFilePath(basePath,realName);
//设置
response.setHeader("content-disposition","attachment;filename="+URLEncoder.encode(filename,"utf-8"));
FileInputStream fis = new FileInputStream(newPath+"\\"+filename);
ServletOutputStream sos = response.getOutputStream();
byte[] buffer = new byte[1024*1024*100];
int len = 0;
while((len=fis.read(buffer))!=-1){
sos.write(buffer,0,len);
}
fis.close();
sos.close();
}
protected void doGet(HttpServletRequest request,HttpServletResponse response) throw ServletException,IOException{
doPost(request,response);
}
}