在一般的系统中,都会为用户提供头像设置的服务,这里我提供一种使用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 格式的输出数据,并支持图片域名的处理。

  1. 首先,该方法重写了父类方法 serialize() ,用于实现自定义的序列化逻辑。
  2. 接下来,对序列化值进行判断,如果为空,则输出空字符串;如果图片域名为空,则原样输出序列化值。
  3. 如果图片域名不为空,则将序列化值按照逗号分隔符进行分割,然后进行遍历处理每个图片地址。
  4. 对于图片地址以 http协议开头的,直接将其追加到字符串构建器中。
  5. 对于不以 http协议开头的图片地址,则将其与图片域名进行拼接,然后再追加到字符串构建器中。
  6. 最后,将字符串构建器中的结果删除最后一个逗号,然后使用 gen.writeString() 方法输出 JSON 格式的字符串。

总结:该方法的作用是对字符串类型的数据进行序列化,支持将图片地址与图片域名进行拼接处理,生成符合 JSON 格式的输出数据,以便于数据传输和存储操作。所以以上的代码总体来说就是处理图像的域名

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐