在一般的系统中,都会为用户提供头像设置的服务,这里我提供一种使用Json序列化的方式来实现头像上传的方法。在下面分析来Json序列化处理头像上传的原理以及拿一个简单的案例来实现(案例只是对思想的一种重现)
JsonSerializer
JsonSerialize
就是今天要介绍的主角,JsonSerializer是一个用于将对象序列化为JSON字符串的类。在.NET框架中,JsonSerializer通常与JsonDeserializer一起使用,用于将对象序列化和反序列化为JSON格式。下面对常用的方法以及源码进行分析:
- 以下是JsonSerializer的源码详细介绍和常用方法的使用方法:
JsongSerializer是一个抽象类,需要它子类去实现它所定义的方法,当您定义一个自定义的Java类来序列化为JSON字符串时,您可以继承JsonSerializer类并实现其中的抽象方法来定义自己的序列化逻辑。JsonSerializer是一个泛型类,它的类型参数T指定要序列化的Java对象类型。此外,该类实现了JsonFormatVisitable接口,这允许访问者模式来处理数据格式
public abstract class JsonSerializer<T> implements JsonFormatVisitable {
//默认构造函数
public JsonSerializer() {
}
public JsonSerializer<T> unwrappingSerializer(NameTransformer unwrapper) {
return this;
}
public JsonSerializer<T> replaceDelegatee(JsonSerializer<?> delegatee) {
throw new UnsupportedOperationException();
}
public JsonSerializer<?> withFilterId(Object filterId) {
return this;
}
public abstract void serialize(T var1, JsonGenerator var2, SerializerProvider var3) throws IOException;
public void serializeWithType(T value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException {
Class<?> clz = this.handledType();
if (clz == null) {
clz = value.getClass();
}
serializers.reportBadDefinition(clz, String.format("Type id handling not implemented for type %s (by serializer of type %s)", clz.getName(), this.getClass().getName()));
}
public Class<T> handledType() {
return null;
}
/** @deprecated */
@Deprecated
public boolean isEmpty(T value) {
return this.isEmpty((SerializerProvider)null, value);
}
public boolean isEmpty(SerializerProvider provider, T value) {
return value == null;
}
public boolean usesObjectId() {
return false;
}
public boolean isUnwrappingSerializer() {
return false;
}
public JsonSerializer<?> getDelegatee() {
return null;
}
public Iterator<PropertyWriter> properties() {
return ClassUtil.emptyIterator();
}
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException {
visitor.expectAnyFormat(type);
}
public abstract static class None extends JsonSerializer<Object> {
public None() {
}
}
}
下面对部分源码进行逐一的讲解
方法unwrappingSerializer(NameTransformer unwrapper)的返回值是一个JsonSerializer对象。该方法接受一个NameTransformer类型的参数unwrapper,该参数用于转换名称。但是,由于该方法的实现为空,它不会进行任何转换并返回其调用对象。
public JsonSerializer<T> unwrappingSerializer(NameTransformer unwrapper) {
return this;
}
方法replaceDelegatee(JsonSerializer<?> delegatee)抛出一个UnsupportedOperationException异常。这表示不支持代理方法的替换。
public JsonSerializer<T> replaceDelegatee(JsonSerializer<?> delegatee) {
throw new UnsupportedOperationException();
}
方法withFilterId(Object filterId)的返回值也是一个JsonSerializer<?>对象。该方法接受一个Object类型的参数filterId,该参数用于指定对象的标识符。但是,由于该方法的实现为空,它不会进行任何操作并返回其调用对象。
public JsonSerializer<?> withFilterId(Object filterId) {
return this;
}
抽象方法serialize(T var1, JsonGenerator var2, SerializerProvider var3)是序列化Java对象的核心方法。它接受一个类型为T的对象var1、一个JsonGenerator对象var2和一个SerializerProvider对象var3作为参数,并抛出IOException异常。该方法应实现将var1对象序列化为JSON字符串的逻辑,并将结果写入var2。
public abstract void serialize(T var1, JsonGenerator var2, SerializerProvider var3) throws IOException;
方法serializeWithType(T value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer)是可选的,它允许在序列化期间指定类型。该方法接受一个类型为T的对象value、一个JsonGenerator对象gen、一个SerializerProvider对象serializers和一个TypeSerializer对象typeSer作为参数,并抛出IOException异常。如果实现类没有覆盖handledType()方法,则该方法将报告无法处理的类型。
public void serializeWithType(T value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException {
Class<?> clz = this.handledType();
if (clz == null) {
clz = value.getClass();
}
方法handledType()是一个抽象方法,它返回要序列化的Java对象类型的Class对象。如果序列化类处理多种类型,则可以在此方法中返回null。
public Class<T> handledType() {
return null;
}
案例分析
下面
ImgJsonSerializer
该方法继承了JsonSerializer类,这是对上面JsonSerializer实现的子类,并重写了JsongSerializer方法
@Component
@RefreshScope
public class ImgJsonSerializer extends JsonSerializer<String> {
//imgDomain是图像的地址,这里我的头像都是存储在minio服务器上,所以地址配置信息是从nacos中拉取下来的,如果你的地址是本地或是其它地址,可以赋值为自己的头像存储地址
@Value("${biz.oss.resources-url}")
private String imgDomain;
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
//下面的if是用来判断
if (StrUtil.isBlank(value)) {//判断字符串是否为空
gen.writeString(StrUtil.EMPTY); //如果为空则将空字符串进行序列化
return;
} else if (StrUtil.isBlank(imgDomain)) {//如果指定的图片域名为空或者空白符
gen.writeString(value);//直接将字符串序列化
return;
}
String[] imgs = value.split(StrUtil.COMMA);// 将逗号分隔的字符串切割成数组
StringBuilder sb = new StringBuilder();//创建一个字符串拼接器
for (String img : imgs) {//遍历数组中的每一个字符串
if (PrincipalUtil.isHttpProtocol(img)) {//如果图片 URL 以 http 开始
sb.append(img).append(StrUtil.COMMA);// 直接将其拼接到结果字符串中
}
else {
sb.append(imgDomain).append(img).append(StrUtil.COMMA);// 否则将其拼接到图片域名后面
}
}
sb.deleteCharAt(sb.length() - 1);// 删除结果字符串中最后一个逗号
gen.writeString(sb.toString()); // 将结果字符串序列化到 JSON 中
}
}
这段代码是用于将字符串类型的数据进行序列化,生成符合 JSON 格式的输出数据,并支持图片域名的处理。
- 首先,该方法重写了父类方法 serialize() ,用于实现自定义的序列化逻辑。
- 接下来,对序列化值进行判断,如果为空,则输出空字符串;如果图片域名为空,则原样输出序列化值。
- 如果图片域名不为空,则将序列化值按照逗号分隔符进行分割,然后进行遍历处理每个图片地址。
- 对于图片地址以 http协议开头的,直接将其追加到字符串构建器中。
- 对于不以 http协议开头的图片地址,则将其与图片域名进行拼接,然后再追加到字符串构建器中。
- 最后,将字符串构建器中的结果删除最后一个逗号,然后使用 gen.writeString() 方法输出 JSON 格式的字符串。
总结:该方法的作用是对字符串类型的数据进行序列化,支持将图片地址与图片域名进行拼接处理,生成符合 JSON 格式的输出数据,以便于数据传输和存储操作。所以以上的代码总体来说就是处理图像的域名