Reputation: 306
Could I get @SerializedName
value from config file etc.?
I mean like:
@SerializedName(value = configProfider.getJsonFieldName())
private String myField
Thanks.
Upvotes: 2
Views: 1319
Reputation: 21115
I was particularly wrong in my comment: this is possible in Gson, but not with @SerializedName
(due to how Gson works internally) and non-compile time expressions (due to Java restrictions). Sorry for the confusion. Gson supports a custom field naming strategy that you can supply while configuring your Gson
instance.
Consider the following custom annotation:
@Retention(RUNTIME)
@Target(FIELD)
@interface DynamicSerializedName {
String value();
}
Now just implement your strategy:
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;
}
}
Create an annotation:
final class Model {
@DynamicSerializedName("gson.model.field")
final String field = null;
}
How it can be used (system properties-based example):
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);
}
}
This example will fail unless you do:
gson.model.field
system property programmatically like System.setProperty("gson.model.field", "dynamic");
;-D
parameter while starting the JVM: -Dgson.model.field=dynamic
.Consider the following JSON (referenced as arbitrary.json
above):
{
"static": "BY-STATIC-NAME",
"dynamic": "BY-DYNAMIC-NAME"
}
Once the @DynamicSerializedName
annotation is set and the corresponding property is properly configured the output will be:
BY-DYNAMIC-NAME
Once you remove the @DynamicSerializedName
annotation from the DTO field, or annotate the field with @SerializedName
(it has higher priority as of Gson 2.8.0), the output will be:
BY-STATIC-NAME
Upvotes: 1