如何在Java项目中使用自定义序列化器处理URL
在Java开发中,处理和序列化URL是一个常见的需求,尤其是在涉及到图像资源时。如果项目需要根据特定条件处理图像URL(如添加前缀),可以自定义一个序列化器来简化这一过程。
本文将介绍如何创建一个自定义的ImgJsonSerializer
类,处理单个URL和URL列表,并在序列化过程中动态添加前缀。
1. 项目背景
在许多项目中,图像资源的URL可能存储为相对路径或者完整的URL。如果你的应用程序需要统一处理这些URL,可能需要在序列化JSON时添加一个域名或路径前缀。这种处理可以在序列化时自动完成,无需在业务逻辑中重复代码。
2. 需求描述
我们需要一个自定义的JSON序列化器ImgJsonSerializer
,能够处理以下两种情况:
- 单个URL字符串:对单个图像URL进行序列化,如果URL是相对路径,则添加一个前缀。
- URL字符串列表:对URL列表进行序列化,遍历列表并对每个URL进行前缀处理。
3. 自定义序列化器的实现
我们将使用Jackson库自定义序列化器。首先,确保项目中已经添加了Jackson的相关依赖。如果没有,请自行添加。
接下来,创建自定义序列化器ImgJsonSerializer
:
点击查看MinioProperties代码
"""
application.yml配置如下
minio:
endpoint: http://localhost:9000 # MinIO服务器的URL
access-key: adminminio # 访问密钥
secret-key: adminminio # 密钥密码
bucket-name: works # 默认的Bucket名称
secure: false # 是否使用HTTPS(如果使用HTTPS,请设置为true)
"""
package com.echo.common.minio;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "minio")
@Data
public class MinioProperties {
private String endpoint;
private String accessKey;
private String secretKey;
private String bucketName;
private String secure;
}
因为我这使用的是Minio对象存储,配置了MinioProperties类
package com.echo.common.ImgJson;
import cn.hutool.core.lang.PatternPool;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.echo.common.minio.MinioProperties;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.List;
@Component
public class ImgJsonSerializer extends JsonSerializer<Object> {
@Autowired
private MinioProperties properties;
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value == null) {
gen.writeString(StrUtil.EMPTY);
return;
}
if (value instanceof String) {
String img = (String) value;
if (StrUtil.isBlank(img)) {
gen.writeString(StrUtil.EMPTY);
} else if (ReUtil.isMatch(PatternPool.URL_HTTP, img)) {
gen.writeString(img);
} else {
gen.writeString(properties.getEndpoint() + img);
}
} else if (value instanceof List<?> list) {
gen.writeStartArray();
for (Object item : list) {
if (item instanceof String img) {
if (StrUtil.isBlank(img)) {
gen.writeString(StrUtil.EMPTY);
} else if (ReUtil.isMatch(PatternPool.URL_HTTP, img)) {
gen.writeString(img);
} else {
gen.writeString(properties.getEndpoint() + img);
}
}
}
gen.writeEndArray();
} else {
throw new IllegalArgumentException("Unsupported value type: " + value.getClass().getName());
}
}
}
4. 如何使用自定义序列化器
在实体类中,将@JsonSerialize(using = ImgJsonSerializer.class)
注解添加到需要序列化的字段上。无论是单个字符串还是字符串列表,ImgJsonSerializer
将根据实际类型进行处理。
对于单个URL字段:
@JsonSerialize(using = ImgJsonSerializer.class)
private String imgUrl;
对于URL列表字段:
@JsonSerialize(using = ImgJsonSerializer.class)
private List<String> imgUrls;
5. 测试和验证
确保MinioProperties
类配置了正确的前缀,并且在应用程序中正确注入。然后你可以创建测试数据,序列化对象,并验证输出的JSON是否符合预期。
示例测试代码:
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new SimpleModule().addSerializer(Object.class, new ImgJsonSerializer()));
MyEntity entity = new MyEntity();
entity.setImgUrl("image.jpg"); // 假设前缀是 http://localhost:9000/
entity.setImgUrls(Arrays.asList("image1.jpg", "http://example.com/image2.jpg"));
String json = mapper.writeValueAsString(entity);
System.out.println(json);
}
6. 总结
通过创建自定义的ImgJsonSerializer
,我们可以灵活地处理单个URL和URL列表,并在序列化过程中添加必要的前缀。这种方法使得处理图像URL变得更加简洁和统一,有助于保持代码的整洁性和可维护性。