目录
1. 新建一个springboot项目
新建一个springboot项目,选择web,默认即可.
主要pom配置文件如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--web包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- maven打包设置-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
2. 配置文件
在配置文件中配置文件上传和下载的根目录,文件大小限制等。
application.properties
file.upload.url=path/to/upload
# 文件大小限制
spring.servlet.multipart.max-file-size=10MB
# 请求大小限制
spring.servlet.multipart.max-request-size=20MB
application.yml
file.upload.url: path/to/upload
spring:
servlet:
multipart:
# 文件大小限制
max-file-size: 10MB
max-request-size: 20MB
3. 控制类实现文件上传和下载
在控制类中实现文件上传和下载。其中,文件上传通过MultipartFile实现文件类型限制、文件大小限制、多文件上传等,下载通过文件流实现。
新增图片预览方法。
@RestController
@RequestMapping(value = "/file")
@CrossOrigin // 允许跨域
@ControllerAdvice // 全局异常处理
public class FileController {
//上传的根目录
@Value("${file.upload.url}")
private String uploadFilePath;
@Value("${file.upload.url}")
private String downloadFilePath;
//捕获上传文件过大的异常
//@ExceptionHandler标识方法将处理指定类型的异常
@ExceptionHandler(MaxUploadSizeExceededException.class)
public ResponseEntity<String> handleMaxSizeException(MaxUploadSizeExceededException exc) {
return ResponseEntity.status(HttpStatus.PAYLOAD_TOO_LARGE).body("文件过大,请重新选择上传图片!");
}
@RequestMapping("/upload")
public String httpUpload(
@RequestParam("files")
//MultipartFile 是 Spring 框架中用于处理文件上传的接口
MultipartFile files[]) {
StringBuffer urls = new StringBuffer();
//遍历多个文件
for (int i = 0; i < files.length; i++) {
//获取文件类型
String contentType = files[i].getContentType();
System.out.println(contentType);
if (!contentType.contains("image")) {
return "文件格式不正确,请重新选择图片!";
}
//获取上传文件的后缀名
String postfix = files[i].getOriginalFilename().substring(files[i].getOriginalFilename().lastIndexOf("."));
//生成文件名 使用时间戳,避免重名
String fileName = System.currentTimeMillis()+postfix;
System.out.println(fileName);
// File dest = new File(uploadFilePath + '/' + fileName);
File dest = new File(uploadFilePath + '/' + fileName);
//目录不存在则创建目录
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
try {
//将上传的文件保存到指定的目标位置
files[i].transferTo(dest);
} catch (Exception e) {
return "程序错误,请重新上传\n" + e.toString();
}
urls.append("\n"+uploadFilePath + '\\' + fileName);
}
return "文件上传成功" + urls.toString();
}
@RequestMapping("/download")
public String fileDownLoad(HttpServletResponse response, @RequestParam("fileName") String fileName) {
// File file = new File(downloadFilePath + '/' + fileName);
File file = new File(downloadFilePath + '\\' + fileName);
if (!file.exists()) {
return "下载文件不存在";
}
//清除之前设置的内容
response.reset();
//设置响应内容类型为二进制流
response.setContentType("application/octet-stream");
//设置响应字符编码为UTF-8
response.setCharacterEncoding("utf-8");
//设置响应文件大小
response.setContentLength((int) file.length());
//设置浏览器以附件的形式下载,并设置文件名
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));) {
byte[] buff = new byte[1024];
OutputStream os = response.getOutputStream();
int i = 0;
while ((i = bis.read(buff)) != -1) {
os.write(buff, 0, i);
os.flush();
}
} catch (IOException e) {
return "下载失败";
}
return "下载成功";
}
/**
* 图片预览功能接口
* @param fileName
* @return
*/
@RequestMapping("showImage")
public ResponseEntity<Resource> showImage(@RequestParam("fileName") String fileName) {
try {
// 指定图片文件的路径 指定目录 追加文件名到 路径 规范化路径,去除冗余路径元素
Path filePath = Paths.get(downloadFilePath).resolve(fileName).normalize();
// 创建一个 Resource 对象,用于封装图片文件的位置
// 将 Path 对象转换为 URI 对象
Resource resource = new UrlResource(filePath.toUri());
// 检查文件是否存在且可读
if (resource.exists() && resource.isReadable()) {
// 根据文件扩展名设置 Content-Type
String contentType;
if (fileName.endsWith(".png")) {
contentType = "image/png";
} else if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
contentType = "image/jpeg";
} else if (fileName.endsWith(".gif")) {
contentType = "image/gif";
} else {
// 如果不是图片类型,返回错误响应
return ResponseEntity.status(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
.body(null);
}
return ResponseEntity.ok()
// 设置响应头,告诉浏览器如何处理文件
// Content-Disposition: inline 表示在浏览器中直接显示图片 同时fileName指定文件名
.header(HttpHeaders.CONTENT_DISPOSITION, "inline;filename=\"" + fileName + "\"")
.header(HttpHeaders.CONTENT_TYPE, contentType)
.body(resource);
} else {
//创建一个 404 错误响应
return ResponseEntity.notFound().build();
}
} catch (Exception e) {
// 创建一个 500 错误响应
return ResponseEntity.status(500).build();
}
}
}
4. 测试
以下测试使用工具postman实现。测试文件大小的图片可以使用代码生成,可参考文章。
测试文件上传格式限制。
测试文件上传图片大小限制。
测试文件上传正常上传图片。
测试文件下载。
测试文件预览。
5. 在其他控制器中调用接口
通过在其他控制器中调用接口,实现文件上传和下载。
1. 配置类
RestTemplate是Spring框架提供的一个同步客户端,用于简化与RESTful Web服务的交互。可以用来发送HTTP请求和处理HTTP响应
,支持GET、POST、PUT、DELETE等常见的HTTP方法,可以发送带有请求头、请求体的复杂请求;自动将响应体转换为Java对象,支持处理不同的响应状态码和异常。
@Configuration
@ComponentScan
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
2. 使用RestTemplate在控制类中调用接口
@RestController
@RequestMapping("test")
public class TestController {
@Autowired
private RestTemplate restTemplate;
/**
* 测试调用接口
*/
@PostMapping("callingInterface")
public ResponseEntity<String> addResfood(@RequestParam("files") MultipartFile files) throws IOException {
String url = "http://example.com/uploadFiles"; // 替换为实际的文件上传接口URL
// 创建请求头
HttpHeaders headers = new HttpHeaders();
// 设置请求头,指定为 multipart/form-data 允许在一个请求中上传多个文件和其他表单字段。
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
// 创建请求体,将文件添加到请求中
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
// 将文件添加到请求中
body.add("files", new FileSystemResource(convert(files)));
// 创建请求实体,将请求头和请求体关联
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
// 发送 POST 请求
ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);
return response;
}
// 将 MultipartFile 转换为 File
private File convert(MultipartFile file) throws IOException {
// 创建临时文件 获取文件名称
File convFile = new File(file.getOriginalFilename());
// 将 MultipartFile 写入临时文件
try (FileOutputStream fos = new FileOutputStream(convFile)) {
fos.write(file.getBytes());
}
return convFile;
}
}
3. 测试
参考链接:
https://cloud.tencent.com/developer/article/1594124