Skip to content

Commit

Permalink
修复复杂 TranslationComponent 组件序列化、反序列化问题
Browse files Browse the repository at this point in the history
  • Loading branch information
Ghost-chu committed Jan 13, 2025
1 parent 66d057a commit 6de2cac
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.ghostchu.peerbanhelper.database.table;

import com.ghostchu.peerbanhelper.alert.AlertLevel;
import com.ghostchu.peerbanhelper.database.TranslationComponentPersistener;
import com.ghostchu.peerbanhelper.text.TranslationComponent;
import com.j256.ormlite.field.DataType;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
import lombok.AllArgsConstructor;
Expand All @@ -26,8 +26,8 @@ public final class AlertEntity {
private AlertLevel level;
@DatabaseField(canBeNull = false, index = true)
private String identifier;
@DatabaseField(canBeNull = false, dataType = DataType.SERIALIZABLE)
@DatabaseField(canBeNull = false, persisterClass = TranslationComponentPersistener.class)
private TranslationComponent title;
@DatabaseField(canBeNull = false, dataType = DataType.SERIALIZABLE)
@DatabaseField(canBeNull = false, persisterClass = TranslationComponentPersistener.class)
private TranslationComponent content;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ghostchu.peerbanhelper.util.json;

import com.ghostchu.peerbanhelper.text.TranslationComponent;
import com.google.gson.*;
import org.jetbrains.annotations.NotNull;

Expand All @@ -13,6 +14,7 @@ public class JsonUtil {
.setExclusionStrategies(new HiddenAnnotationExclusionStrategy())
.serializeNulls()
.registerTypeAdapter(Timestamp.class, TimestampTypeAdapter.INSTANCE)
.registerTypeAdapter(TranslationComponent.class, TranslationComponentTypeAdapter.INSTANCE)
.disableHtmlEscaping()
.create();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,72 @@
package com.ghostchu.peerbanhelper.util.json;

import com.ghostchu.peerbanhelper.text.TranslationComponent;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import java.lang.reflect.Type;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static com.ghostchu.peerbanhelper.text.TextManager.tlUI;

public class TranslationComponentTypeAdapter implements JsonSerializer<TranslationComponent> {
public class TranslationComponentTypeAdapter extends TypeAdapter<TranslationComponent> {
public static final TranslationComponentTypeAdapter INSTANCE = new TranslationComponentTypeAdapter();

@Override
public JsonElement serialize(TranslationComponent ts, Type t, JsonSerializationContext jsc) {
return new JsonPrimitive(tlUI(ts));
public void write(JsonWriter out, TranslationComponent value) throws IOException {
out.beginObject();
out.name("key").value(value.getKey());
out.name("params");
out.beginArray(); // 开始 JSON 数组
// 遍历 params 数组并写入元素
for (Object param : value.getParams()) {
if (param instanceof String) {
out.value((String) param); // 如果是 String,直接写入
} else if (param instanceof TranslationComponent) {
// 如果是 TranslationComponent,递归调用 write 方法
TranslationComponentTypeAdapter.INSTANCE.write(out, (TranslationComponent) param);
} else {
out.nullValue(); // 如果是其他类型,写入 null(可以根据需求调整)
}
}
out.endArray(); // 结束 JSON 数组
out.endObject(); // 结束 JSON 对象
}

@Override
public TranslationComponent read(JsonReader in) throws IOException {
String key = null;
List<Object> params = new ArrayList<>();

in.beginObject(); // 开始读取 JSON 对象

while (in.hasNext()) { // 循环读取每个字段
String name = in.nextName();
if ("key".equals(name)) {
key = in.nextString(); // 读取 key 字段
} else if ("params".equals(name)) {
in.beginArray(); // 开始读取 JSON 数组
while (in.hasNext()) {
// 判断当前元素是字符串还是 TranslationComponent
if (in.peek() == JsonToken.STRING) {
params.add(in.nextString()); // 如果是字符串,直接添加到 params 列表
} else if (in.peek() == JsonToken.BEGIN_OBJECT) {
// 如果是对象,则递归读取 TranslationComponent
params.add(TranslationComponentTypeAdapter.INSTANCE.read(in));
} else {
in.skipValue(); // 跳过不需要的值
}
}
in.endArray(); // 结束数组读取
} else {
in.skipValue(); // 跳过不需要的字段
}
}

in.endObject(); // 结束 JSON 对象的读取

// 构造并返回 TranslationComponent 对象
return new TranslationComponent(key, params.toArray(new Object[0]));
}
}

0 comments on commit 6de2cac

Please sign in to comment.