Day101 項目實戰5 圖片上傳

實現圖片上傳

剛纔的新增實現中,我們並沒有上傳圖片,接下來我們一起完成圖片上傳邏輯。

文件的上傳並不只是在品牌管理中有需求,以後的其它服務也可能需要,因此我們創建一個獨立的微服務,專門處理各種上傳。

搭建項目

  • 創建微服務module
  • EurekaClient和web依賴
  • 編寫yml配置,注意限制文件上傳的大小
  • 引導類

編寫上傳功能

controller

編寫controller需要知道4個內容:結合用法指南

  • 請求方式:上傳肯定是POST

  • 請求路徑:/upload/image

  • 請求參數:文件,參數名是file,SpringMVC會封裝爲一個接口:MultipartFile

  • 返回結果:上傳成功後得到的文件的url路徑,也就是返回String

代碼如下:

@Controller
@RequestMapping("upload")
public class UploadController {
​
    @Autowired
    private UploadService uploadService;
​
    /**
     * 圖片上傳
     * @param file
     * @return
     */
    @PostMapping("image")
    public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile file){
        String url = this.uploadService.upload(file);
        if (StringUtils.isBlank(url)) {
            return ResponseEntity.badRequest().build();
        }
        return ResponseEntity.status(HttpStatus.CREATED).body(url);
    }
}

service

在上傳文件過程中,我們需要對上傳的內容進行校驗:

  1. 校驗文件大小

  2. 校驗文件的媒體類型

  3. 校驗文件的內容

文件大小在Spring的配置文件中設置,因此已經會被校驗,我們不用管。

具體代碼:

@Service
public class UploadService {
​
    private static final List<String> CONTENT_TYPES = Arrays.asList("image/jpeg", "image/gif");
​
    private static final Logger LOGGER = LoggerFactory.getLogger(UploadService.class);
​
    public String upload(MultipartFile file) {
​
        String originalFilename = file.getOriginalFilename();
        // 校驗文件的類型
        String contentType = file.getContentType();
        if (!CONTENT_TYPES.contains(contentType)){
            // 文件類型不合法,直接返回null
            LOGGER.info("文件類型不合法:{}", originalFilename);
            return null;
        }
​
        try {
            // 校驗文件的內容
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            if (bufferedImage == null){
                LOGGER.info("文件內容不合法:{}", originalFilename);
                return null;
            }
​
            // 保存到服務器
            file.transferTo(new File("C:\\leyou\\images\\" + originalFilename));
​
            // 生成url地址,返回
            return "http://image.leyou.com/" + originalFilename;
        } catch (IOException e) {
            LOGGER.info("服務器內部錯誤:{}", originalFilename);
            e.printStackTrace();
        }
        return null;
    }
}

這裏有一個問題:爲什麼圖片地址需要使用另外的url?

  • 圖片不能保存在服務器內部,這樣會對服務器產生額外的加載負擔

  • 一般靜態資源都應該使用獨立域名,這樣訪問靜態資源時不會攜帶一些不必要的cookie,減小請求的數據量

測試上傳

我們通過RestClient工具來測試:

繞過網關

圖片上傳是文件的傳輸,如果也經過Zuul網關的代理,文件就會經過多次網路傳輸,造成不必要的網絡負擔。在高併發時,可能導致網絡阻塞,Zuul網關不可用。這樣我們的整個系統就癱瘓了。

所以,我們上傳文件的請求就不經過網關來處理了。

Nginx的rewrite指令

	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 {	
			proxy_pass http://127.0.0.1:8082;
			proxy_connect_timeout 600;
			proxy_read_timeout 600;
			
			rewrite "^/api/(.*)$" /$1 break; 
        }
		
        location / {
			proxy_pass http://127.0.0.1:10010;
			proxy_connect_timeout 600;
			proxy_read_timeout 600;
        }
    }

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章