一、上传对表单的要求
1) 表单的提交方式 :"method=post"
2) 表单的类型 :enctype="multipart/form-data"
3) 上传表单的文件项:<input type="file" name="xx" /> //其中名字是必须要的
例如: <h1>上传</h1>
<h2><font color="red"></font></h2>
<form action="" method="post" enctype="multipart/form-data"/>
<p>用户名:<input name="userName" type="text"/></p>
<p>文件:<input name="xx" type="file"/></br></p>
<p><input type="submit" value="上传"/></p>
</form>
二、 使用servlet时:多部件表单上传对servlet取值问题
1) request.getParameter("..."),这个方法在表单为multiparty/form-data中取不到值
2) 但是我们可以使用 ServletInputStream request.getInputStream();来获取流信息
三、 多部件表单与普通表单的结构
1) 普通表单项结构 1个头:content-Disposition,包含name="XXX" 即表单的名字, 表单体就是表单的值
2) 多部件表单普通表单结构 含有2个头
*content-Disposition,包含name="xx",filname="上传文件的路径";
*content-type: 指上传的文件类型,如上传的是图片的话格式则为:image/jpeg
四、上传的组件(这里介绍2种)
1、使用apache-commons-fileupload 上传*使用apache-commons-fileupload 上传
*使用springmvc下的spring-webmvc (MultipartFile )上传
1) commons-fileupload
*需要的jar(网上可以下载)
commons-fileupload
要使用流所以需要commons-io.jar;
2)上传三步
*工厂:DiskFileItemFactory
*解析器:ServletFileUpload
*表单项:FileItem
3)相关代码
*创建工厂
DiskFileItemFactory fac = new DiskFileItemFactory();
*创建解析器
ServletFileUpLoad sfp = new ServletFileUpLoad(fac);
*使用解析器 获取FileItem 集合 List<FileItem> items = sfp.parseRequest(reques);
*看下 FileItem的方法
String filename = file.getName(); //文件名称
String getFileName(); //返回当前表单项的名称
String fileStr = file.getString(String charset); //返回表单的值;
long fileSize = file.getSize(); //文件的字节数
InputStream in = file.getInputStream(); //文件的对应输入流
void write(file destFile); //将文件保存到指定的目录
代码例子:
request.setCharacterEncoding("utf-8"); //编码
//创建工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//创建解析器
ServletFileUpload sfl = new ServletFileUpload(factory);
try {
//解析
List<FileItem> im = sfl.parseRequest(request);
FileItem f1 = im.get(0);
System.out.println("多部件表单项的文件:"+f1.getFieldName()
+"---名称:"+f1.getName()+"文件大小:"+f1.getSize());
try {
//写往磁盘(也可以写到服务器的相应地址)
f1.write(new File("e:\\photo\\cc.jpg"));
} catch (Exception e) {
e.printStackTrace();
}
} catch (FileUploadException e) {
e.printStackTrace();
}
-------------------------------------------
五、上传的细节2、使用MultipartFile
1) 由于Post一个包含文件上传的Form会以multipart/form-data请求发送给服务 器,必须明确告诉转发器(DispatcherServlet)如何处理MultipartRequest。首先在项目 配 置文件中声明一个MultipartResolver:
2) xml 代码
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为1MB(也可以不配置而在代码中限制上传的文件大小) -->
<property name="maxUploadSize">
<value>1048576</value>
</property>
</bean>
3)、上传步骤
*请求转化为多部件的请求
MultipartHttpServletRequest mulReq= (MultipartHttpServletRequest) request;
*获取
MultipartFile mfile= mulReq.getFile(“多部件表单值的name”);
*写入到相应的目录
mfile.transferTo(new File(path));
4)、代码例子:
//转化request
MultipartHttpServletRequest mulReq= (MultipartHttpServletRequest) request;
//获取上传表单的name值
String picName = request.getParameter(“picName”);
//解析为多部件文件
MultipartFile mfile = mulReq.getFile(picName);
//仅仅允许图片格式
List<String> fileTypes = new ArrayList<String>();
fileTypes.add("jpg");
fileTypes.add("jpeg");
fileTypes.add("bmp");
fileTypes.add("gif");
fileTypes.add("png");
//取得原文件名称
String orifilename = mfile.getOriginalFilename();
//获取扩展名
String extensionName=orifilename.substring(orifilename.lastIndexOf(".")+1);
//校验扩展名
if ( fileTypes.contains(extensionName.toLowerCase())) {
//限制图片的大小
if(file.getSize() <= 5 * 1024*1024){
mfile.transferTo(new File(path));
}
}
--------------------------------------------
1、文件保存在项目的路径
*文件保存可以在web-inf下(安全问题)其他目录下可能被注入非法程序)
*上传的文件保存webRoot下(因为很多其他的项目都可能要用到上传的文件)
2、上传文件格式和大小:
*要求上传的文件格式为jpg,就不能上传其他格式
上传的时候就必须要限制上传的文件类型,最好的做法是在前端和后台都做下校验。
*上传文件的大小需要按要求做限制
3、文件名称问题:
*上传文件出现重名,所以需要我们为文件加个前缀,前缀不能重复。可以是uuid (UUID uuid = UUID.randomUUID();)或者时间(System.currentTimeMillis())
*上传文件乱码问题
可以使用这个request.setCharacterEncoding("utf-8");
4、文件目录
目录打撒 一个目录下不能存放太多的文件,不同的上传功能目录应该归类存放。
5、缓存大小与临时目录(主要针对大文件上传的)。
Common-FileUpload 中可以设置缓存大小和临时目录(默认是10k)
方法:DiskFileItemFactory(int sizeThreshold, File repository)
sizeThreshold为定义的缓存大小,repository为缓存目录
如 DiskFileItemFactory fa = new DiskFileItemFactory(2*1024, new File(“F:/temp”));