在分布式环境下解决springmvc传统文件上传所带来的弊端

一、文件上传

说明:传统方式的文件上传,指的是我们上传的文件和访问的应用存在于同一台服务器上。
并且上传完成之后,浏览器可能跳转。

1. 第一步:创建 maven 工程并导入 commons-fileupload 坐标

1 
2  commons-fileupload
3  commons-fileupload
4  1.3.1
5 

2. 第二步:编写 jsp 页面

 

简单案例演示:
1 
2 图片:
3 4

 

上传产品的图片案例演示:
 1 
 3                 
 4                 
5 6
7
产品信息
8
9 10
产品名称
11
12 14
15 16
产品价格
17
18 20
21 22
产品图片
23
24 25
26 27
所属类别
28
29 34
35 36
产品描述
37
38 40
41 42
43
44 45
46 47 49

 

和上边的代码写在一页中,这个代码在页面加载时就会主动发送请求,查询所属分类
 1     
 2     

 

在分布式环境下解决springmvc传统文件上传所带来的弊端_第1张图片

 

 

3.第三步:编写product类和控制器

Product类

 1 public class Product {
 2 
 3   private int id;
 4   private String name;
 5   private double price;
 6   private String image;
 7   private String desc;
 8   private int cid;
 9 
10 
11   public int getId() {
12     return id;
13   }
14 
15   public void setId(int id) {
16     this.id = id;
17   }
18 
19 
20   public String getName() {
21     return name;
22   }
23 
24   public void setName(String name) {
25     this.name = name;
26   }
27 
28 
29   public double getPrice() {
30     return price;
31   }
32 
33   public void setPrice(double price) {
34     this.price = price;
35   }
36 
37 
38   public String getImage() {
39     return image;
40   }
41 
42   public void setImage(String image) {
43     this.image = image;
44   }
45 
46 
47   public String getDesc() {
48     return desc;
49   }
50 
51   public void setDesc(String desc) {
52     this.desc = desc;
53   }
54 
55 
56   public int getCid() {
57     return cid;
58   }
59 
60   public void setCid(int cid) {
61     this.cid = cid;
62   }
63 
64   @Override
65   public String toString() {
66     return "Product{" +
67             "id=" + id +
68             ", name='" + name + '\'' +
69             ", price=" + price +
70             ", image='" + image + '\'' +
71             ", desc='" + desc + '\'' +
72             ", cid=" + cid +
73             '}';
74   }
75 }

控制器

 1 @Controller
 2 @RequestMapping("/product")
 3 public class ProductController {
 4     @Autowired
 5     private ProductService productService;
 6     @RequestMapping("/save")
 7    public String save(HttpServletRequest request,MultipartFile image){
 8         Map map = request.getParameterMap();
 9 //        System.out.println("image = " + image);
10         Product product = new Product();
11         try {
12             BeanUtils.populate(product,map);
13 
14 
15             //定义文件名
16             String fileName = "";
17             //1.获取原始文件名
18             String uploadFileName = image.getOriginalFilename();
19             //2.截取文件扩展名
20             String extendName = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1, uploadFileName.length());
21             //3.把文件加上随机数,防止文件重复
22             String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
23             //4.判断是否输入了文件名
24 
25             if(!StringUtils.isEmpty(image)) {
26                 fileName = uuid+"_"+image+"."+extendName;
27             }else {
28                 fileName = uuid+"_"+uploadFileName;
29             }
30             System.out.println(fileName);
31             //2.获取文件路径
32             ServletContext context = request.getSession().getServletContext();
33             String basePath = context.getRealPath("/img");//设置文件上传之后保存的位置,这里是指target/gongcheng/img
34             //3.解决同一文件夹中文件过多问题
35            // String datePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
36 
37             //4.判断路径是否存在
38             File file = new File(basePath);//File file = new File(basePath+"/"+datePath());(若使用第3步中的datePath,这步用注释后面的file)
39             if(!file.exists()) {
40                 file.mkdirs();
41             }
42 
43             //5.使用 MulitpartFile 接口中方法,把上传的文件写到指定位置
44             image.transferTo(new File(file,fileName));
45             product.setImage(fileName);//把自定义的文件名存入数据库中
46 
47             productService.save(product);
48 
49         } catch (Exception e) {
50             e.printStackTrace();
51         }
52 
53 
54 
55         return "product-list";
56     }
57 
58 
59     @RequestMapping("/findAll")
60     @ResponseBody
61     public List findAll(){
62 
63         List products = productService.findAll();
6465 
66         return products;
67     }
68 
69 
70 }

 

4. 第四步:在spring-mvc.xml中配置文件解析器

 1 
 2 
 3 class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
 4 
 5 
 6 5242880
 7 
 8 
 9 注意:
10 文件上传的解析器 id 是固定的,不能起别的名称,否则无法实现请求参数的绑定。(不光是文件,其他
11 字段也将无法绑定)

 

二、数据库图片在页面显示

 1 
 2 

愿你走出半生,归来仍是少年!

以上是利用springmvc实现的文件上传功能,在分布式环境下会出现如下问题:

[1]Web应用重新部署问题

重新部署Web应用时,卸载(删除)旧的Web应用,连同用户上传的文件一起删除。重新加载新的Web应用后以前用户上传的文件不会自动恢复。

危害总结:Web应用重新部署会导致用户上传的文件丢失。

[2]集群环境下文件数据同步问题

危害总结:在没有文件的同步机制情况下,上传的文件只能上传到集群中的一台服务器上,导致访问集群中其他服务器时用户访问不到已上传的文件。

[3]Tomcat被拖垮

用户上传的文件如果数据量膨胀到了一个非常庞大的体积,那么就会严重影响Tomcat的运行效率。

[4]服务器存储自动扩容问题

危害总结:手动对服务器进行扩容,有可能导致项目中其他地方需要进行连带修改。

解决方案介绍

①自己搭建文件服务器

举例:FastDFS

好处:服务器可以自己维护、自己定制。

缺点:需要投入的人力、物力更多。

适用:规模比较大的项目,要存储海量的文件。

②使用第三方云服务

举例:阿里云提供的OSS对象存储服务。

好处:不必自己维护服务器的软硬件资源。直接调用相关API即可操作,更加轻量级。

缺点:数据不在自己手里。服务器不由自己维护。

适用:较小规模的应用,文件数据不是绝对私密。

 

参考:https://www.cnblogs.com/hujunwei/p/11181759.html

你可能感兴趣的:(#,分布式解决方案&认证,大学与Java那些年)