servlet的文件上传总结

1、实现上传准备工作

    表单设置如下属性:
    a、method=post
    b、提供file组件   <input type="file" />
    c、设置form表单属性为:entype="multipart/form-data"如果这个属性不设置,文件自身无法传递给servlet
        上传目的:
                   1、 将客户端的图片传递给服务端,在服务端建立一个文件,文件中存放着客户端图片的内容
                   2、将表单中的数据放入DB中一份


2、分析上传协议格式

   
   
  1. 没有设置enctype属性时HTTP协议格式
  2. POST /TestUpload/ServetDemo01 http/1.1
  3. 请求头
  4. 请求头
  5. 请求头
  6. username=tom
  7. password=1234
  8. userhead=111.bmp

   
   
  1. 设置enctype属性时HTTP协议格式
  2. POST /TestUpload/ServetDemo01 http/1.1
  3. 请求头
  4. 请求头
  5. 请求头
  6. Content-Type: multipart/form-data; boundary=---------------------------54581570913334
  7. Content-Length: 9659
  8. -----------------------------54581570913334
  9. Content-Disposition: form-data; name="username"
  10. 11
  11. -----------------------------54581570913334
  12. Content-Disposition: form-data; name="password"
  13. 11
  14. -----------------------------54581570913334
  15. Content-Disposition: form-data; name="userhead"; filename="11.bmp"
  16. Content-Type: image/bmp
  17. BM6$图片的二进制乱码数据
  18. BM6$图片的二进制乱码数据
  19. BM6$图片的二进制乱码数据
  20. BM6$图片的二进制乱码数据
  21. BM6$图片的二进制乱码数据
  22. BM6$图片的二进制乱码数据
  23. BM6$图片的二进制乱码数据
  24. -----------------------------54581570913334--



3、测试:

             a、servlet的API使用:
   
   
  1. public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  2. System.out.println(Thread.currentThread().getId()+ ""+this);
  3. //由于request.parameterName();这类API获取的是1_请求路径后的键值对的数据2_请求正文部分键值对的数据
  4. //由于我们设置了表单的enctype属性,如果以POST方式传递数据时,请求体中的内容格式发生了变化,传统的API无法获取数据
  5. //System.out.println(request.getParameter("username"));
  6. //System.out.println(request.getParameter("password"));
  7. //System.out.println(request.getParameter("userhead"));
  8. //通过request获取输入流
  9. InputStream is = request.getInputStream();
  10. //打印输入流中的内容
  11. int i=is.read();
  12. while(i!=-1){
  13. System.out.print((char)i);
  14. i=is.read();
  15. }
  16. }

结论:
1_用传统的方式无法获取表单参数
2_通过request获取到一个输入流,通过打印输入流可以获取到请求体中的数据
   理论上可以实现手动上传

                b、工具类

1_导入jar包,commons-fileupload.jar  commons-io.jar

2_实现简单3行代码,获取到一个集合,集合存放着FileItem对象
  FileItem每对分割线中间的内容
      
      
  1. DiskFileItemFactory fac=new DiskFileItemFactory();
  2. ServletFileUpload upload=new ServletFileUpload(fac);
  3. try {
  4. List<FileItem> list = upload.parseRequest(request);
  5. }catch(){
  6. }



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_向客户端响应上传成功提示消息

   
   
  1. public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  2. //1_导入jar包,commons-fileupload.jar commons-io.jar
  3. //2_实现简单3行代码,获取到一个集合,集合存放着FileItem对象//FileItem每对分割线中间的内容
  4. DiskFileItemFactory fac=new DiskFileItemFactory();
  5. ServletFileUpload upload=new ServletFileUpload(fac);
  6. Map<String,String> map=new HashMap<String,String>();
  7. try {
  8. List<FileItem> list = upload.parseRequest(request);
  9. for (FileItem fileItem : list) {
  10. //3_判断FilteIte对象是普通项,还是上传项
  11. if(fileItem.isFormField()){
  12. //4_如果FileItem是普通项,将对应数据放入到Map
  13. //{“username”<==>”tom”,”password”<===>”1234”}
  14. //System.out.println(fileItem.getFieldName()+" :普通项"); username password
  15. //System.out.println(fileItem.getName()+" :普通项"); null null
  16. //System.out.println(fileItem.getString()+" :普通项"); tom 1234
  17. //fileItem.getString("utf-8") ; 解决传递到服务端的数据的中文乱码问题
  18. map.put(fileItem.getFieldName(), fileItem.getString("utf-8"));
  19. }else{
  20. //System.out.println(fileItem.getFieldName()+" :上传项"); userhead
  21. //System.out.println(fileItem.getName()+" :上传项"); 11.bmp
  22. //System.out.println(fileItem.getString()+" :上传项"); 图片二进制数据(图片数据,不推荐以此种凡是获取图片中的数据)
  23. //fileItem.getInputStream();//推荐用此API获取图片数据
  24. //5_如果是上传项
  25. //获取到服务端项目下images目录真实路径
  26. //D:\tomcat\tomcat71_ee50\webapps\TestUpload\images
  27. String realPath=getServletContext().getRealPath("/images");
  28. File dir=new File(realPath);
  29. if(!dir.exists()){
  30. dir.mkdirs();
  31. }
  32. //在服务端创建一个文件 11.bmp(此时文件中没有内容)
  33. File file=new File(realPath,fileItem.getName());
  34. if(!file.exists()){
  35. file.createNewFile();
  36. }
  37. //通过FilteItem获取到输入流,通过输入流可以获取到图片中的数据
  38. InputStream is=fileItem.getInputStream();
  39. //获取到输出流,通过输出流可以向文件中写数据
  40. OutputStream os=new FileOutputStream(file);
  41. //流对接
  42. IOUtils.copy(is, os);
  43. IOUtils.closeQuietly(is);
  44. IOUtils.closeQuietly(os);
  45. //向Map中放入以下数据 “pimage”<===>”服务端新创建文件路径”
  46. map.put("pimage", "/images/"+fileItem.getName());
  47. }
  48. }
  49. //{“username”<==>”tom”,”password”<===>”1234”,”pimage”<==>”图片路径”}
  50. //6_将MAP中的数据赋值给一个Product对象
  51. User user=new User();
  52. //BeanUtils.populate(user,map);
  53. //7_调用业务层功能,将Product对象上的数据保存在DB中
  54. //8_向客户端响应上传成功提示消息
  55. } catch (Exception e) {
  56. e.printStackTrace();
  57. }
  58. }

4、增加多重目录结构


   
   
  1. public String addProduct(HttpServletRequest request, HttpServletResponse response) throws Exception {
  2. //1_导入jar包,commons-fileupload.jar commons-io.jar
  3. //2_实现简单3行代码,获取到一个集合,集合存放着FileItem对象
  4. //FileItem每对分割线中间的内容
  5. Map<String,String> map=new HashMap<String,String>();
  6. DiskFileItemFactory fac=new DiskFileItemFactory();
  7. ServletFileUpload upload=new ServletFileUpload(fac);
  8. List<FileItem> list=upload.parseRequest(request);
  9. for (FileItem fileItem : list) {
  10. //3_判断FilteIte对象是普通项,还是上传项
  11. if(fileItem.isFormField()){
  12. //4_如果FileItem是普通项,将对应数据放入到Map
  13. //{“username”<==>”tom”,”password”<===>”1234”}
  14. map.put(fileItem.getFieldName(), fileItem.getString("utf-8"));
  15. }else{
  16. //5_如果是上传项
  17. //获取到文件名称 11.bmp
  18. String oldFileName=fileItem.getName();
  19. //获取随机文件名称 123422143214214.bmp
  20. String uuidFileName=UploadUtils.getUUIDName(oldFileName);
  21. //获取到/products/3/真实路径 D:\tomcat\tomcat71_ee50\webapps\store_v5\products\3
  22. String realPath = getServletContext().getRealPath("/products/3");
  23. //创建随机目录 /c/a/4/a/f/8/7/3/
  24. String randStr=UploadUtils.getDir(uuidFileName);
  25. // D:\tomcat\tomcat71_ee50\webapps\store_v5\products\3/c/a/4/a/f/8/7/3/
  26. File randDir=new File(realPath+randStr);
  27. if(!randDir.exists()){
  28. randDir.mkdirs();
  29. }
  30. //在服务端创建一个文件 11.bmp(此时文件中没有内容)
  31. File file=new File(randDir,uuidFileName);
  32. if(!file.exists()){
  33. file.createNewFile();
  34. }
  35. //通过FilteItem获取到输入流 ,
  36. InputStream is=fileItem.getInputStream();
  37. //获取到输出流,和文件发生关系
  38. OutputStream os=new FileOutputStream(file);
  39. //流对接
  40. IOUtils.copy(is, os);
  41. IOUtils.closeQuietly(is);
  42. IOUtils.closeQuietly(os);
  43. // 向Map中放入以下数据 “pimage”<===>”服务端新创建文件路径”
  44. map.put("pimage", "products/3"+randStr+uuidFileName);
  45. }
  46. }
  47. //6_将MAP中的数据赋值给一个Product对象
  48. //{“username”<==>”tom”,”password”<===>”1234”,”pimage”<==>”图片路径”}
  49. Product product=new Product();
  50. BeanUtils.populate(product, map);
  51. product.setPid(UUIDUtils.getId());
  52. product.setMarket_price(23.23);
  53. product.setPdate(new Date());
  54. product.setPflag(0);
  55. product.setIs_hot(1);
  56. //7_调用业务层功能,将Product对象上的数据保存在DB中
  57. ProductService.saveProduct(product);
  58. //8_向客户端响应上传成功提示消息
  59. response.setContentType("text/html;charset=utf-8");
  60. response.getWriter().print("uploadOk");
  61. return null;
  62. }






















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值