文件上传过大问题

说明:以下是学习黑马乐优商城总结,如果侵权,请联系删除

项目场景:

在黑马乐优商城中,有一个文件上传微服务,此文章就是总结文件上传微服务中碰见的问题。
为了方便文件上传服务,创建了一个独立的微服务,专门处理各种上传。


步骤一: 搭建图片上传服务

1.1 创建module

在这里插入图片描述

1.2 依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
        <artifactId>ly_common</artifactId>
        <groupId>com.leyou</groupId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

1.3 编写配置

server:
  port: 8082
spring:
  application:
    name: upload-service
  servlet:
    multipart:
      max-file-size: 5MB # 限制文件上传的大小
# Eureka
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
    registry-fetch-interval-seconds: 15
  instance:
    ip-address: 127.0.0.1
    prefer-ip-address: true

注意:限制了文件的大小

1.4 启动类

package com.leyou;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * @Author: heboxuan
 * @Date: Created in 11:10 2021/2/10
 */
@SpringBootApplication
@EnableDiscoveryClient
public class LyUploadApplication {
    public static void main(String[] args) {
        SpringApplication.run(LyUploadApplication.class,args);
    }
}

1.5 在网关的配置文件增加ly_upload的路由映射

zuul:
  prefix: /api # 添加路由前缀
  routes:
    item-service: #这里是路由id,随便写
      path: /item/** # 将商品微服务映射到/item/**
      serviceId: item-service
    upload-service:
      path: /upload/**
      serviceId: upload-service

步骤二: 实现本地图片上传

在这里插入图片描述

2.1 编写上传功能

在这里插入图片描述
在这里插入图片描述
controller

package com.leyou.upload.controller;

import com.leyou.upload.service.UploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * @Author: heboxuan
 * @Date: Created in 11:22 2021/2/10
 */
@RestController
public class UploadController {
    @Autowired
    private UploadService uploadService;

    /**
     * 上传图片功能
     * @param file
     * @return url路径
     */
    @PostMapping("image")
    public ResponseEntity<String> uploadImage(@RequestParam("file")MultipartFile file) {
        // 返回200,并且携带url路径
        return ResponseEntity.ok(uploadService.uploadImage(file));
    }
}

service
在这里插入图片描述

package com.leyou.upload.service;

import com.leyou.common.exception.LyException;
import com.leyou.common.exception.enums.ExceptionEnum;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * @Author: heboxuan
 * @Date: Created in 11:23 2021/2/10
 */
@Service
public class UploadService {

    //支持文件类型
    private static final List<String> suffixes= Arrays.asList("image/png", "image/jpeg", "image/bmp");

    /**
     * 本地上传
     * @param file
     * @return
     */
    public String uploadImage(MultipartFile file) {
        //检查文件类型是否支持
        String contentType = file.getContentType();
        if (!suffixes.contains(contentType)) {
            throw new LyException(ExceptionEnum.INVALID_FILE_TYPE);
        }
        //检查当前文件是否是图片,使用java提供的ImageIO工具类
        try {
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            //如果bufferedImage有值,说明是图片,如果不是,上传错误
            if (bufferedImage==null) {
                throw new LyException(ExceptionEnum.INVALID_FILE_TYPE);
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new LyException(ExceptionEnum.INVALID_FILE_TYPE);
        }
        //原文件名
        String originalFilename = file.getOriginalFilename();
        //获取文件的后缀
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        //构造新的文件名,名字不重复
        String newFileName=UUID.randomUUID().toString()+ suffix;
        //上传文件,存在nginx下
        String filePath = "D:\live\nginx-1.14.0\html ";
        File dir = new File(filePath);
        //检查上传目录是否存在
        if (!dir.exists()) {
            //如果目录不存在,创建目录
            dir.mkdir();
        }
        //把文件上传到本地目录,使用IO流
        try {
            file.transferTo(new File(dir,newFileName));
        } catch (Exception e) {
            e.printStackTrace();
            throw new LyException(ExceptionEnum.FILE_UPLOAD_ERROR);
        }
        //http://image.leyou.com/XXXXXX.jpg
        String url="http://image.leyou.com/"+newFileName;
        return url;
    }

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试上传
在这里插入图片描述
在这里插入图片描述

2.2 Nginx的请求大小

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3 绕过网关缓存

对于文件上传的微服务没必要经过网关,如果同时多个大文件上传经过网关,网关处理这些请求既耗时,也可能造成网关崩溃(因为请求携带数据,数据包含文件,文件过大),所以当是文件上传的请求时,绕过网关,不处理。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

在这里插入图片描述

posted @ 2022-01-24 10:20  KeepArlen  阅读(335)  评论(0)    收藏  举报