分析
1.上传条件(3个):
1.1 表单的请求方式必须是 post
1.2 表单提交的类型 enctype=”multipart/form-data”
1.3 上传控件 file类型 必须得写name属性:
<input type="file" name="filename"/>
2.处理上传:第三方库
2.1 添加jar(2个) commons-fileupload-xx.jar commons-io-xx.jar
2.2 上传步骤代码:
2.2.1 创建配置类 DiskFileItemFactory
a.配置临时目录new File();
b.配置临时目录大小,默认10KB, C:\User\Administer\AppData\Local\Temp\
2.2.2 创建上传的核心类ServletFileUpload
常用:setProgressListener();设置进度
参数1:当前上传的字节数 参数2:总的字节数
2.2.3 解析请求 parseRequest(request); 返回值List<FileItem>
2.2.4 遍历取出每一项FileItem
2.2.5 判断类型 isFormFiled()
成立,普通表单: fileItem.getFiledName(); fileItem.getString("utf-8");
不成立,上传项 :fileItem.write();
3.上传的注意事项:
3.1 文件名的获取: fileItem.getName(); 不同浏览器取到的结果不一样。
字符串截取
3.2 放置文件名重复覆盖内容: 处理文件名(唯一)
System.currentMillons()+filename;
UUID.randomUUID()+“_”+filename;
3.3 打散目录:
3.3.1 直接在跟目录下存储
//创建目录
File file=new File(“C:\\img”);
if(!file.exists()){
file.mkDirs();
}
//创建文件
File file2=new File(file,filename)
3.3.2 按照日期打散目录
long time = System.currentMillons;
SimpleDateFomat format =new SimpleDateFomat("yyyy-MM-dd");
String date = format.format(new Date(time));
//创建目录
File file=new File(“C:\\img”,date);
if(!file.exists()){
file.mkDirs();
}
//创建文件
File file2=new File(file,filename);
3.3.3 按照hashcode值打散目录
int code= filename.hashCode;
String code1 = Integer.toHexString(code);
String dir = code1.charAt(0)+"\\"+code1.charAt(1);
//创建目录
File file=new File(“C:\\img”,dir);
if(!file.exists()){
file.mkDirs();
}
//创建文件
File file2=new File(file,filename)
4.上传功能及图片展示:
add.jsp AddShopServlet 处理的数据类型: Map<String,String> key:表单项的name value:表单项的值
展示:网络地址:
tomcat的虚拟目录:
server.xml中Host下添加如下话语:(配置当前使用tomcat) conf/server.xml backup/server.xml
Eclipse: servers/server.xml
docBase:磁盘的真实目录(该目录必须是存在) path:虚拟目录(映射在tomca服务器上的地址)
<Context path="/img01" docBase="c:\img"></Context>
访问的路径是:http://localhost:8080/img01/具体资源
代码实现:
FileUtils.java:
package com.qf.utils;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import org.apache.commons.fileupload.FileItem;
public class FileUtils {
/**
*
* @param diskPath磁盘路径
* @return 网络访问路径
*
*/
public static String getNetPath(String diskPath) {
int index1 = diskPath.indexOf("img");
String basePath= "http://localhost:8080/img01/"+diskPath.substring(index1+4).replace("\\", "/") ;
System.out.println(basePath);
return basePath;
}
// 获取上传的文件名称
public static String getFileName(FileItem fileItem) {
// 在不同浏览器取值结果不一样(name有的是只有名称,有的是连带的路径的名称)
String name = fileItem.getName();
System.out.println("name" + name);
String filename = name.substring(name.lastIndexOf("\\") + 1);
System.out.println("filename= " + filename);
return filename;
}
//保证文件名称唯一性
public static String getFileNameByHashCode(FileItem fileItem) {
String filename = getFileName(fileItem);
// 方式一:使用时间戳区分:
// filename =System.currentTimeMillis()+filename;
// 方式二: 使用UUID区分:
filename = UUID.randomUUID() + "_" + filename;
return filename;
}
// 方式一:默认
/**
* @param fileItem
* 上传项
* @return 返回的是上传要写入的文件目录
*/
public static File test1(FileItem fileItem) {
File file = new File("C:\\img");
if (!file.exists()) {
// mkdirs:创建多级目录,即使父目录不存在也能创建成功
// mkdir:只能单级目录,而且要求是必须父目录存在
file.mkdirs();
}
// 创建文件
File file2 = new File(file, getFileNameByHashCode(fileItem));
return file2;
}
// 方式二:保证名称的唯一性
public static File test2(FileItem fileItem) {
File file = new File("C:\\img");
if (!file.exists()) {
// mkdirs:创建多级目录,即使父目录不存在也能创建成功
// mkdir:只能单级目录,而且要求是必须父目录存在
file.mkdirs();
}
// 创建文件
File file2 = new File(file, getFileNameByHashCode(fileItem));
return file2;
}
// 方式三:文件目录进行变化
// 1.按照日期存储(按照日期打散文件)
public static File test3(FileItem fileItem) {
long time = System.currentTimeMillis();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String date = format.format(new Date(time));
System.out.println("date" + date);
// 目录
File file = new File("C:\\img", date);
if (!file.exists()) {
// mkdirs:创建多级目录,即使父目录不存在也能创建成功
// mkdir:只能单级目录,而且要求是必须父目录存在
file.mkdirs();
}
// 创建文件
File file2 = new File(file, getFileNameByHashCode(fileItem));
return file2;
}
// 2.按照hashcode随机值存储(按照hashcode打散文件)
public static File test4(FileItem fileItem) {
String filename =getFileNameByHashCode(fileItem);
// 获取文件名称hashcode值
int code = filename.hashCode();
System.out.println("==code=" + code);
// 把int类型的值转化成16进制的字符串
String code1 = Integer.toHexString(code);
System.out.println("==code1=" + code1);
String dir = code1.charAt(0) + "\\" + code1.charAt(1);
// 目录
File file = new File("C:\\img", dir);
if (!file.exists()) {
// mkdirs:创建多级目录,即使父目录不存在也能创建成功
// mkdir:只能单级目录,而且要求是必须父目录存在
file.mkdirs();
}
// 创建文件
File file2 = new File(file, filename);
return file2;
}
}
UploadUtils.java:
package com.qf.utils;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
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;
public class UploadUtils {
public static Map<String, String> getRequestData(HttpServletRequest request) {
Map<String, String> map = new HashMap();
if (!ServletFileUpload.isMultipartContent(request)) {
return null;
}
// 1.配置DiskFileItemFactory
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(new File("c:\\"));
// 2.创建上传核心类
ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
// 3.解析请求
try {
List<FileItem> fileItems = servletFileUpload.parseRequest(request);
for (FileItem fileItem : fileItems) {
// 判断表单类型
if (fileItem.isFormField()) {
// 普通表单
String name = fileItem.getFieldName();
String value = fileItem.getString("utf-8");
map.put(name, value);
} else {
// 上传项
File file = FileUtils.test4(fileItem);
String netPath = FileUtils.getNetPath(file.getAbsolutePath());
System.out.println("netPath=" + netPath);
map.put("imgurl", netPath);
fileItem.write(file);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return map;
}
}
AddShopServlet.java:
package com.qf.web.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
import com.mysql.jdbc.UpdatableResultSet;
import com.qf.domain.Shop;
import com.qf.service.ShopService;
import com.qf.service.impl.ShopServiceImpl;
import com.qf.utils.UploadUtils;
public class AddShopServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Map<String, String> map = UploadUtils.getRequestData(request);
Shop shop = new Shop();
try {
BeanUtils .populate(shop, map);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(shop.getName());
shop.setId(UUID.randomUUID().toString());
ShopService ss = new ShopServiceImpl();
try {
ss.addProducts(shop);
//添加成功
//添加完数据 应该走查询servlet
request.getRequestDispatcher("queryAllShopListServlet").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
//添加失败的话 返回到添加页面
request.getRequestDispatcher("admin/products/add.jsp").forward(request, response);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
修改三个地方的server.xml
地方
1.eclipse的server.xml
2.tomcat下的conf目录的server.xml
3.tomcat下的backup目录的server.xml(有的可能没有,没有就配前两个就行)
如何配?
修改server.xml 加上这句话:
<Context path="/img01" docBase="c:\img"></Context>