1 文件上传
1、依赖
- SpringMVC为文件上传提供了直接的支持,这种支持是通过即插即用的MultipartResolver实现的。
- Spring用Jakarta Commons FileUpload技术实现了一个CommonsMultipartResovler。
- 在SpringBoot中,只需要添加
web-start
依赖即可:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2、Controller
package com.leyou.upload.controller; import com.leyou.upload.service.UploadService; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; @Controller @RequestMapping("/upload") public class UploadController { @Autowired private UploadService uploadService; @PostMapping("/image") public ResponseEntity<String> uploadImage(@RequestParam("file")MultipartFile file) { String url = this.uploadService.uploadImage(file); if (StringUtils.isBlank(url)) { return ResponseEntity.badRequest().build(); } return ResponseEntity.status(HttpStatus.CREATED).body(url); } }
3、Service
package com.leyou.upload.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.util.Arrays; import java.util.List; @Service public class UploadService { private static final List<String> CONTENT_TYPES = Arrays.asList("image/gif", "image/jpeg"); private static final Logger LOGGER = LoggerFactory.getLogger(UploadService.class); public String uploadImage(MultipartFile file) { String originalFilename = file.getOriginalFilename(); // 1、校验文件类型 String contentType = file.getContentType(); if (!CONTENT_TYPES.contains(contentType)) { LOGGER.info("文件类型不合法:{}", originalFilename); return null; } try { // 2、校验文件内容 BufferedImage bufferedImage = ImageIO.read(file.getInputStream()); if (bufferedImage == null) { LOGGER.info("文件内容不合法:{}", originalFilename); return null; } // 3、保存到服务器 file.transferTo(new File("E:\\image\\" + originalFilename)); // 4、返回url return "http://image.leyou.com/" + originalFilename; } catch (Exception e) { LOGGER.info("服务器内部错误:{}", originalFilename); e.printStackTrace(); } return null; } }
2 绕过网关
- 图片上传是文件的传输,如果也经过Zuul网关的代理,文件就会经过多次网路传输,造成不必要的网络负担。在高并发时,可能导致网络阻塞,Zuul网关不可用。
- 因此,上传文件的请求一般不经过网关处理。
1、方式一:Zuul的路由过滤
Zuul的
ignored-patterns
属性,忽略不希望路由的URL路径:zuul.ignored-patterns: /upload/**
Zuul的
ignored-services
属性,进行服务过滤:zuul.ignored-services: upload-service
2、方式二:Nginx过滤
server { listen 80; # 监听端口 server_name api.leyou.com; # 监听域名 location /api/upload { # 代理路径 proxy_pass http://127.0.0.1:8082; proxy_connect_timeout 600; proxy_read_timeout 60; } location / { # 代理路径 proxy_pass http://127.0.0.1:10010; proxy_connect_timeout 600; proxy_read_timeout 60; rewrite "^/api/(.*)$" /$1 break; } }