当前位置: 首页 > news >正文

网站开发与建设方向济宁市城市建设投资中心网站

网站开发与建设方向,济宁市城市建设投资中心网站,网站开发微信授权登录,手机应用商店app下载官方版工厂模式是一种创建对象的设计模式&#xff0c;它将对象的创建和使用分离&#xff0c;通过一个工厂类来负责创建对象。 我以文件上传策略工厂为例/*** 文件上传策略工厂*/ Slf4j Component public class FileUploadStrategyFactory {private final Map<String, FileUploadSt…

工厂模式是一种创建对象的设计模式,它将对象的创建和使用分离,通过一个工厂类来负责创建对象。
我以文件上传策略工厂为例

/*** 文件上传策略工厂*/
@Slf4j
@Component
public class FileUploadStrategyFactory {private final Map<String, FileUploadStrategy> strategyMap = new ConcurrentHashMap<>();@Autowiredpublic FileUploadStrategyFactory(List<FileUploadStrategy> strategies) {for (FileUploadStrategy strategy : strategies) {strategyMap.put(strategy.getType(), strategy);}}/*** 获取文件上传策略** @param type 策略类型* @return 文件上传策略*/public FileUploadStrategy getStrategy(String type) {FileUploadStrategy strategy = strategyMap.get(type);if (strategy == null) {throw new IllegalArgumentException("不支持的文件上传类型: " + type);}return strategy;}/*** 获取所有策略类型** @return 策略类型列表*/public java.util.Set<String> getAllTypes() {return strategyMap.keySet();}
} 
/*** 文件上传策略接口*/
public interface FileUploadStrategy {/*** 获取策略类型*/String getType();/*** 上传文件** @param file 文件* @param config OSS配置* @return 上传结果*/FileUploadResult upload(MultipartFile file, SysOssConfig config);/*** 上传文件流** @param inputStream 文件流* @param fileName 文件名* @param contentType 文件类型* @param config OSS配置* @return 上传结果*/FileUploadResult upload(InputStream inputStream, String fileName, String contentType, SysOssConfig config);/*** 删除文件** @param fileName 文件名* @param config OSS配置* @return 删除结果*/boolean delete(String fileName, SysOssConfig config);/*** 获取文件预签名URL** @param fileName 文件名* @param config OSS配置* @param expireTime 过期时间(秒)* @return 预签名URL*/String getPresignedUrl(String fileName, SysOssConfig config, int expireTime);/*** 获取文件下载流** @param fileName 文件名* @param config OSS配置* @return 文件输入流* @throws IOException IO异常*/InputStream getFileInputStream(String fileName, SysOssConfig config) throws IOException;/*** 获取文件预览信息** @param fileName 文件名* @param config OSS配置* @return 预览信息* @throws IOException IO异常*/FilePreviewInfo getPreviewInfo(String fileName, String originalName, String contentType, long size, SysOssConfig config) throws IOException;
}

MinIO文件上传策略

/*** MinIO文件上传策略*/
@Slf4j
@Component
public class MinioFileUploadStrategy implements FileUploadStrategy {@Overridepublic String getType() {return "minio";}@Overridepublic FileUploadResult upload(MultipartFile file, SysOssConfig config) {try {MinioClient minioClient = createMinioClient(config);String originalName = file.getOriginalFilename();String fileName = generateFileName(originalName);String objectName = buildObjectName(fileName, config);// 确保桶存在ensureBucketExists(minioClient, config.getBucketName());// 上传文件minioClient.putObject(PutObjectArgs.builder().bucket(config.getBucketName()).object(objectName).stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build());// 构建访问URLString url = buildAccessUrl(config, objectName);return new FileUploadResult().setFileName(fileName).setOriginalName(originalName).setFileSuffix(FileUtils.getFileExtension(originalName)).setUrl(url).setSize(file.getSize()).setFilePath(objectName).setContentType(file.getContentType()).setConfigKey(config.getConfigKey()).setUploadStatus(1);} catch (Exception e) {log.error("MinIO文件上传失败", e);throw new RuntimeException("MinIO文件上传失败: " + e.getMessage());}}@Overridepublic FileUploadResult upload(InputStream inputStream, String fileName, String contentType, SysOssConfig config) {try {MinioClient minioClient = createMinioClient(config);String objectName = buildObjectName(fileName, config);// 确保桶存在ensureBucketExists(minioClient, config.getBucketName());// 由于无法直接获取InputStream的大小,使用-1让MinIO自动处理minioClient.putObject(PutObjectArgs.builder().bucket(config.getBucketName()).object(objectName).stream(inputStream, -1, 10485760) // 10MB part size.contentType(contentType).build());// 获取文件信息StatObjectResponse stat = minioClient.statObject(StatObjectArgs.builder().bucket(config.getBucketName()).object(objectName).build());// 构建访问URLString url = buildAccessUrl(config, objectName);return new FileUploadResult().setFileName(fileName).setOriginalName(fileName).setFileSuffix(FileUtils.getFileExtension(fileName)).setUrl(url).setSize(stat.size()).setFilePath(objectName).setContentType(contentType).setConfigKey(config.getConfigKey()).setUploadStatus(1);} catch (Exception e) {log.error("MinIO文件流上传失败", e);throw new RuntimeException("MinIO文件流上传失败: " + e.getMessage());}}@Overridepublic boolean delete(String fileName, SysOssConfig config) {try {MinioClient minioClient = createMinioClient(config);String objectName = config.getPrefix() + "/" + fileName;minioClient.removeObject(RemoveObjectArgs.builder().bucket(config.getBucketName()).object(objectName).build());return true;} catch (Exception e) {log.error("删除MinIO文件失败: {}", fileName, e);return false;}}@Overridepublic String getPresignedUrl(String fileName, SysOssConfig config, int expireTime) {try {MinioClient minioClient = createMinioClient(config);String objectName = config.getPrefix() + "/" + fileName;return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(config.getBucketName()).object(objectName).expiry(expireTime, TimeUnit.SECONDS).build());} catch (Exception e) {log.error("获取MinIO预签名URL失败: {}", fileName, e);return null;}}@Overridepublic InputStream getFileInputStream(String fileName, SysOssConfig config) throws IOException {try {MinioClient minioClient = createMinioClient(config);// 确保桶存在ensureBucketExists(minioClient, config.getBucketName());// 获取文件流return minioClient.getObject(GetObjectArgs.builder().bucket(config.getBucketName()).object(fileName).build());} catch (Exception e) {log.error("获取MinIO文件流失败: {}", e.getMessage(), e);throw new IOException("获取MinIO文件流失败: " + e.getMessage());}}@Overridepublic FilePreviewInfo getPreviewInfo(String fileName, String originalName, String contentType, long size, SysOssConfig config) throws IOException {try {MinioClient minioClient = createMinioClient(config);// 确保桶存在ensureBucketExists(minioClient, config.getBucketName());// 获取预签名URL,有效期10分钟String url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(config.getBucketName()).object(fileName).method(Method.GET).expiry(10, TimeUnit.MINUTES).build());// 构建预览信息FilePreviewInfo previewInfo = new FilePreviewInfo().setPreviewUrl(url).setContentType(contentType).setOriginalName(originalName).setSize(size);// 设置预览类型if (isImageFile(contentType)) {// 图片直接预览previewInfo.setPreviewType(1);} else if (isPdfFile(contentType)) {// PDF直接预览previewInfo.setPreviewType(3);} else if (isOfficeFile(contentType)) {// Office文档需要预览服务previewInfo.setPreviewType(2);previewInfo.setNeedConvert(true);} else if (isVideoFile(contentType)) {// 视频文件previewInfo.setPreviewType(4);} else if (isAudioFile(contentType)) {// 音频文件previewInfo.setPreviewType(5);} else if (isTextFile(contentType, originalName)) {// 文本文件previewInfo.setPreviewType(6);} else {// 不支持预览previewInfo.setPreviewType(0);}return previewInfo;} catch (Exception e) {log.error("获取MinIO预览信息失败: {}", e.getMessage(), e);throw new IOException("获取MinIO预览信息失败: " + e.getMessage());}}/*** 判断是否为文本文件*/private boolean isTextFile(String contentType, String fileName) {// 根据内容类型判断if (contentType != null && (contentType.equals("text/plain") ||contentType.equals("text/html") ||contentType.equals("text/css") ||contentType.equals("text/javascript") ||contentType.equals("application/json") ||contentType.equals("application/xml"))) {return true;}// 根据文件扩展名判断if (fileName != null) {String lowerName = fileName.toLowerCase();return lowerName.endsWith(".txt") ||lowerName.endsWith(".log") ||lowerName.endsWith(".ini") ||lowerName.endsWith(".json") ||lowerName.endsWith(".xml") ||lowerName.endsWith(".md") ||lowerName.endsWith(".csv");}return false;}private MinioClient createMinioClient(SysOssConfig config) {return MinioClient.builder().endpoint(config.getEndpoint()).credentials(config.getAccessKey(), config.getSecretKey()).region(config.getRegion()).build();}private void ensureBucketExists(MinioClient minioClient, String bucketName) throws Exception {boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());if (!exists) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());log.info("创建MinIO桶: {}", bucketName);}}private String generateFileName(String originalName) {String extension = FileUtils.getFileExtension(originalName);String uuid = UUID.randomUUID().toString().replace("-", "");return uuid + (StringUtils.hasText(extension) ? "." + extension : "");}private String buildObjectName(String fileName, SysOssConfig config) {String prefix = StringUtils.hasText(config.getPrefix()) ? config.getPrefix() : "upload";String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));return prefix + "/" + datePath + "/" + fileName;}private String buildAccessUrl(SysOssConfig config, String objectName) {String baseUrl = config.getDomain();if (!StringUtils.hasText(baseUrl)) {baseUrl = config.getEndpoint();}// 确保URL以/结尾if (!baseUrl.endsWith("/")) {baseUrl += "/";}return baseUrl + config.getBucketName() + "/" + objectName;}/*** 判断是否为图片文件*/private boolean isImageFile(String contentType) {return contentType != null && contentType.startsWith("image/");}/*** 判断是否为PDF文件*/private boolean isPdfFile(String contentType) {return contentType != null && contentType.equals("application/pdf");}/*** 判断是否为Office文件*/private boolean isOfficeFile(String contentType) {if (contentType == null) return false;return contentType.contains("word") ||contentType.contains("excel") ||contentType.contains("powerpoint") ||contentType.contains("ms-excel") ||contentType.contains("ms-word") ||contentType.contains("ms-powerpoint") ||contentType.contains("openxmlformats");}/*** 判断是否为视频文件*/private boolean isVideoFile(String contentType) {return contentType != null && contentType.startsWith("video/");}/*** 判断是否为音频文件*/private boolean isAudioFile(String contentType) {return contentType != null && contentType.startsWith("audio/");}
}

阿里云OSS文件上传策略

/*** 阿里云OSS文件上传策略*/
@Slf4j
@Component
public class AliyunOssFileUploadStrategy implements FileUploadStrategy {@Overridepublic String getType() {return "aliyun";}@Overridepublic FileUploadResult upload(MultipartFile file, SysOssConfig config) {OSS ossClient = null;try {ossClient = createOssClient(config);String originalName = file.getOriginalFilename();String fileName = generateFileName(originalName);String objectName = buildObjectName(fileName, config);// 创建上传Object的MetadataObjectMetadata metadata = new ObjectMetadata();metadata.setContentLength(file.getSize());metadata.setContentType(file.getContentType());metadata.setCacheControl("no-cache");metadata.setHeader("Pragma", "no-cache");metadata.setContentDisposition("inline;filename=" + originalName);// 上传文件PutObjectRequest putObjectRequest = new PutObjectRequest(config.getBucketName(), objectName, file.getInputStream(), metadata);ossClient.putObject(putObjectRequest);// 构建访问URLString url = buildAccessUrl(config, objectName);return new FileUploadResult().setFileName(fileName).setOriginalName(originalName).setFileSuffix(FileUtils.getFileExtension(originalName)).setUrl(url).setSize(file.getSize()).setFilePath(objectName).setContentType(file.getContentType()).setConfigKey(config.getConfigKey()).setUploadStatus(1);} catch (Exception e) {log.error("阿里云OSS文件上传失败", e);throw new RuntimeException("阿里云OSS文件上传失败: " + e.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}}@Overridepublic FileUploadResult upload(InputStream inputStream, String fileName, String contentType, SysOssConfig config) {OSS ossClient = null;try {ossClient = createOssClient(config);String objectName = buildObjectName(fileName, config);// 创建上传Object的MetadataObjectMetadata metadata = new ObjectMetadata();metadata.setContentType(contentType);metadata.setCacheControl("no-cache");metadata.setHeader("Pragma", "no-cache");metadata.setContentDisposition("inline;filename=" + fileName);// 上传文件PutObjectRequest putObjectRequest = new PutObjectRequest(config.getBucketName(), objectName, inputStream, metadata);ossClient.putObject(putObjectRequest);// 获取文件信息com.aliyun.oss.model.ObjectMetadata objMetadata = ossClient.getObjectMetadata(config.getBucketName(), objectName);long size = objMetadata.getContentLength();// 构建访问URLString url = buildAccessUrl(config, objectName);return new FileUploadResult().setFileName(fileName).setOriginalName(fileName).setFileSuffix(FileUtils.getFileExtension(fileName)).setUrl(url).setSize(size).setFilePath(objectName).setContentType(contentType).setConfigKey(config.getConfigKey()).setUploadStatus(1);} catch (Exception e) {log.error("阿里云OSS文件流上传失败", e);throw new RuntimeException("阿里云OSS文件流上传失败: " + e.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}}@Overridepublic boolean delete(String fileName, SysOssConfig config) {OSS ossClient = null;try {ossClient = createOssClient(config);String objectName = config.getPrefix() + "/" + fileName;ossClient.deleteObject(config.getBucketName(), objectName);return true;} catch (Exception e) {log.error("删除阿里云OSS文件失败: {}", fileName, e);return false;} finally {if (ossClient != null) {ossClient.shutdown();}}}@Overridepublic String getPresignedUrl(String fileName, SysOssConfig config, int expireTime) {OSS ossClient = null;try {ossClient = createOssClient(config);String objectName = config.getPrefix() + "/" + fileName;// 设置过期时间Date expiration = new Date(System.currentTimeMillis() + expireTime * 1000L);return ossClient.generatePresignedUrl(config.getBucketName(), objectName, expiration).toString();} catch (Exception e) {log.error("获取阿里云OSS预签名URL失败: {}", fileName, e);return null;} finally {if (ossClient != null) {ossClient.shutdown();}}}@Overridepublic InputStream getFileInputStream(String fileName, SysOssConfig config) throws IOException {OSS ossClient = null;try {ossClient = createOssClient(config);// 获取文件流OSSObject ossObject = ossClient.getObject(config.getBucketName(), fileName);return ossObject.getObjectContent();} catch (Exception e) {log.error("获取阿里云OSS文件流失败: {}", e.getMessage(), e);throw new IOException("获取阿里云OSS文件流失败: " + e.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}}@Overridepublic FilePreviewInfo getPreviewInfo(String fileName, String originalName, String contentType, long size, SysOssConfig config) throws IOException {OSS ossClient = null;try {ossClient = createOssClient(config);// 检查文件是否存在boolean exists = ossClient.doesObjectExist(config.getBucketName(), fileName);if (!exists) {log.error("阿里云OSS文件不存在: {}", fileName);throw new IOException("文件不存在: " + fileName);}// 获取签名URL,默认10分钟有效期Date expiration = new Date(System.currentTimeMillis() + 10 * 60 * 1000);GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(config.getBucketName(), fileName);request.setExpiration(expiration);URL signedUrl = ossClient.generatePresignedUrl(request);String url = signedUrl.toString();// 构建预览信息FilePreviewInfo previewInfo = new FilePreviewInfo().setPreviewUrl(url).setContentType(contentType).setOriginalName(originalName).setSize(size);// 设置预览类型if (isImageFile(contentType)) {// 图片直接预览previewInfo.setPreviewType(1);} else if (isPdfFile(contentType)) {// PDF直接预览previewInfo.setPreviewType(3);} else if (isOfficeFile(contentType)) {// Office文档需要预览服务previewInfo.setPreviewType(2);previewInfo.setNeedConvert(true);} else if (isVideoFile(contentType)) {// 视频文件previewInfo.setPreviewType(4);} else if (isAudioFile(contentType)) {// 音频文件previewInfo.setPreviewType(5);} else if (isTextFile(contentType, originalName)) {// 文本文件previewInfo.setPreviewType(6);} else {// 不支持预览previewInfo.setPreviewType(0);}return previewInfo;} catch (Exception e) {log.error("获取阿里云OSS预览信息失败: {}", e.getMessage(), e);throw new IOException("获取阿里云OSS预览信息失败: " + e.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}}/*** 判断是否为文本文件*/private boolean isTextFile(String contentType, String fileName) {// 根据内容类型判断if (contentType != null && (contentType.equals("text/plain") ||contentType.equals("text/html") ||contentType.equals("text/css") ||contentType.equals("text/javascript") ||contentType.equals("application/json") ||contentType.equals("application/xml"))) {return true;}// 根据文件扩展名判断if (fileName != null) {String lowerName = fileName.toLowerCase();return lowerName.endsWith(".txt") ||lowerName.endsWith(".log") ||lowerName.endsWith(".ini") ||lowerName.endsWith(".json") ||lowerName.endsWith(".xml") ||lowerName.endsWith(".md") ||lowerName.endsWith(".csv");}return false;}private OSS createOssClient(SysOssConfig config) {String endpoint = config.getEndpoint();if (config.getIsHttps() != null && config.getIsHttps() == 1) {if (!endpoint.startsWith("https://")) {endpoint = "https://" + endpoint.replace("http://", "");}} else {if (!endpoint.startsWith("http://")) {endpoint = "http://" + endpoint.replace("https://", "");}}return new OSSClientBuilder().build(endpoint, config.getAccessKey(), config.getSecretKey());}private String generateFileName(String originalName) {String extension = FileUtils.getFileExtension(originalName);String uuid = UUID.randomUUID().toString().replace("-", "");return uuid + (StringUtils.hasText(extension) ? "." + extension : "");}private String buildObjectName(String fileName, SysOssConfig config) {String prefix = StringUtils.hasText(config.getPrefix()) ? config.getPrefix() : "upload";String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));return prefix + "/" + datePath + "/" + fileName;}private String buildAccessUrl(SysOssConfig config, String objectName) {String baseUrl = config.getDomain();if (!StringUtils.hasText(baseUrl)) {String endpoint = config.getEndpoint();if (config.getIsHttps() != null && config.getIsHttps() == 1) {baseUrl = "https://" + config.getBucketName() + "." + endpoint.replace("https://", "").replace("http://", "");} else {baseUrl = "http://" + config.getBucketName() + "." + endpoint.replace("https://", "").replace("http://", "");}}// 确保URL以/结尾if (!baseUrl.endsWith("/")) {baseUrl += "/";}return baseUrl + objectName;}/*** 判断是否为图片文件*/private boolean isImageFile(String contentType) {return contentType != null && contentType.startsWith("image/");}/*** 判断是否为PDF文件*/private boolean isPdfFile(String contentType) {return contentType != null && contentType.equals("application/pdf");}/*** 判断是否为Office文件*/private boolean isOfficeFile(String contentType) {if (contentType == null) return false;return contentType.contains("word") ||contentType.contains("excel") ||contentType.contains("powerpoint") ||contentType.contains("ms-excel") ||contentType.contains("ms-word") ||contentType.contains("ms-powerpoint") ||contentType.contains("openxmlformats");}/*** 判断是否为视频文件*/private boolean isVideoFile(String contentType) {return contentType != null && contentType.startsWith("video/");}/*** 判断是否为音频文件*/private boolean isAudioFile(String contentType) {return contentType != null && contentType.startsWith("audio/");}
}

本地文件上传策略

/*** 本地文件上传策略*/
@Slf4j
@Component
public class LocalFileUploadStrategy implements FileUploadStrategy {@Value("${file.upload.path:./upload}")private String uploadPath;@Value("${server.servlet.context-path:}")private String contextPath;@Value("${server.port:8080}")private String serverPort;@Overridepublic String getType() {return "local";}@Overridepublic FileUploadResult upload(MultipartFile file, SysOssConfig config) {try {// 初始化上传路径initUploadPath();String originalName = file.getOriginalFilename();String fileName = generateFileName(originalName);String filePath = buildFilePath(fileName, config);String fullPath = getNormalizedPath(uploadPath, filePath);log.info("保存文件到: {}", fullPath);// 创建目录createDirectories(fullPath);// 保存文件File targetFile = new File(fullPath);try {file.transferTo(targetFile);} catch (IOException e) {log.error("保存文件失败: {}", e.getMessage());// 尝试使用替代方法保存try (FileOutputStream out = new FileOutputStream(targetFile)) {out.write(file.getBytes());}}// 确认文件已保存成功if (!targetFile.exists()) {throw new IOException("文件保存失败,无法在目标路径找到文件: " + targetFile.getAbsolutePath());}// 构建访问URLString url = buildAccessUrl(filePath);return new FileUploadResult().setFileName(fileName).setOriginalName(originalName).setFileSuffix(FileUtils.getFileExtension(originalName)).setUrl(url).setSize(file.getSize()).setFilePath(filePath).setContentType(file.getContentType()).setConfigKey(config.getConfigKey()).setUploadStatus(1);} catch (IOException e) {log.error("本地文件上传失败: {}", e.getMessage(), e);throw new RuntimeException("本地文件上传失败: " + e.getMessage());}}@Overridepublic FileUploadResult upload(InputStream inputStream, String fileName, String contentType, SysOssConfig config) {try {// 初始化上传路径initUploadPath();String filePath = buildFilePath(fileName, config);String fullPath = getNormalizedPath(uploadPath, filePath);log.info("保存文件流到: {}", fullPath);// 创建目录createDirectories(fullPath);// 保存文件File targetFile = new File(fullPath);try (FileOutputStream outputStream = new FileOutputStream(targetFile)) {byte[] buffer = new byte[8192];int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}}// 获取文件大小long size = targetFile.length();// 构建访问URLString url = buildAccessUrl(filePath);return new FileUploadResult().setFileName(fileName).setOriginalName(fileName).setFileSuffix(FileUtils.getFileExtension(fileName)).setUrl(url).setSize(size).setFilePath(filePath).setContentType(contentType).setConfigKey(config.getConfigKey()).setUploadStatus(1);} catch (IOException e) {log.error("本地文件流上传失败: {}", e.getMessage(), e);throw new RuntimeException("本地文件流上传失败: " + e.getMessage());}}@Overridepublic boolean delete(String fileName, SysOssConfig config) {try {String filePath = config.getPrefix() + File.separator + fileName;String fullPath = getNormalizedPath(uploadPath, filePath);File file = new File(fullPath);if (file.exists()) {return file.delete();}return true;} catch (Exception e) {log.error("删除本地文件失败: {}", fileName, e);return false;}}@Overridepublic String getPresignedUrl(String fileName, SysOssConfig config, int expireTime) {// 本地存储不需要预签名URL,直接返回访问URLString filePath = config.getPrefix() + File.separator + fileName;return buildAccessUrl(filePath);}@Overridepublic InputStream getFileInputStream(String fileName, SysOssConfig config) throws IOException {String fullPath = getNormalizedPath(uploadPath, fileName);log.debug("获取文件流: {}", fullPath);File file = new File(fullPath);if (!file.exists() || !file.isFile()) {log.error("文件不存在: {}", fullPath);throw new IOException("文件不存在: " + fileName);}return new FileInputStream(file);}@Overridepublic FilePreviewInfo getPreviewInfo(String fileName, String originalName, String contentType, long size, SysOssConfig config) throws IOException {String fullPath = getNormalizedPath(uploadPath, fileName);File file = new File(fullPath);if (!file.exists() || !file.isFile()) {log.error("文件不存在: {}", fullPath);throw new IOException("文件不存在: " + fileName);}// 构建URLString url = buildAccessUrl(fileName);// 判断文件类型,确定预览类型FilePreviewInfo previewInfo = new FilePreviewInfo().setPreviewUrl(url).setContentType(contentType).setOriginalName(originalName).setSize(size);// 设置预览类型if (isImageFile(contentType)) {// 图片直接预览previewInfo.setPreviewType(1);} else if (isPdfFile(contentType)) {// PDF直接预览previewInfo.setPreviewType(3);} else if (isOfficeFile(contentType)) {// Office文档需要预览服务previewInfo.setPreviewType(2);previewInfo.setNeedConvert(true);} else if (isVideoFile(contentType)) {// 视频文件previewInfo.setPreviewType(4);} else if (isAudioFile(contentType)) {// 音频文件previewInfo.setPreviewType(5);} else if (isTextFile(contentType, originalName)) {// 文本文件previewInfo.setPreviewType(6);} else {// 不支持预览previewInfo.setPreviewType(0);}return previewInfo;}private String generateFileName(String originalName) {String extension = FileUtils.getFileExtension(originalName);String uuid = UUID.randomUUID().toString().replace("-", "");return uuid + (StringUtils.hasText(extension) ? "." + extension : "");}private String buildFilePath(String fileName, SysOssConfig config) {// 直接使用日期路径,不添加额外的前缀,避免重复的upload目录String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));return datePath + File.separator + fileName;}/*** 初始化上传根目录*/private void initUploadPath() throws IOException {File uploadDir = new File(uploadPath);if (!uploadDir.exists()) {log.info("创建上传根目录: {}", uploadPath);if (!uploadDir.mkdirs()) {throw new IOException("无法创建上传根目录: " + uploadPath);}}}/*** 获取规范化的完整路径*/private String getNormalizedPath(String basePath, String relativePath) {// 确保基础路径不以分隔符结尾if (basePath.endsWith(File.separator)) {basePath = basePath.substring(0, basePath.length() - 1);}// 确保相对路径不以分隔符开头if (relativePath.startsWith(File.separator)) {relativePath = relativePath.substring(1);}// 组合并规范化路径Path path = Paths.get(basePath, relativePath).normalize();return path.toString();}private void createDirectories(String fullPath) throws IOException {try {Path path = Paths.get(fullPath).getParent();if (path != null && !Files.exists(path)) {log.info("创建目录: {}", path);Files.createDirectories(path);}} catch (IOException e) {log.error("创建目录失败: {}", e.getMessage(), e);// 尝试使用File API创建目录File directory = new File(Paths.get(fullPath).getParent().toString());if (!directory.exists() && !directory.mkdirs()) {throw new IOException("无法创建目录: " + directory.getAbsolutePath());}}}private String buildAccessUrl(String filePath) {// 构建完整的访问URLString baseUrl = "";// 获取当前主机名和端口baseUrl = "http://localhost:" + serverPort;if (StringUtils.hasText(contextPath) && !contextPath.equals("/")) {baseUrl += contextPath;}// 将Windows风格的路径分隔符替换为URL路径分隔符String normalizedPath = filePath.replace(File.separator, "/");return baseUrl + "/file/" + normalizedPath;}/*** 判断是否为图片文件*/private boolean isImageFile(String contentType) {return contentType != null && contentType.startsWith("image/");}/*** 判断是否为PDF文件*/private boolean isPdfFile(String contentType) {return contentType != null && contentType.equals("application/pdf");}/*** 判断是否为Office文件*/private boolean isOfficeFile(String contentType) {if (contentType == null) return false;return contentType.contains("word") ||contentType.contains("excel") ||contentType.contains("powerpoint") ||contentType.contains("ms-excel") ||contentType.contains("ms-word") ||contentType.contains("ms-powerpoint") ||contentType.contains("openxmlformats");}/*** 判断是否为视频文件*/private boolean isVideoFile(String contentType) {return contentType != null && contentType.startsWith("video/");}/*** 判断是否为音频文件*/private boolean isAudioFile(String contentType) {return contentType != null && contentType.startsWith("audio/");}/*** 判断是否为文本文件*/private boolean isTextFile(String contentType, String fileName) {// 根据内容类型判断if (contentType != null && (contentType.equals("text/plain") ||contentType.equals("text/html") ||contentType.equals("text/css") ||contentType.equals("text/javascript") ||contentType.equals("application/json") ||contentType.equals("application/xml"))) {return true;}// 根据文件扩展名判断if (fileName != null) {String lowerName = fileName.toLowerCase();return lowerName.endsWith(".txt") ||lowerName.endsWith(".log") ||lowerName.endsWith(".ini") ||lowerName.endsWith(".json") ||lowerName.endsWith(".xml") ||lowerName.endsWith(".md") ||lowerName.endsWith(".csv");}return false;}
}


FileUploadStrategyFactory 就是工厂类,它负责创建和管理不同类型的 FileUploadStrategy 对象。FileUploadStrategy 是一个接口,定义了文件上传策略的通用方法,而 AliyunOssFileUploadStrategy 等实现类则是具体的策略实现。

FileUploadStrategyFactory 类通过一个 Map 来存储不同类型的 FileUploadStrategy 对象,键是策略类型(如 "aliyun"),值是对应的策略对象。这样,当需要使用某个具体的文件上传策略时,只需要通过策略类型从工厂类中获取对应的策略对象即可,而不需要直接实例化具体的策略类。

FileUploadStrategyFactory 构造方法的含义和触发机制

    @Autowiredpublic FileUploadStrategyFactory(List<FileUploadStrategy> strategies) {for (FileUploadStrategy strategy : strategies) {strategyMap.put(strategy.getType(), strategy);}}

当 Spring 容器启动时,它会自动扫描所有的组件(使用 @Component@Service 等注解标记的类),并创建这些组件的实例。在创建 FileUploadStrategyFactory 实例时,Spring 会根据 @Autowired 注解的要求,自动查找所有实现了 FileUploadStrategy 接口的 Bean,并将它们作为一个 List 注入到 FileUploadStrategyFactory 的构造方法中。

我有三个不同的 FileUploadStrategy 实现类:AliyunOssFileUploadStrategy、LocalFileUploadStrategy 和 MinioFileUploadStrategy,Spring 容器会自动创建这三个类的实例,并将它们作为一个 List 注入到 FileUploadStrategyFactory 的构造方法中。然后,FileUploadStrategyFactory 会将这三个策略对象存储在 strategyMap 中,以便后续使用。

http://www.dtcms.com/a/444336.html

相关文章:

  • 快速做网站团队电子商务网站建设方案设计报告
  • 赣州营销型网站策划网页编辑模式快捷键
  • 网站响应是什么问题吗南昌住房城市建设支行官方网站
  • 网站不允许上传文件大连在哪里哪个省
  • 成都网站建设快速服务wordpress博客没有找到
  • 浦东新区网站优化推广wordpress自适应框架
  • 济南一哥网站建设公司怎样下载手机app
  • 自己怎么做可以让百度收录的网站安康市集约化平台
  • 一屏式网站有什么好处智能设计平台
  • 室内设计招聘网站有哪些h5建站免费
  • 查询网站备案显示划横线发布新闻
  • 智能手机网站建设黑龙江 俄语网站制作
  • 新动力网站建设公司淄博网站建设培训
  • Mysql速成笔记3(单表DQL)
  • 博客优化网站seo怎么写网络科技公司起名大全免费
  • pycharm运行时将控制台显示的内容保存下来
  • 钟表商城网站建设方案百度竞价广告的位置
  • 网站备案系统知乎自媒体平台注册
  • 广州建网站的网络公司深圳市做门窗网站有哪些推广
  • 罗湖区网站公司2022年免费ppt模板下载
  • 万维建设网站企业文化ppt模板免费
  • 用word 做网站建设部网站 标准定额司
  • 职场社交网站怎么做环球旅行社网站建设规划书论文
  • 在手机上怎么制作网站公众号商城
  • word怎么做网站链接青岛建韩国网站的公司
  • 如何企业网站的软文西安短视频制作公司
  • 音乐网站开发的目的闵行网络推广公司
  • 5g互联如何取消网站备案wordpress支付宝接口
  • 长沙品质网站建设优点网站开发工作总结
  • 设计网站排行榜前十名可以在家做兼职的网站