Gson的开发人员表示,他们从未对添加此功能的请求感到不满,他们担心会滥用api来增加对此功能的支持.
添加此功能的一种方法是使用TypeAdapter(我为粗糙的代码道歉,但这证明了原理):
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.google.common.base.CaseFormat;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
public class AccessorBasedTypeAdaptor<T> extends TypeAdapter<T> {
private Gson gson;
public AccessorBasedTypeAdaptor(Gson gson) {
this.gson = gson;
}
@SuppressWarnings("unchecked")
@Override
public void write(JsonWriter out, T value) throws IOException {
out.beginObject();
for (Method method : value.getClass().getMethods()) {
boolean nonBooleanAccessor = method.getName().startsWith("get");
boolean booleanAccessor = method.getName().startsWith("is");
if ((nonBooleanAccessor || booleanAccessor) && !method.getName().equals("getClass") && method.getParameterTypes().length == 0) {
try {
String name = method.getName().substring(nonBooleanAccessor ? 3 : 2);
name = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, name);
Object returnValue = method.invoke(value);
if(returnValue != null) {
TypeToken<?> token = TypeToken.get(returnValue.getClass());
TypeAdapter adapter = gson.getAdapter(token);
out.name(name);
adapter.write(out, returnValue);
}
} catch (Exception e) {
throw new ConfigurationException("problem writing json: ", e);
}
}
}
out.endObject();
}
@Override
public T read(JsonReader in) throws IOException {
throw new UnsupportedOperationException("Only supports writes.");
}
}
Run Code Online (Sandbox Code Playgroud)
您可以将此注册为给定类型的普通类型适配器或通过TypeAdapterfactory注册 - 可能检查是否存在运行时注释:
public class TypeFactory implements TypeAdapterFactory {
@SuppressWarnings("unchecked")
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
Class<? super T> t = type.getRawType();
if(t.isAnnotationPresent(UseAccessor.class)) {
return (TypeAdapter<T>) new AccessorBasedTypeAdaptor(gson);
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
创建gson实例时,可以将其指定为正常:
new GsonBuilder().registerTypeAdapterFactory(new TypeFactory()).create();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3303 次 |
| 最近记录: |