(1)前期准备
首先导入jar包,需要jar包的支持
(2)上传部分
在控制层(Servlet)中分为四步
1.创建FileItemFactory工厂
FileItemFactory factory = new DiskFileItemFactory();
2.创建文件上传组件
ServletFileUpload upload = new ServletFileUpload(factory);
*因为上传的图片名可能有中文,在正式上传时要先处理一下照片名中文乱码的问题
upload.setHeaderEncoding("utf-8");//解决中文乱码(上传文件名称有中文的情况下)的问题在实现上传之前
*在上传之前可以添加判断图片的大小
//设置文件的上传大小,超过的话在上传时会抛出异常,
// 在处理异常时结束方法,并返回错误信息在视图层
upload.setSizeMax(6*16*1024);//设置多张图片的总的大小
upload.setFileSizeMax(16*1024);//设置单张图片的大小
3.实现上传并对表单项进行封装(表单中的各个数据都会被封装到FileItem对象中)
List<FileItem> itemList = null;
try {
itemList = upload.parseRequest(request);//解析请求
} catch (FileUploadException e) {
e.printStackTrace();
//处理文件超过设定了大小
request.setAttribute("error","文件大小不能超过16kb");
request.getRequestDispatcher("/add.jsp").forward(request,response);
return;
}
4.遍历集合,对每个表单项进行处理
*对于file表单项和普通的表单项要进行不同的处理
**注意的是普通表单项中 type = “text” 的 value 属性有中文的情况下要注意中文乱码的问题
**FileItem中获取表单项的各种方法
/*System.out.println(item.isFormField()); //是否是file表单项 是file false 不是file true
System.out.println(item.getFieldName());//表单项的name属性的值
System.out.println(item.getString());//对于非file表单项,value属性的值;对于file表单项,是文件内容
System.out.println(item.getName());//对于file表单项,上传文件的名称;对于非file表单项,返回null
System.out.println(item.getContentType());//对于file表单项,上传文件mime类型 ;对于非file表单项,返回null
System.out.println(item.getSize());//对于file表单项,上传文件的大小 ;对于非file表单项,value值的宽度*/
//4.遍历集合,对每个表单项进行处理
String name = null;
int age = 0;
double score = 0.0;
String contentType = null;
String fileName = null;
String photoName = null;
for(int i = 0;i<itemList.size();i++){
//对file表单项和普通表单项进行不同的处理
FileItem item = itemList.get(i);//一个fileItem中封装了一个表单项
if(item.isFormField()){//为true时为普通表单项
//根据各个表单的value值
if("name".equals(item.getFieldName())){
name = item.getString("utf-8");//解决value中的中文乱码问题
}
if("age".equals(item.getFieldName())){
age = Integer.parseInt(item.getString());
}
if("score".equals(item.getFieldName())){
score = Double.parseDouble(item.getString());
}
}else{//为false是file表单
//如果file表单项有多个的话,需要根据name属性来做专门的赋值
if("photo".equals(item.getFieldName())){
//限制文件的类型
contentType = item.getContentType();
if(!"image/jpeg".equals(contentType)&&!"image/gif".equals(contentType)){
request.setAttribute("error","照片格式只能是jpg和gif格式!");
request.getRequestDispatcher("/add.jsp").forward(request,response);
return;
}
File dir = new File("d:/upload");
if(!dir.exists()){
dir.mkdirs();
}
fileName = item.getName();
//解决上传图片名称相同的问题
UUID uuid = UUID.randomUUID();
String sphotoName = uuid.toString();
//加上扩展名
String xeml = fileName.substring(fileName.lastIndexOf("."));
photoName = sphotoName+xeml;
File file = new File(dir,photoName);
try {
item.write(file);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
**上面就已经获取form表单中的各个表单项的值,就可以进行封装到对象中,然后调用业务层进行添加数据库的操作了
(2)下载部分
**在下载中的控制层中没有转发和重定向,是通过IO流的文件复制就可以实现下载,分为三步完成
1.创建一个输入流和输出流
File file = new File("d:/upload",stu.getPhotoName());//找到在服务器下的照片
resp.setContentLength((int)file.length());//告诉浏览器文件的长度
resp.setContentType(stu.getPhotoType());//告诉浏览器文件的类型
String realName = stu.getRealName();//从数据库中获取到的照片的真实名称,在作为附件下载时使用
String userAgent = req.getHeader("User-Agent").toLowerCase();//浏览器的信息
//解决下载附件名称中文乱码的问题
if(userAgent.indexOf("mozilla")>=0){
realName = URLEncoder.encode(realName, "utf-8");
}else{
realName = new String(realName.getBytes("utf-8"),"iso-8859-1");
}
resp.setHeader("Content-disposition","attachment;filename="+realName);//设置头信息作为附件下载,文件名为什么
InputStream is = new FileInputStream(file);//从服务器中读取文件
OutputStream os = resp.getOutputStream();//通过响应写到客户端浏览器
2.使用一个输入流和输出流完成复制
**导入的包是
import org.apache.commons.io.IOUtils;
IOUtils.copy(is,os);
3.关闭流
is.close();
os.close();