From efdb727e4823d679ac9c7f520a692bc64456d833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=92?= Date: Mon, 3 Nov 2025 15:46:21 +0800 Subject: [PATCH] 1 --- .../business/service/ImageConvertService.java | 85 +++++++++++++++---- 1 file changed, 67 insertions(+), 18 deletions(-) diff --git a/src/main/java/cn/van/business/service/ImageConvertService.java b/src/main/java/cn/van/business/service/ImageConvertService.java index e5b1275..3af343c 100644 --- a/src/main/java/cn/van/business/service/ImageConvertService.java +++ b/src/main/java/cn/van/business/service/ImageConvertService.java @@ -2,7 +2,6 @@ package cn.van.business.service; import cn.van.business.model.pl.ImageConversion; import cn.van.business.repository.ImageConversionRepository; -import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import lombok.extern.slf4j.Slf4j; @@ -16,9 +15,7 @@ import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -97,22 +94,37 @@ public class ImageConvertService { return Collections.emptyList(); } + log.info("开始转换图片URL列表,共{}张图片", imageUrls.size()); List convertedUrls = new ArrayList<>(); + int successCount = 0; + int skipCount = 0; + for (String imageUrl : imageUrls) { if (StrUtil.isBlank(imageUrl)) { continue; } + log.debug("处理图片URL: {}", imageUrl); try { String convertedUrl = convertImageUrl(imageUrl); + if (!convertedUrl.equals(imageUrl)) { + successCount++; + log.debug("图片转换成功: {} -> {}", imageUrl, convertedUrl); + } else { + skipCount++; + log.debug("图片无需转换(非webp格式): {}", imageUrl); + } convertedUrls.add(convertedUrl); } catch (Exception e) { // 转换失败时使用原URL,不中断流程 + skipCount++; log.warn("图片转换失败,使用原URL: {}. 错误: {}", imageUrl, e.getMessage()); convertedUrls.add(imageUrl); } } + log.info("图片URL转换完成,共{}张,成功转换{}张,跳过/失败{}张", + imageUrls.size(), successCount, skipCount); return convertedUrls; } @@ -128,31 +140,59 @@ public class ImageConvertService { return originalUrl; } + // 规范化URL:处理协议相对URL(//开头) + String normalizedUrl = normalizeUrl(originalUrl); + // 检查是否为webp格式 - if (!isWebpFormat(originalUrl)) { - return originalUrl; + if (!isWebpFormat(normalizedUrl)) { + return originalUrl; // 返回原URL,保持一致性 } // 检查系统是否支持webp转换 if (!WebPImageIO.isWebPSupported()) { - log.debug("系统不支持webp格式,跳过转换: {}", originalUrl); + log.warn("系统不支持webp格式,跳过转换: {}", normalizedUrl); throw new IOException("系统不支持webp格式转换"); } - // 检查是否已转换 - Optional existing = imageConversionRepository.findByOriginalUrl(originalUrl); + // 使用规范化后的URL进行缓存查询和转换 + // 检查是否已转换(使用规范化URL作为key) + Optional existing = imageConversionRepository.findByOriginalUrl(normalizedUrl); if (existing.isPresent()) { ImageConversion conversion = existing.get(); - log.debug("使用缓存的转换结果: {} -> {}", originalUrl, conversion.getConvertedUrl()); + log.debug("使用缓存的转换结果: {} -> {}", normalizedUrl, conversion.getConvertedUrl()); return conversion.getConvertedUrl(); } - // 执行转换 - String convertedUrl = performConversion(originalUrl); - log.info("图片转换成功: {} -> {}", originalUrl, convertedUrl); + // 执行转换(使用规范化URL) + log.info("开始转换webp图片: {}", normalizedUrl); + String convertedUrl = performConversion(normalizedUrl); + log.info("图片转换成功: {} -> {}", normalizedUrl, convertedUrl); return convertedUrl; } + /** + * 规范化URL:处理协议相对URL等特殊情况 + * + * @param url 原始URL + * @return 规范化后的URL + */ + private String normalizeUrl(String url) { + if (StrUtil.isBlank(url)) { + return url; + } + + // 清理特殊字符(如零宽字符) + String cleanUrl = url.trim().replaceAll("[\\u200B-\\u200D\\uFEFF]", ""); + + // 处理协议相对URL(//开头) + if (cleanUrl.startsWith("//")) { + cleanUrl = "https:" + cleanUrl; + log.debug("转换协议相对URL: {} -> {}", url, cleanUrl); + } + + return cleanUrl; + } + /** * 检查URL是否为webp格式 * @@ -164,13 +204,22 @@ public class ImageConvertService { return false; } - // 检查URL中是否包含.webp - String lowerUrl = url.toLowerCase(); + // 清理URL中的特殊字符(如零宽字符) + String cleanUrl = url.trim().replaceAll("[\\u200B-\\u200D\\uFEFF]", ""); + + // 检查URL中是否包含.webp扩展名(不区分大小写) + String lowerUrl = cleanUrl.toLowerCase(); // 检查URL参数或路径中是否包含webp - return lowerUrl.contains(".webp") || - lowerUrl.contains("format=webp") || - lowerUrl.contains("?webp") || - lowerUrl.contains("&webp"); + boolean isWebp = lowerUrl.contains(".webp") || + lowerUrl.contains("format=webp") || + lowerUrl.contains("?webp") || + lowerUrl.contains("&webp"); + + if (isWebp) { + log.debug("检测到webp格式图片: {}", cleanUrl); + } + + return isWebp; } /**