feat(framework): OssPresignResponseBodyAdvice 支持 List<String> 字段预签名
- @OssPresignUrl 注解现在同时适用于 String 和 List<String> 字段 - 回填时防御不可变 List,自动降级为 ArrayList - FileServiceImpl 预签名访问 URL 去除查询参数,保持持久化路径干净 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -130,8 +130,21 @@ public class OssPresignResponseBodyAdvice implements ResponseBodyAdvice<Object>
|
|||||||
String signed = signedMap.get(entry.url);
|
String signed = signedMap.get(entry.url);
|
||||||
if (signed != null) {
|
if (signed != null) {
|
||||||
try {
|
try {
|
||||||
|
if (entry.isList()) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<String> list = (List<String>) entry.field.get(entry.target);
|
||||||
|
try {
|
||||||
|
list.set(entry.index(), signed);
|
||||||
|
} catch (UnsupportedOperationException ex) {
|
||||||
|
// 不可变 List(如 List.of()),替换为可变 ArrayList 后重试
|
||||||
|
List<String> mutable = new ArrayList<>(list);
|
||||||
|
mutable.set(entry.index(), signed);
|
||||||
|
entry.field.set(entry.target, mutable);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
entry.field.set(entry.target, signed);
|
entry.field.set(entry.target, signed);
|
||||||
} catch (IllegalAccessException e) {
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
log.warn("[OssPresignResponseBodyAdvice] 回填签名 URL 失败: field={}", entry.field.getName(), e);
|
log.warn("[OssPresignResponseBodyAdvice] 回填签名 URL 失败: field={}", entry.field.getName(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,6 +208,15 @@ public class OssPresignResponseBodyAdvice implements ResponseBodyAdvice<Object>
|
|||||||
if (value instanceof String url && StrUtil.isNotEmpty(url)) {
|
if (value instanceof String url && StrUtil.isNotEmpty(url)) {
|
||||||
entries.add(new FieldEntry(obj, field, url));
|
entries.add(new FieldEntry(obj, field, url));
|
||||||
}
|
}
|
||||||
|
// 带注解的 List<String> 字段:逐个收集 URL
|
||||||
|
if (value instanceof List<?> list) {
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Object item = list.get(i);
|
||||||
|
if (item instanceof String url && StrUtil.isNotEmpty(url)) {
|
||||||
|
entries.add(new FieldEntry(obj, field, i, url));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 非简单类型字段:递归(递归入口会再次判断 isProjectClass)
|
// 非简单类型字段:递归(递归入口会再次判断 isProjectClass)
|
||||||
collectUrls(value, entries, visited, depth + 1);
|
collectUrls(value, entries, visited, depth + 1);
|
||||||
@@ -221,7 +243,8 @@ public class OssPresignResponseBodyAdvice implements ResponseBodyAdvice<Object>
|
|||||||
return FIELD_CACHE.computeIfAbsent(clazz, c -> {
|
return FIELD_CACHE.computeIfAbsent(clazz, c -> {
|
||||||
Set<Field> result = new HashSet<>();
|
Set<Field> result = new HashSet<>();
|
||||||
for (Field field : getAllFields(c)) {
|
for (Field field : getAllFields(c)) {
|
||||||
if (field.isAnnotationPresent(OssPresignUrl.class) && field.getType() == String.class) {
|
if (field.isAnnotationPresent(OssPresignUrl.class)
|
||||||
|
&& (field.getType() == String.class || List.class.isAssignableFrom(field.getType()))) {
|
||||||
result.add(field);
|
result.add(field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -340,6 +363,16 @@ public class OssPresignResponseBodyAdvice implements ResponseBodyAdvice<Object>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private record FieldEntry(Object target, Field field, String url) {}
|
private record FieldEntry(Object target, Field field, int index, String url) {
|
||||||
|
|
||||||
|
/** String 字段构造 */
|
||||||
|
FieldEntry(Object target, Field field, String url) {
|
||||||
|
this(target, field, -1, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isList() {
|
||||||
|
return index >= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public class FileServiceImpl implements FileService {
|
|||||||
// 2. 获取文件预签名地址
|
// 2. 获取文件预签名地址
|
||||||
FileClient fileClient = fileConfigService.getMasterFileClient();
|
FileClient fileClient = fileConfigService.getMasterFileClient();
|
||||||
String uploadUrl = fileClient.presignPutUrl(path);
|
String uploadUrl = fileClient.presignPutUrl(path);
|
||||||
String visitUrl = fileClient.presignGetUrl(path, null);
|
String visitUrl = HttpUtils.removeUrlQuery(fileClient.presignGetUrl(path, null));
|
||||||
return new FilePresignedUrlRespVO().setConfigId(fileClient.getId())
|
return new FilePresignedUrlRespVO().setConfigId(fileClient.getId())
|
||||||
.setPath(path).setUploadUrl(uploadUrl).setUrl(visitUrl);
|
.setPath(path).setUploadUrl(uploadUrl).setUrl(visitUrl);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user