一、文件的上传和下载原理
1、文件上传的原理分析
1.1文件上传的必要前提:
a、提供form表单,method必须是post
b、form表单的enctype必须是multipart/form-data
c、提供input type="file"类的上传输入域
1.2enctype属性
作用:告知服务器请求正文的MIME类型。(请求消息头:Content-Type作用是一致的)可选值:
1、application/x-www-form-urlencoded(默认):
正文:name=admin&password=123
服务器获取数据:String name = request.getParameter(“name”);
2、multipart/form-data:
正文:
服务器获取数据:request.getParameter(String)方法获取指定的表单字段字符内容,但文件上传表单已经不在是字符内容,而是字节内容,所以失效。
2、借助第三方的上传组件实现文件上传
2.1 fileupload概述
fileupload是由apache的commons组件提供的上传组件。它最主要的工作就是帮我们解析request.getInputStream()。
导入commons-fileupload相关jar包
1、commons-fileupload.jar,核心包;
2、commons-io.jar,依赖包。
2.2 fileupload的核心类有:
DiskFileItemFactory、ServletFileUpload、FileItem。
a、解析原理
2.3 fileupload简单应用
使用fileupload组件的步骤如下:
1.创建工厂类DiskFileItemFactory对象:
DiskFileItemFactory factory = new DiskFileItemFactory()
2.使用工厂创建解析器对象:
ServletFileUpload fileUpload = new ServletFileUpload(factory)
3.使用解析器来解析request对象:
List list = fileUpload.parseRequest(request)
FileItem对象对应一个表单项(表单字段)。可以是文件字段或普通字段。
1、boolean isFormField():判断当前表单字段是否为普通文本字段,如果返回false,说明是文件字段;
2、String getFieldName():获取字段名称,例如:,返回的是username;
3、String getString():获取字段的内容,如果是文件字段,那么获取的是文件内容,当然上传的文件必须是文本文件;
4、String getName():获取文件字段的文件名称;(a.txt)
5、String getContentType():获取上传的文件的MIME类型,例如:text/plain。
6、int getSize():获取上传文件的大小;
7、InputStream getInputStream():获取上传文件对应的输入流;
8、void write(File):把上传的文件保存到指定文件中。
9、delete();
二、代码
1、页面代码。
注:form表单里面加上参数 enctype=“multipart/form-data”。js的作用是添加选择文件按钮,删除选择文件按钮。
图示:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script language="JavaScript" type="text/javascript">
var webtype=".$webType";
var merchantUrl="";
var contextPath="${contextPath}";
function addFile() {
var div1 = document.getElementById("div1");
div1.innerHTML +="<div>\n" +
" <input type=\"file\" name=\"demandDoc\"/><input type=\"button\" value=\"删除\" οnclick=\"delFile(this)\"/>\n" +
" </div>"
}
function delFile(input) {
input.parentNode.parentNode.removeChild(input.parentNode);
}
</script>
</head>
<body>
<form id="form" name="form" action="${contextPath}/DemandFileInfoServlet" method="post" enctype="multipart/form-data">
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="showlist">
<tbody>
<div>
<input type="hidden" name="employeeId" id="employeeId" value="$!employeeId"/>
标题:<input type="text" name="title" id="title" value="$!demand.title"/><br/><br/>
描述:<textarea name="des" value="$!demand.des" id="des" rows="10" cols="50"></textarea>
</div><br/>
<div id="div1">
添加附件:
<div>
<input type="file" name="demandDoc"/><input type="button" value="添加" οnclick="addFile()"/><br>
</div>
</div>
</tbody>
</table>
</form>
</body>
</html>
2、java代码
@WebServlet(urlPatterns = "/DemandFileInfoServlet")
public class DemandFileInfoServlet extends HttpServlet {
@Autowired
private DemandService demandService;
@Autowired
private SerialGeneratorMgr serialGeneratorMgr;
@Autowired
private DemandRecordService demandRecordService;
@Autowired
private DemandRecordAccessoryService demandRecordAccessoryService;
HashMap<String, Object> result = new HashMap<>();
Demand demand = new Demand();
String demandRecordId;
private static final Logger logger = LoggerFactory.getLogger(DemandFileInfoServlet2.class);
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().print("suc");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String isUpLoadComplete = "suc";
if (demandService == null) {
demandService = SpringContextLoaderListener.getSpringWebApplicationContext().getBean(DemandService.class);
}
//判断是否可以上传文件格式
boolean isMultipartContent = ServletFileUpload.isMultipartContent(req);
if (!isMultipartContent) {
throw new TimeCardServiceException("your form is not multipart/form-data");
}
//创建一个DiskFileItemfactory工厂类
DiskFileItemFactory factory = new DiskFileItemFactory();
//创建一个ServletFileUpload
ServletFileUpload sfu = new ServletFileUpload(factory);
//解析一个request对象,并得到一个表单的集合
List<FileItem> fileItems = null;
try {
fileItems = sfu.parseRequest(req);
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) {
//普通表单项
processFromField(fileItem);
} else {
//上传表单项
processUplodField(fileItem);
}
}
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String putDate = sdf.format(date);
demand.setPutDate(putDate);
demand.setUpdateTime(putDate);
demand.setStatus("0");
if (serialGeneratorMgr == null) {
serialGeneratorMgr = SpringContextLoaderListener.getSpringWebApplicationContext().getBean(SerialGeneratorMgr.class);
}
String demandId = serialGeneratorMgr.getSerialKey(Constants.DEMAND_SERIAL); //自动生成Id
demand.setId(demandId);
demandService.insertSelective(demand);
//向需求修改明细表中插入数据
DemandRecord demandRecord = new DemandRecord();
demandRecord.setId(demandRecordId);
demandRecord.setDemandId(demandId);
demandRecord.setSuffixStatus("0");
demandRecord.setDes(demand.getDes());
demandRecord.setUpdateTime(putDate);
demandRecord.setUpdateEmployeeId(demand.getEmployeeId());
if (demandRecordService == null) {
demandRecordService = SpringContextLoaderListener.getSpringWebApplicationContext().getBean(DemandRecordService.class);
}
demandRecordService.insertSelective(demandRecord);
demandRecordId = null;
} catch (Exception e) {
isUpLoadComplete = "fail";
logger.error("{}", e);
} finally {
req.getSession().setAttribute("upLopublishassessmentadComplated", isUpLoadComplete);
resp.getWriter().print("<script>parent.location.href = \"demand/demand_list.jhtml\"</script>");
}
}
//上传表单
private void processUplodField(FileItem fileItem) {
String fileName = fileItem.getName(); //文件项的值 a.txt
fileName = UUID.randomUUID() + "_" + fileName;
try {
logger.info("开始上传文件........");
System.out.println("开始上传文件........");
//获得文件输入流
InputStream is = fileItem.getInputStream();
//获取文件存储路径
SysParamsDAO sysParamsDAO = SpringContextLoaderListener.getSpringWebApplicationContext().getBean(SysParamsDAO.class);
// SysParams sysParams = sysParamsDAO.selectByPrimaryKey("FilePathForDemand");
SysParams sysParams = sysParamsDAO.selectByPrimaryKey("FilePath");
String storeDirectory = sysParams.getValue(); // storeDirectory:/opt/timecard/demandForAttachment
//如果不存在"/opt/timecard/demandForAttachment"路径,则创建这个路径
File file2 = new File(storeDirectory);
if (!file2.isDirectory() && !file2.exists()) {
file2.mkdir(); //创建单层目录
}
//在storeDirectory下,创建完整的文件目录
File file = new File(storeDirectory, fileName);
String allDirectory = storeDirectory + "/" + fileName;
DemandRecordAccessory demandRecordAccessory = new DemandRecordAccessory();
if (serialGeneratorMgr == null) {
serialGeneratorMgr = SpringContextLoaderListener.getSpringWebApplicationContext().getBean(SerialGeneratorMgr.class);
}
if (StringUtils.isBlank(demandRecordId)) {
demandRecordId = serialGeneratorMgr.getSerialKey(Constants.DEMAND_RECORD_SERIAL);
}
demandRecordAccessory.setDemandRecordId(demandRecordId);
demandRecordAccessory.setAccessory(allDirectory);
if (demandRecordAccessoryService == null) {
demandRecordAccessoryService = SpringContextLoaderListener.getSpringWebApplicationContext().getBean(DemandRecordAccessoryService.class);
}
demandRecordAccessoryService.insertSelective(demandRecordAccessory);
//通过文件输出流将上传的文件保存到磁盘
FileOutputStream fos = new FileOutputStream(file);
int len = 0;
byte[] b = new byte[1024];
while ((len = is.read(b)) != -1) {
fos.write(b, 0, len);
}
fos.close();
is.close();
logger.info("上传文件完成........");
System.out.println("上传文件完成........");
} catch (Exception e) {
logger.error("{}", e);
e.printStackTrace();
}
}
//普通表单
private void processFromField(FileItem fileItem) throws UnsupportedEncodingException {
String fieldName = fileItem.getFieldName(); //字段名
String fieldValue = fileItem.getString("UTF-8"); //字段值
if ("employeeId".equals(fieldName)) {
demand.setEmployeeId(fieldValue);
}
if ("title".equals(fieldName)) {
demand.setTitle(fieldValue);
}
if ("des".equals(fieldName)) {
demand.setDes(fieldValue);
}
}
}