Gson:指定类或字段的命名策略

js4nwp54  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(181)

不幸的是,我解析的JSON数据中同时存在不同的命名策略。

{
  "camelCaseData" : {
    "someField" : 1
  },
  "snake_case_data" : {
    "some_field" : 2
  }
}

有没有可能为整个snakeCaseData指定命名策略?或者另一种解决方案可以帮助避免通过@SerializedName手动注解每个字段?
类似于以下内容

class Data {
  CamelCaseData camelCaseData;

  @GsonNamingPolicy(com.google.gson.FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES )
  SnakeCaseData snakeCaseData;
}
daupos2t

daupos2t1#

我不知道你到底要问什么,但我想这可能会对你有所帮助。基本上,这需要你注解任何只包含snake大小写字段的类,以及任何包含camel大小写字段的类中的snake大小写字段。
首先,我们按照您的建议定义一个注解:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface GsonNamingPolicy {
    FieldNamingPolicy value();
}

然后,我们将按照上面所描述的那样对类进行注解:

public static class CamelCaseData {
    int someField;
}

@GsonNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
public static class SnakeCaseData {
    int someField;
}

public static class Data {
    CamelCaseData camelCaseData;

    @GsonNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
    SnakeCaseData snakeCaseData;
}

最后,我们定义了一个定制的FieldNamingStrategy,它检查字段和它的声明类是否有新的注解,如果有注解,就使用注解中定义的策略,否则就使用默认策略。

public static class AnnotationFieldNamingStrategy implements FieldNamingStrategy {
    public String translateName(Field field) {
        Class<?> declaringClass = field.getDeclaringClass();

        GsonNamingPolicy fieldNamingPolicy = field.getAnnotation(GsonNamingPolicy.class);
        GsonNamingPolicy classNamingPolicy = declaringClass.getAnnotation(GsonNamingPolicy.class);

        FieldNamingPolicy policy = FieldNamingPolicy.IDENTITY;

        if (fieldNamingPolicy != null) {
            policy = fieldNamingPolicy.value();
        } else if (classNamingPolicy != null) {
            policy = classNamingPolicy.value();
        }

        return policy.translateName(field);
    }
}

然后,您可以在配置Gson时使用此策略:

Gson gson = new GsonBuilder()
            .setFieldNamingStrategy(new AnnotationFieldNamingStrategy())
            .create();

    Data data = gson.fromJson(json, Data.class);

    System.out.println(data.camelCaseData.someField);
    System.out.println(data.snakeCaseData.someField);

这并不是你所要求的,但希望它能帮助你。我不相信有一种方法可以检查一个字段是否在声明它的类之外的级别上被注解。有一种方法可以达到你所要求的,但它可能需要使用自定义的TypeAdapterTypeAdapterFactory

相关问题