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=tompassword=1234userhead=111.bmp
设置enctype属性时HTTP协议格式POST /TestUpload/ServetDemo01 http/1.1请求头请求头请求头Content-Type: multipart/form-data; boundary=---------------------------54581570913334Content-Length: 9659-----------------------------54581570913334Content-Disposition: form-data; name="username"11-----------------------------54581570913334Content-Disposition: form-data; name="password"11-----------------------------54581570913334Content-Disposition: form-data; name="userhead"; filename="11.bmp"Content-Type: image/bmpBM6$图片的二进制乱码数据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; }