JavaWeb-文件上传案例
使用fileupload组件完成文件的上传应用
1)需求:
Ⅰ。上传
> 在upload.jsp页面上使用jQuery实现"新增一个附件",”删除附件“,但至少需要保留一个。
> 对文件的扩展名和文件的大小进行验证,以下的规则是可配置的,而不是写死在程序中的
>>文件的扩展名必须为.pptx,docx,doc
>>每个文件的大小不能超过1M
>>总的文件大小不能超过5M
> 若验证失败,则在upload.jsp页面上显示错误信息:
>> 若某一个文件不符合要求:xxx文件扩展名不合法或xxx文件大小超过1M
>> 总的文件大小不能超过5M
> 若验证通过,则进行文件的上传操作
>>文件上传,并给一个不能和其他文件重复的名字,但扩展名不变
>>在对应的数据表中添加一条记录
id file_name file_path file_desc
jsp页面:
<%--
Created by IntelliJ IDEA.
User: dell
Date: 2019/7/22
Time: 10:19
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="/jQuery/jquery-3.4.0.min.js"></script>
<script type="text/javascript">
$(function () {
var i =2;
$("#addFile").click(function () {
$(this).parent().parent().before("<tr class='file'><td>File"
+ i +":</td><td><input type='file' name='file"
+ i +"'></td></tr><tr class='desc'><td>Desc"
+ i +":</td><td><input type='text' name='desc"
+ i +"'><input type='button' id='delete"
+ i +"' value='删除'></input></td></tr>");
i++;
//获取删除按钮
$("#delete" + (i-1)).click(function () {
var $tr = $(this).parent().parent();
$tr.prev("tr").remove();
$tr.remove();
//对i重新排序
$(".file").each(function (index) {
var n = index +1;
$(this).find("td:first").text("File" + n);
$(this).find("td:last input").attr("name","file"+n);
})
$(".desc").each(function (index) {
var n = index +1;
$(this).find("td:first").text("Desc" + n);
$(this).find("td:last input").attr("name","desc"+n);
})
i--;
});
});
})
</script>
</head>
<body>
<font color="red">${msg }</font>
<br><br>
<form action="/FileUploadServlet" method="post" enctype="multipart/form-data">
<input type="hidden" id="fileNum" name="fileNum" value="1">
<table>
<tr class="file">
<td>File1:</td>
<td><input type="file" name="file1"></td>
</tr>
<tr class="desc">
<td>Desc1:</td>
<td><input type="text" name="desc1"></td>
</tr>
<tr>
<td><input type="submit" id="submit" value="提交"></td>
<td><input type="button" id="addFile" value="新增一个附件"></td>
</tr>
</table>
</form>
</body>
</html>
配置文件:
exts=pptx,docx,doc file.max.size=1048576 total.file.max.size=5242880
配置文件实例化的类
package entity;
import java.util.HashMap;
import java.util.Map;
public class FileUploadAppProperties {
private Map<String,String> properties = new HashMap<>();
private FileUploadAppProperties(){}
private static FileUploadAppProperties instance = new FileUploadAppProperties();
public static FileUploadAppProperties getInstance(){
return instance;
}
public void addProperties(String propertyName,String propertyValue){
properties.put(propertyName,propertyValue);
}
public String getProperty(String propertyName){
return properties.get(propertyName);
}
}
监听:
package listener;
import entity.FileUploadAppProperties;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;
public class FileUploadAppListener implements ServletContextListener {
public FileUploadAppListener() {
}
@Override
public void contextInitialized(ServletContextEvent sce) {
InputStream in = getClass().getClassLoader().getResourceAsStream("WEB-INF/upload.properties");
Properties properties = new Properties();
try {
properties.load(in);
for (Map.Entry<Object,Object> prop: properties.entrySet()
) {
String propertyName = (String) prop.getKey();
String propertyValue = (String) prop.getValue();
FileUploadAppProperties.getInstance().addProperties(propertyName,propertyValue);
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
Servlet
package servlet;
import entity.FileUploadAppProperties;
import entity.FileUploadBean;
import exception.InvalidExtNameException;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;
public class FileUploadServlet extends HttpServlet {
private static final String FILE_PATH = "/WEB-INF/files/";
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path = null;
ServletFileUpload upload = getServletFileUpload();
try {
//把需要上传的FileItem都放入到该Map中
//键:文件的待存放的路径,值:对应的FileItem对象
Map<String,FileItem> uploadFiles = new HashMap<String,FileItem>();
//解析请求,得到FileItem的集合
List<FileItem> items = upload.parseRequest(req);
//1.构建FileUploadBean的集合,同时填充uploadFiles
List<FileUploadBean> beans = buildFileUploadBeans(items,uploadFiles);
//2.校验扩展名
vaidateExtName(beans);
//3.校验文件的大小:在解析时,已经校验了,我们只需要通过异常得到结果
//4.进行文件的上传操作
upload(uploadFiles);
//5.把上传的信息保存到数据库中
saveBeans(beans);
path = "/upload/success.jsp";
} catch (Exception e) {
e.printStackTrace();
path = "/upload/upload.jsp";
req.setAttribute("msg",e.getMessage());
}
req.getRequestDispatcher(path).forward(req,resp);
}
private ServletFileUpload getServletFileUpload() {
String exts = FileUploadAppProperties.getInstance().getProperty("exts");
String fileMaxSize = FileUploadAppProperties.getInstance().getProperty("file.max.size");
String totalFileMaxSize = FileUploadAppProperties.getInstance().getProperty("total.file.max.size");
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024 * 500);
File tempDirectory = new File("d:\\tempDirectory");
factory.setRepository(tempDirectory);
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setSizeMax(Integer.parseInt(totalFileMaxSize));
upload.setFileSizeMax(Integer.parseInt(fileMaxSize));
return upload;
}
private void saveBeans(List<FileUploadBean> beans) {
}
/**
* 校验扩展名是否合法
* @param beans
*/
private void vaidateExtName(List<FileUploadBean> beans) {
String exts = FileUploadAppProperties.getInstance().getProperty("exts");
List<String> extList = Arrays.asList(exts.split(","));
for (FileUploadBean bean : beans
) {
String fileName = bean.getFileName();
String extName = fileName.substring(fileName.lastIndexOf(".")+1);
if (!extList.contains(extName)){
throw new InvalidExtNameException(fileName + "扩展名不合法");
}
}
}
/**
* 利用传入的FileItem的集合,构建FileUploadBean的集合,同时填充uploadFiles
* FileUploadBean对象封装了:id,fileName,file'P'ath,fileDesc
* uploadFiles:Map<String,FileItem>类型,存放文件域类型的FileItem。键:待保存的文件的名字,值:FileItem对象
* 构建过程:
* 1.遍历FileItem的集合,得到desc的Map<String,string>,键:desc的fieldName(desc1,desc2...),
*
* 2.遍历FileItem的集合,得到文件域额那些FileItem对象,构建对应的key(desc1...)来获取其desc,构建的FileUploadBean对象,并填充beans和uploadFiles。
* @param items
* @param uploadFiles
* @return
*/
private List<FileUploadBean> buildFileUploadBeans(List<FileItem> items, Map<String, FileItem> uploadFiles) {
List<FileUploadBean> beans = new ArrayList<>();
//1.遍历FileItem的集合,先得到desc的Map<String,string>,其中键:fieldName(desc1,desc2...),
//值表单域对应字段的值
Map<String,String> descs = new HashMap<>();
for (FileItem item : items
) {
if (item.isFormField())
descs.put(item.getFieldName(),item.getString());
}
//2.遍历FileItem的集合,得到文件域的FileItem对象
//每得到一个FileItem对象都创建一个FileUploadBean对象
//得到fileName,构建filePath,从1的Map中得到当前FileItem对应的那个desc。
//使用fileName后面的数字去匹配
for (FileItem item : items
) {
if (!item.isFormField()){
String fieldName = item.getFieldName();
String index = fieldName.substring(fieldName.length()-1);
String fileName = item.getName();
String desc = descs.get("desc" + index);
String filePath = getFilePath(fileName);
FileUploadBean bean = new FileUploadBean(fileName,filePath,desc);
beans.add(bean);
uploadFiles.put(filePath,item);
}
}
return beans;
}
/**
* 根据指定的文件名构建一个随机的文件名
* 1.构建的文件的文件名的扩展名和给定的文件的扩展名一致
* 2.利用ServletContext的getRealPath方法获取的绝对路径
* 3.利用Random和当前的系统时间构建随机的文件的名字
* @param fileName
* @return
*/
private String getFilePath(String fileName) {
String extName = fileName.substring(fileName.lastIndexOf("."));
Random random = new Random();
int randomNumber = random.nextInt(100000);
String filePath = getServletContext().getRealPath(FILE_PATH)+"\\" + System.currentTimeMillis()+ randomNumber + extName;
return filePath;
}
/**
* 文件上传前的准备工作,得到filePath和InputStream
* @param uploadFiles
* @throws IOException
*/
private void upload(Map<String, FileItem> uploadFiles) throws IOException {
for (Map.Entry<String,FileItem> uploadFile : uploadFiles.entrySet()
) {
String filePath = uploadFile.getKey();
FileItem item = uploadFile.getValue();
upload(filePath,item.getInputStream());
}
}
/**
* 文件上传的io方法
* @param filePath
* @param inputStream
* @throws IOException
*/
private void upload(String filePath, InputStream inputStream) throws IOException {
OutputStream out = new FileOutputStream(filePath);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inputStream.read(buffer))!=-1){
out.write(buffer,0,len);
}
inputStream.close();
out.close();
}
}
异常:
package exception;
public class InvalidExtNameException extends RuntimeException {
public InvalidExtNameException(String msg){
super(msg);
}
}

浙公网安备 33010602011771号