文件的上傳並不僅是在品牌管理中有需求,之後的其它服務也可能須要,所以咱們建立一個獨立的微服務,專門處理各類上傳。java
1.搭建模塊nginx
(1)建立模塊web
(2)依賴spring
咱們須要EurekaClient和web依賴:apache
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>leyou</artifactId> <groupId>lucky.leyou.parent</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>lucky.leyou.upload</groupId> <artifactId>leyou-upload</artifactId> <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> </dependencies> </project>
(3)編寫配置api
server: port: 8082 spring: application: name: upload-service servlet: multipart: max-file-size: 5MB # 限制文件上傳的大小 # Eureka eureka: client: service-url: defaultZone: http://localhost:10086/eureka instance: lease-renewal-interval-in-seconds: 5 # 每隔5秒發送一次心跳 lease-expiration-duration-in-seconds: 10 # 10秒不發送就過時
(4)引導類跨域
package lucky.leyou; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class LeyouUploadApplication { public static void main(String[] args) { SpringApplication.run(LeyouUploadApplication.class, args); } }
(5)模塊初步結構圖瀏覽器
2.編寫上傳功能服務器
(1)Controllercookie
package lucky.leyou.upload.controller; import lucky.leyou.upload.service.IUploadService; 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(path = "/upload") public class UploadController { @Autowired IUploadService iUploadService; @PostMapping(path = "/image") public ResponseEntity<String> uploadImage(@RequestParam("file")MultipartFile file){ String url=this.iUploadService.uploadImage(file); //若url爲空,則返回400,上傳失敗 if(StringUtils.isBlank(url)){ return ResponseEntity.badRequest().build(); } return ResponseEntity.status(HttpStatus.CREATED).body(url); } }
(2)service
接口
package lucky.leyou.upload.service; import org.springframework.web.multipart.MultipartFile; public interface IUploadService { String uploadImage(MultipartFile file); }
實現類
package lucky.leyou.upload.service.impl; import lucky.leyou.upload.service.IUploadService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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; public class UploadServiceImpl implements IUploadService { private static final List<String> CONTENT_TYPES = Arrays.asList("image/jpeg", "image/gif"); private static final Logger LOGGER = LoggerFactory.getLogger(UploadServiceImpl.class); @Override public String uploadImage(MultipartFile file) { String originalFilename = file.getOriginalFilename(); // 校驗文件的類型 String contentType = file.getContentType(); //利用瀏覽器開發者模式下可見的content-type,判斷文件類型 //Content-Type: application/x-www-form-urlencoded 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:\\Users\\image\\" + originalFilename)); // 生成url地址,返回 return "http://image.leyou.com/" + originalFilename; } catch (IOException e) { LOGGER.info("服務器內部錯誤:{}", originalFilename); e.printStackTrace(); } return null; } }
(3)使用Nginx代理,實現域名訪問
進入Nginx的安裝路徑E:\toolsoftware\nginx-1.14.0\nginx-1.14.0\conf,修改
添加一個server,以下配置
server { listen 80; server_name image.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 / { root C:\\Users\\image; } }
從新加載Nginx
(4)修改host解析
(5)效果圖
(6)修改Nginx配置文件
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; }
(7)重啓nginx,再次上傳,發現跟上次的狀態碼已經不同了,可是依然報錯
不過慶幸的是,這個錯誤已經不是第一次見了,跨域問題。
package lucky.leyou.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; /** * 利用cors解決跨域問題 */ @Configuration public class LeyouCorsConfig { @Bean public CorsFilter corsFilter() { //1.添加CORS配置信息 CorsConfiguration config = new CorsConfiguration(); //1) 容許的域,不要寫*,不然cookie就沒法使用了 config.addAllowedOrigin("http://manage.leyou.com"); //2) 是否發送Cookie信息 config.setAllowCredentials(true); //3) 容許的請求方式 config.addAllowedMethod("*"); // 4)容許的頭信息 config.addAllowedHeader("*"); //2.添加映射路徑,咱們攔截一切請求 UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); configSource.registerCorsConfiguration("/**", config); //3.返回新的CorsFilter. return new CorsFilter(configSource); } }
(8)最終效果
<1>若文件類型不符合
<2>若類型符合