使用 Gson 序列化时如何在 Firebase Admin SDK 中应用消息 class 的@Key
How to apply the @Key of the Message class in the Firebase Admin SDK when serializing using Gson
在用Gson序列化messageclass的builder创建的对象时,想获取键名android.
我认为 @Key 应该得到 android,而不是 androidConfig,作为序列化的结果,但事实并非如此。
Objectmapper 和 Gson 也是如此。
我的开发环境是Spring Boot 2.3.12.RELEASE, Firebase ADMIN SDK 8.0.1., Gson 2.8.8
[source]
message = Message.builder()
.setNotification(Notification.builder()
.setTitle(pushMessageDto.getTitle())
.setBody(pushMessageDto.getBody())
.setImage(pushMessageDto.getImage())
.build())
.setAndroidConfig(AndroidConfig.builder()
.setTtl(3600 * 1000)
.setNotification(AndroidNotification.builder()
.setIcon(ar.getIcon())
.setColor(ar.getColor())
.setClickAction(ar.getClickAction())
.build())
.build())
.setTopic(pushMessageDto.getTopic())
.build();
Gson gson = new Gson();
String m = gson.toJson(message);
[serializing results]
{
"validate_only":false,
"message":{
"notification":{
"title":"a",
"body":"b",
"image":"c"
},
"androidConfig":{
"ttl":"3",
"notification":{
"icon":"",
"color":"#32a852",
"clickAction":"MainActivity",
}
},
"topic":"weather"
}
}
[Message class of Firebase Admin SDK]
public class Message {
@Key("data")
private final Map<String, String> data;
@Key("notification")
private final Notification notification;
@Key("android")
private final AndroidConfig androidConfig;
@Key("webpush")
private final WebpushConfig webpushConfig;
@Key("apns")
private final ApnsConfig apnsConfig;
@Key("token")
private final String token;
@Key("topic")
private final String topic;
@Key("condition")
private final String condition;
@Key("fcm_options")
private final FcmOptions fcmOptions;
Gson 默认只支持它的 @SerializedName
注释来指定自定义 JSON 成员名称。
假设您正在使用的 @Key
注释在运行时可用 (@Retention(RUNTIME)
),您可以编写自定义 FieldNamingStrategy
:
public class KeyFieldNamingStrategy implements FieldNamingStrategy {
private final FieldNamingStrategy delegate;
public KeyFieldNamingStrategy(FieldNamingStrategy delegate) {
this.delegate = delegate;
}
@Override
public String translateName(Field f) {
Key key = f.getAnnotation(Key.class);
if (key == null) {
// No annotation, use delegate
return delegate.translateName(f);
} else {
return key.value();
}
}
}
然后用GsonBuilder
注册:
Gson gson = new GsonBuilder()
// Uses IDENTITY as delegate, which uses field names as is
.setFieldNamingStrategy(new KeyFieldNamingStrategy(FieldNamingPolicy.IDENTITY))
.create();
在用Gson序列化messageclass的builder创建的对象时,想获取键名android.
我认为 @Key 应该得到 android,而不是 androidConfig,作为序列化的结果,但事实并非如此。 Objectmapper 和 Gson 也是如此。
我的开发环境是Spring Boot 2.3.12.RELEASE, Firebase ADMIN SDK 8.0.1., Gson 2.8.8
[source]
message = Message.builder()
.setNotification(Notification.builder()
.setTitle(pushMessageDto.getTitle())
.setBody(pushMessageDto.getBody())
.setImage(pushMessageDto.getImage())
.build())
.setAndroidConfig(AndroidConfig.builder()
.setTtl(3600 * 1000)
.setNotification(AndroidNotification.builder()
.setIcon(ar.getIcon())
.setColor(ar.getColor())
.setClickAction(ar.getClickAction())
.build())
.build())
.setTopic(pushMessageDto.getTopic())
.build();
Gson gson = new Gson();
String m = gson.toJson(message);
[serializing results]
{
"validate_only":false,
"message":{
"notification":{
"title":"a",
"body":"b",
"image":"c"
},
"androidConfig":{
"ttl":"3",
"notification":{
"icon":"",
"color":"#32a852",
"clickAction":"MainActivity",
}
},
"topic":"weather"
}
}
[Message class of Firebase Admin SDK]
public class Message {
@Key("data")
private final Map<String, String> data;
@Key("notification")
private final Notification notification;
@Key("android")
private final AndroidConfig androidConfig;
@Key("webpush")
private final WebpushConfig webpushConfig;
@Key("apns")
private final ApnsConfig apnsConfig;
@Key("token")
private final String token;
@Key("topic")
private final String topic;
@Key("condition")
private final String condition;
@Key("fcm_options")
private final FcmOptions fcmOptions;
Gson 默认只支持它的 @SerializedName
注释来指定自定义 JSON 成员名称。
假设您正在使用的 @Key
注释在运行时可用 (@Retention(RUNTIME)
),您可以编写自定义 FieldNamingStrategy
:
public class KeyFieldNamingStrategy implements FieldNamingStrategy {
private final FieldNamingStrategy delegate;
public KeyFieldNamingStrategy(FieldNamingStrategy delegate) {
this.delegate = delegate;
}
@Override
public String translateName(Field f) {
Key key = f.getAnnotation(Key.class);
if (key == null) {
// No annotation, use delegate
return delegate.translateName(f);
} else {
return key.value();
}
}
}
然后用GsonBuilder
注册:
Gson gson = new GsonBuilder()
// Uses IDENTITY as delegate, which uses field names as is
.setFieldNamingStrategy(new KeyFieldNamingStrategy(FieldNamingPolicy.IDENTITY))
.create();