89 lines
3.0 KiB
Java
89 lines
3.0 KiB
Java
package cn.van.business.controller;
|
||
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.beans.factory.annotation.Value;
|
||
import org.springframework.core.io.FileSystemResource;
|
||
import org.springframework.core.io.Resource;
|
||
import org.springframework.http.HttpHeaders;
|
||
import org.springframework.http.MediaType;
|
||
import org.springframework.http.ResponseEntity;
|
||
import org.springframework.web.bind.annotation.GetMapping;
|
||
import org.springframework.web.bind.annotation.PathVariable;
|
||
import org.springframework.web.bind.annotation.RequestMapping;
|
||
import org.springframework.web.bind.annotation.RestController;
|
||
|
||
import java.io.File;
|
||
import java.nio.file.Files;
|
||
import java.nio.file.Path;
|
||
import java.nio.file.Paths;
|
||
|
||
/**
|
||
* 图片访问控制器
|
||
* 用于访问转换后的jpg图片
|
||
*
|
||
* @author System
|
||
*/
|
||
@Slf4j
|
||
@RestController
|
||
@RequestMapping("/images")
|
||
public class ImageController {
|
||
|
||
/**
|
||
* 图片存储根目录
|
||
*/
|
||
@Value("${image.convert.storage-path:${java.io.tmpdir}/comment-images}")
|
||
private String storagePath;
|
||
|
||
/**
|
||
* 获取转换后的图片
|
||
*
|
||
* @param filename 文件名(通常是MD5值.jpg)
|
||
* @return 图片文件
|
||
*/
|
||
@GetMapping("/{filename:.+}")
|
||
public ResponseEntity<Resource> getImage(@PathVariable String filename) {
|
||
try {
|
||
// 安全检查:防止路径遍历攻击
|
||
if (filename.contains("..") || filename.contains("/") || filename.contains("\\")) {
|
||
log.warn("非法的文件名请求: {}", filename);
|
||
return ResponseEntity.badRequest().build();
|
||
}
|
||
|
||
Path filePath = Paths.get(storagePath, filename);
|
||
File file = filePath.toFile();
|
||
|
||
if (!file.exists() || !file.isFile()) {
|
||
log.warn("图片文件不存在: {}", filePath);
|
||
return ResponseEntity.notFound().build();
|
||
}
|
||
|
||
// 检查文件是否在存储目录内(防止路径遍历)
|
||
Path storageDir = Paths.get(storagePath).toAbsolutePath().normalize();
|
||
Path resolvedPath = filePath.toAbsolutePath().normalize();
|
||
if (!resolvedPath.startsWith(storageDir)) {
|
||
log.warn("非法的文件路径访问: {}", resolvedPath);
|
||
return ResponseEntity.badRequest().build();
|
||
}
|
||
|
||
Resource resource = new FileSystemResource(file);
|
||
|
||
// 判断文件类型
|
||
String contentType = Files.probeContentType(filePath);
|
||
if (contentType == null) {
|
||
// 如果无法探测,默认使用image/jpeg
|
||
contentType = MediaType.IMAGE_JPEG_VALUE;
|
||
}
|
||
|
||
return ResponseEntity.ok()
|
||
.contentType(MediaType.parseMediaType(contentType))
|
||
.header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + filename + "\"")
|
||
.body(resource);
|
||
|
||
} catch (Exception e) {
|
||
log.error("获取图片失败: {}", filename, e);
|
||
return ResponseEntity.internalServerError().build();
|
||
}
|
||
}
|
||
}
|
||
|