目录
创建一个Maven项目
项目目录结构
完整的pom文件如下
新建引导类UploadApplication
引入配置类
配置application.yml文件
新建CorsConfiguration配置类,解决跨域问题
新建Swagger2类,方便测试,当然也可以不写,用postman测试
通过SwitchHosts程序配置hosts文件
创建FastDFSTest测试类
测试文件上传:
通过域名访问:
新建UploadController类
新建UploadService类
swagger进行测试
4.0.0
com.fjx
file_upload
1.0.0-SNAPSHOT
jar
org.springframework.boot
spring-boot-starter-parent
2.0.6.RELEASE
UTF-8
UTF-8
1.8
1.26.1-RELEASE
2.0.7.RELEASE
org.springframework.boot
spring-boot-starter-web
${spring-boot.version}
org.springframework.boot
spring-boot-starter-test
${spring-boot.version}
com.github.tobato
fastdfs-client
${fastDFS.client.version}
io.springfox
springfox-swagger2
2.7.0
io.springfox
springfox-swagger-ui
2.7.0
org.springframework.boot
spring-boot-maven-plugin
package com.fjx;/*
@author Jason
@DESCRIPTION :启动接口
@create 2019-12-24
*/
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class UploadApplication {
public static void main(String[] args) {
SpringApplication.run(UploadApplication.class);
}
}
package com.fjx.config;/*
@author Jason
@DESCRIPTION
@create 2019-12-21
*/
import com.github.tobato.fastdfs.FdfsClientConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableMBeanExport;
import org.springframework.context.annotation.Import;
import org.springframework.jmx.support.RegistrationPolicy;
@Configuration
@Import(FdfsClientConfig.class)
// 解决jmx重复注册bean的问题
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastClientImporter {
}
server:
port: 8082
spring:
application:
name: upload-service
servlet:
multipart:
max-file-size: 5MB # 限制文件上传的大小
# FastDFS配置
fdfs:
so-timeout: 1501 # 超时时间
connect-timeout: 601 # 连接超时时间
thumb-image: # 缩略图
width: 60
height: 60
tracker-list: # tracker地址:你的虚拟机服务器地址+端口(默认是22122)
- 192.168.60.72:22122
package com.fjx.config;/*
@author Jason
@DESCRIPTION 解决跨域问题
@create 2019-12-24
*/
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfiguration {
@Bean
public CorsFilter corsFilter() {
//1.添加CORS配置信息,用来初始化Cors配置对象
org.springframework.web.cors.CorsConfiguration config = new org.springframework.web.cors.CorsConfiguration();
//1) 添加允许的跨域域名,如果携带cookie,则不可以写* *,表示所有的域名都可以跨域访问
config.addAllowedOrigin("http://manage.leyou.com");
//2) 是否允许携带发送Cookie信息,true表示允许迭代cookie信息
config.setAllowCredentials(true);
//3) 允许的请求方式,*代表所有的请求方法,包括GET
// config.addAllowedMethod("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
// 4)允许的头信息
config.addAllowedHeader("*");
//2.添加映射路径,我们拦截一切请求,初始化cors配置源对象
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
configSource.registerCorsConfiguration("/**", config);
//3.返回新的CorsFilter实例,参数为:cors配置源对象
return new CorsFilter(configSource);
}
}
package com.fjx.config;/*
@author Jason
@DESCRIPTION
@create 2019-12-19
*/
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class Swagger2 {
//@Profile({"dev", "test"})
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.fjx.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("upload-service RESTful APIs")
.description("")
.termsOfServiceUrl("")
.version("1.0")
.build();
}
}
注意:代码中有图片路径,换成自己电脑中的一张图片路径
package com.fjx.test;/*
@author Jason
@DESCRIPTION
@create 2019-12-24
*/
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.domain.ThumbImageConfig;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@SpringBootTest
@RunWith(SpringRunner.class)
public class FastDFSTest {
@Autowired
private FastFileStorageClient storageClient;
@Autowired
private ThumbImageConfig thumbImageConfig;
@Test
public void testUpload() throws FileNotFoundException {
// 要上传的文件,找一个图片路径
File file = new File("D:\\project\\hm49\\image\\1.jpeg");
// 上传并保存图片,参数:1-上传的文件流 2-文件的大小 3-文件的后缀 4-可以不管他
StorePath storePath = this.storageClient.uploadFile(
new FileInputStream(file), file.length(), "jpg", null);
// 带分组的路径
System.out.println(storePath.getFullPath());
// 不带分组的路径
System.out.println(storePath.getPath());
}
@Test
public void testUploadAndCreateThumb() throws FileNotFoundException {
File file = new File("D:\\project\\hm49\\image\\2.jpeg");
// 上传并且生成缩略图
StorePath storePath = this.storageClient.uploadImageAndCrtThumbImage(
new FileInputStream(file), file.length(), "png", null);
// 带分组的路径
System.out.println(storePath.getFullPath());
// 不带分组的路径
System.out.println(storePath.getPath());
// 获取缩略图路径
String path = thumbImageConfig.getThumbImagePath(storePath.getPath());
System.out.println(path);
}
}
package com.fjx.controller;/*
@author 天赋吉运-Jason
@DESCRIPTION
@create 2019-12-21
*/
import com.fjx.service.UploadService;
import org.apache.commons.lang3.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;
/**
* 图片上传
* @param file
* @return
*/
@PostMapping("image")
public ResponseEntity 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);
}
}
package com.fjx.service;/*
@author 天赋吉运-Jason
@DESCRIPTION
@create 2019-12-24
*/
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
@Service
public class UploadService {
public static String FILE_FORMAT = "WEBP、BMP、PCX、TIF、GIF、JPEG、TGA、EXIF、FPX、" +
"SVG、PSD、CDR、PCD、DXF、UFO、EPS、AI、PNG、HDRI、RAW、WMF、FLIC、EMF、ICO、JPG、JPEG、PNG、GIF";
private static final Logger LOGGER = LoggerFactory.getLogger(UploadService.class);
@Autowired
private FastFileStorageClient storageClient;
public String upload(MultipartFile file) {
String originalFilename = file.getOriginalFilename();
// 校验文件的类型,file.getContentType()表示获取文件类型
String contentType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.') + 1).toUpperCase();
if (!FILE_FORMAT.contains(contentType)) {
// 文件类型不合法,直接返回null
LOGGER.info("文件类型不合法:{}", originalFilename);
return null;
}
try {
// 校验文件的内容,ImageIO是一个工具类
BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
if (bufferedImage == null) {
LOGGER.info("文件内容不合法:{}", originalFilename);
return null;
}
// 保存到服务器
String ext = StringUtils.substringAfterLast(originalFilename, ".");
StorePath storePath = this.storageClient.uploadFile(file.getInputStream(), file.getSize(), ext, null);
// 生成url地址,进行回显
return "http://image.leyou.com/" + storePath.getFullPath();
} catch (IOException e) {
LOGGER.info("服务器内部错误:{}", originalFilename);
e.printStackTrace();
}
return null;
}
}
github地址:https://github.com/Jason1627/FastDFS-.git
关于FastDFS文件上传封装完成,欢迎评论讨论!