1、实现上传准备工作
表单设置如下属性:
a、method=post
b、提供file组件 <input type="file" />
c、设置form表单属性为:entype="multipart/form-data"如果这个属性不设置,文件自身无法传递给servlet
上传目的:
1、
将客户端的图片传递给服务端,在服务端建立一个文件,文件中存放着客户端图片的内容
2、将表单中的数据放入DB中一份
2、分析上传协议格式
没有设置enctype属性时HTTP协议格式
POST /TestUpload/ServetDemo01 http/1.1
请求头
请求头
请求头
username=tom
password=1234
userhead=111.bmp
设置enctype属性时HTTP协议格式
POST /TestUpload/ServetDemo01 http/1.1
请求头
请求头
请求头
Content-Type: multipart/form-data; boundary=---------------------------54581570913334
Content-Length: 9659
-----------------------------54581570913334
Content-Disposition: form-data; name="username"
11
-----------------------------54581570913334
Content-Disposition: form-data; name="password"
11
-----------------------------54581570913334
Content-Disposition: form-data; name="userhead"; filename="11.bmp"
Content-Type: image/bmp
BM6$图片的二进制乱码数据
BM6$图片的二进制乱码数据
BM6$图片的二进制乱码数据
BM6$图片的二进制乱码数据
BM6$图片的二进制乱码数据
BM6$图片的二进制乱码数据
BM6$图片的二进制乱码数据
-----------------------------54581570913334--
3、测试:
a、servlet的API使用:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(Thread.currentThread().getId()+ ""+this);
//由于request.parameterName();这类API获取的是1_请求路径后的键值对的数据2_请求正文部分键值对的数据
//由于我们设置了表单的enctype属性,如果以POST方式传递数据时,请求体中的内容格式发生了变化,传统的API无法获取数据
//System.out.println(request.getParameter("username"));
//System.out.println(request.getParameter("password"));
//System.out.println(request.getParameter("userhead"));
//通过request获取输入流
InputStream is = request.getInputStream();
//打印输入流中的内容
int i=is.read();
while(i!=-1){
System.out.print((char)i);
i=is.read();
}
}
结论:
1_用传统的方式无法获取表单参数
2_通过request获取到一个输入流,通过打印输入流可以获取到请求体中的数据
理论上可以实现手动上传
b、工具类
1_导入jar包,commons-fileupload.jar commons-io.jar
2_实现简单3行代码,获取到一个集合,集合存放着FileItem对象FileItem每对分割线中间的内容
DiskFileItemFactory fac=new DiskFileItemFactory();
ServletFileUpload upload=new ServletFileUpload(fac);
try {
List<FileItem> list = upload.parseRequest(request);
}catch(){
}
3_判断FilteIte对象是普通项,还是上传项4_如果FileItem是普通项,将对应数据放入到Map{“username”<==>”tom”,”password”<===>”1234”}
5_如果是上传项在服务端创建一个文件 11.bmp(此时文件中没有内容)通过FilteItem获取到输入流,将输入流中的内容输出到文件中向Map中放入以下数据 “pimage”<===>”服务端新创建文件路径”6_将MAP中的数据赋值给一个Product对象{“username”<==>”tom”,”password”<===>”1234”,”pimage”<==>”图片路径”}7_调用业务层功能,将Product对象上的数据保存在DB中8_向客户端响应上传成功提示消息
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1_导入jar包,commons-fileupload.jar commons-io.jar
//2_实现简单3行代码,获取到一个集合,集合存放着FileItem对象//FileItem每对分割线中间的内容
DiskFileItemFactory fac=new DiskFileItemFactory();
ServletFileUpload upload=new ServletFileUpload(fac);
Map<String,String> map=new HashMap<String,String>();
try {
List<FileItem> list = upload.parseRequest(request);
for (FileItem fileItem : list) {
//3_判断FilteIte对象是普通项,还是上传项
if(fileItem.isFormField()){
//4_如果FileItem是普通项,将对应数据放入到Map
//{“username”<==>”tom”,”password”<===>”1234”}
//System.out.println(fileItem.getFieldName()+" :普通项"); username password
//System.out.println(fileItem.getName()+" :普通项"); null null
//System.out.println(fileItem.getString()+" :普通项"); tom 1234
//fileItem.getString("utf-8") ; 解决传递到服务端的数据的中文乱码问题
map.put(fileItem.getFieldName(), fileItem.getString("utf-8"));
}else{
//System.out.println(fileItem.getFieldName()+" :上传项"); userhead
//System.out.println(fileItem.getName()+" :上传项"); 11.bmp
//System.out.println(fileItem.getString()+" :上传项"); 图片二进制数据(图片数据,不推荐以此种凡是获取图片中的数据)
//fileItem.getInputStream();//推荐用此API获取图片数据
//5_如果是上传项
//获取到服务端项目下images目录真实路径
//D:\tomcat\tomcat71_ee50\webapps\TestUpload\images
String realPath=getServletContext().getRealPath("/images");
File dir=new File(realPath);
if(!dir.exists()){
dir.mkdirs();
}
//在服务端创建一个文件 11.bmp(此时文件中没有内容)
File file=new File(realPath,fileItem.getName());
if(!file.exists()){
file.createNewFile();
}
//通过FilteItem获取到输入流,通过输入流可以获取到图片中的数据
InputStream is=fileItem.getInputStream();
//获取到输出流,通过输出流可以向文件中写数据
OutputStream os=new FileOutputStream(file);
//流对接
IOUtils.copy(is, os);
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
//向Map中放入以下数据 “pimage”<===>”服务端新创建文件路径”
map.put("pimage", "/images/"+fileItem.getName());
}
}
//{“username”<==>”tom”,”password”<===>”1234”,”pimage”<==>”图片路径”}
//6_将MAP中的数据赋值给一个Product对象
User user=new User();
//BeanUtils.populate(user,map);
//7_调用业务层功能,将Product对象上的数据保存在DB中
//8_向客户端响应上传成功提示消息
} catch (Exception e) {
e.printStackTrace();
}
}
4、增加多重目录结构
public String addProduct(HttpServletRequest request, HttpServletResponse response) throws Exception {
//1_导入jar包,commons-fileupload.jar commons-io.jar
//2_实现简单3行代码,获取到一个集合,集合存放着FileItem对象
//FileItem每对分割线中间的内容
Map<String,String> map=new HashMap<String,String>();
DiskFileItemFactory fac=new DiskFileItemFactory();
ServletFileUpload upload=new ServletFileUpload(fac);
List<FileItem> list=upload.parseRequest(request);
for (FileItem fileItem : list) {
//3_判断FilteIte对象是普通项,还是上传项
if(fileItem.isFormField()){
//4_如果FileItem是普通项,将对应数据放入到Map
//{“username”<==>”tom”,”password”<===>”1234”}
map.put(fileItem.getFieldName(), fileItem.getString("utf-8"));
}else{
//5_如果是上传项
//获取到文件名称 11.bmp
String oldFileName=fileItem.getName();
//获取随机文件名称 123422143214214.bmp
String uuidFileName=UploadUtils.getUUIDName(oldFileName);
//获取到/products/3/真实路径 D:\tomcat\tomcat71_ee50\webapps\store_v5\products\3
String realPath = getServletContext().getRealPath("/products/3");
//创建随机目录 /c/a/4/a/f/8/7/3/
String randStr=UploadUtils.getDir(uuidFileName);
// D:\tomcat\tomcat71_ee50\webapps\store_v5\products\3/c/a/4/a/f/8/7/3/
File randDir=new File(realPath+randStr);
if(!randDir.exists()){
randDir.mkdirs();
}
//在服务端创建一个文件 11.bmp(此时文件中没有内容)
File file=new File(randDir,uuidFileName);
if(!file.exists()){
file.createNewFile();
}
//通过FilteItem获取到输入流 ,
InputStream is=fileItem.getInputStream();
//获取到输出流,和文件发生关系
OutputStream os=new FileOutputStream(file);
//流对接
IOUtils.copy(is, os);
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
// 向Map中放入以下数据 “pimage”<===>”服务端新创建文件路径”
map.put("pimage", "products/3"+randStr+uuidFileName);
}
}
//6_将MAP中的数据赋值给一个Product对象
//{“username”<==>”tom”,”password”<===>”1234”,”pimage”<==>”图片路径”}
Product product=new Product();
BeanUtils.populate(product, map);
product.setPid(UUIDUtils.getId());
product.setMarket_price(23.23);
product.setPdate(new Date());
product.setPflag(0);
product.setIs_hot(1);
//7_调用业务层功能,将Product对象上的数据保存在DB中
ProductService.saveProduct(product);
//8_向客户端响应上传成功提示消息
response.setContentType("text/html;charset=utf-8");
response.getWriter().print("uploadOk");
return null;
}