leyou_05_文件上传

1.搭建一个新的微服务Ly-upload用来上传文件

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>
    //Ly-common包含了自定义异常处理
<dependency> <groupId>com.leyou.common</groupId> <artifactId>Ly-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>

3.编写application.yaml的文件配置

server:
  port: 8082
spring:
  application:
    name: upload-service
  servlet:
    multipart:
      max-file-size: 5MB # 限制文件上传的大小
    max-request-sieze: 10MB #限制每次请求的上传的文件大小  # Eureka eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka instance: lease-renewal-interval-in-seconds: 5 # 每隔5秒发送一次心跳 lease-expiration-duration-in-seconds: 10 # 10秒不发送就过期 prefer-ip-address: true ip-address: 127.0.0.1

4.起动类

@SpringBootApplication
@EnableDiscoveryClient
public class LyUploadApplication {
    public static void main(String[] args) {
        SpringApplication.run(LyUploadApplication.class);
    }
}

5.接受参数name="file"

当文件上传成功时返回一个文件路径   ResponseEntity.status(HttpStatus.OK).body(url);

@RestController
@RequestMapping("upload")
public class UploadController {

    @Autowired
    private UploadService uploadService;
    @PostMapping("image") //当文件上传的时候 SpringMvc会自动把上传的文件封装到MultipartFile中去
    public ResponseEntity<String> uploadImg(@RequestParam("file") MultipartFile file) {

        String url=uploadService.uuploadImg(file);
     //
return ResponseEntity.status(HttpStatus.OK).body(url); } }
当文件上传的时候 SpringMvc会自动把上传的文件封装到MultipartFile中去。使用MultipartFile来接受文件
@RequestParam("file") MultipartFile file

6.文件上传

@Service
@Slf4j
public class UploadService {

    private static  final List<String> ALLOW_TYPES= Arrays.asList("image/jpeg","image/png");
    public String uploadImg(MultipartFile file) {
        try {

            //检验文件的类型 防止恶意文件
            String contentType = file.getContentType();
            if (!ALLOW_TYPES.contains(contentType)){
                throw  new LyException(ExceptionEnum.INVALID_FILE_TYPE);
            };
            //校验文件的内容
            BufferedImage image = ImageIO.read(file.getInputStream());
            if (image==null){
                throw  new LyException(ExceptionEnum.INVALID_FILE_TYPE);
            }
            //保存文件到本地
            File local = new File("F:\javaee\IdeaResource\uploadImg\",file.getOriginalFilename());
            file.transferTo(local);
            //返回文件地址
            return "http://image.leyou.com/"+file.getOriginalFilename();
        } catch (IOException e) {
            log.error("上传失败",e);
            throw  new LyException(ExceptionEnum.UPLOAD_FILE_ERROR);
        }
    }
}

代码详解:1.防止恶意文件对文件进行简单的校验

       保证文件后缀名是我们规定的:

      private static  final List<String> ALLOW_TYPES= Arrays.asList("image/jpeg","image/png");
  
    Arrays.asList可以报我们 直接把参数转化成数组元素

         保证文件内容是图片:如果检验到图片则image为空

       //校验文件的内容
            BufferedImage image = ImageIO.read(file.getInputStream());
            if (image==null){
                throw  new LyException(ExceptionEnum.INVALID_FILE_TYPE);
            }

      2.上传图片

        使用transferTo(dest)方法将上传文件写到服务器上指定的文件。

       //保存文件到本地
            File local = new File("F:\javaee\IdeaResource\uploadImg\",file.getOriginalFilename());
            file.transferTo(local);
            //返回文件地址
            return "http://image.leyou.com/"+file.getOriginalFilename();

7测试    

返回地址上传成功

8.服务器上传图片时非常消耗网关的时间资源

当nginx检测到收到的地址是/api/upload/*是不在向网关转发,而是直接转发到该资源所在的位置

# 上传路径的映射
        server {
        listen       80;
        server_name  api.leyou.com;

        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        location /api/upload {
            rewrite "^/(.*)$" /zuul/$1;
            proxy_pass http://192.168.11.82:8082;
        }

        location / {
            proxy_pass http://192.168.11.82:10010;
            proxy_connect_timeout 600;
            proxy_read_timeout 600;
        }
    }
  • 首先,我们映射路径是/api/upload,而下面一个映射路径是 / ,根据最长路径匹配原则,/api/upload优先级更高。也就是说,凡是以/api/upload开头的路径,都会被第一个配置处理

  • proxy_pass:反向代理,这次我们代理到8082端口,也就是upload-service服务

  • rewrite

    "^/(.*)$" /zuul/$1;路径重写 去除http://api.leyou.com/api/upload/image中的api前缀

修改完成,输入nginx -s reload命令重新加载配置。然后再次上传试试。

 

 

原文地址:https://www.cnblogs.com/asndxj/p/11574531.html