有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Gson中的java可配置@SerializedName

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

我的意思是:

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

谢谢


共 (1) 个答案

  1. # 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);
        }
    }
    

    此示例将失败,除非您执行以下操作:

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

    考虑下面的JSON(上面引用为^ {CD7>}):

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

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

    BY-DYNAMIC-NAME

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

    BY-STATIC-NAME