Gson中可配置的@SerializedName

时间:2017-04-20 10:43:56

标签: java gson

我可以从配置文件中获取@SerializedName值吗?

我的意思是:

@SerializedName(value = configProfider.getJsonFieldName())
private String myField

感谢。

1 个答案:

答案 0 :(得分:1)

我在评论中特别错误:这在Gson中是可能的,但不是@SerializedName(由于Gson如何在内部工作)和非编译时表达式(由于Java限制)。对困惑感到抱歉。 Gson支持在配置Gson实例时可以提供的自定义字段命名策略。

考虑以下自定义注释:

@Retention(RUNTIME)
@Target(FIELD)
@interface DynamicSerializedName {

    String value();

}

现在只需实施您的策略:

final class DynamicSerializedNameStrategy
        implements FieldNamingStrategy {

    private final Function<? super String, String> translator;

    private DynamicSerializedNameStrategy(final Function<? super String, String> translator) {
        this.translator = translator;
    }

    static FieldNamingStrategy getDynamicSerializedNameStrategy(final Function<? super String, String> translator) {
        return new DynamicSerializedNameStrategy(translator);
    }

    @Override
    public String translateName(final Field field) {
        final DynamicSerializedName annotation = field.getAnnotation(DynamicSerializedName.class);
        if ( annotation == null ) {
            // Taking the default naming strategy
            // @SerializedName takes higher priority in ReflectiveTypeAdapterFactory.Adapter anyway
            return FieldNamingPolicy.IDENTITY.translateName(field);
        }
        final String key = annotation.value();
        final String resolvedName = translator.apply(key);
        if ( resolvedName == null ) {
            throw new IllegalArgumentException("Cannot resolve name by " + key + " for " + field);
        }
        return resolvedName;
    }

}

创建注释:

final class Model {

    @DynamicSerializedName("gson.model.field")
    final String field = null;

}

如何使用它(基于系统属性的示例):

private static final Gson gson = new GsonBuilder()
        .setFieldNamingStrategy(getDynamicSerializedNameStrategy(System::getProperty))
        .create();

public static void main(final String... args)
        throws IOException {
    try ( final Reader reader = getPackageResourceReader(Q43517297.class, "arbitrary.json") ) {
        final Model model = gson.fromJson(reader, Model.class);
        System.out.println(model.field);
    }
}

除非您这样做,否则此示例将失败:

  • 以编程方式定义gson.model.field系统属性,如System.setProperty("gson.model.field", "dynamic");;
  • 或在启动JVM时使用-D参数定义系统属性:-Dgson.model.field=dynamic

考虑以下JSON(上面引用为arbitrary.json):

{
    "static": "BY-STATIC-NAME",
    "dynamic": "BY-DYNAMIC-NAME"
}

设置@DynamicSerializedName注释并正确配置相应的属性后,输出将为:

  

BY-DYNAMIC-NAME

从DTO字段中删除@DynamicSerializedName注释,或使用@SerializedName注释该字段(从Gson 2.8.0开始具有更高的优先级),输出将为:

  

BY-STATIC-NAME