【发布时间】:2021-04-05 21:18:05
【问题描述】:
我试图使用 GSON 序列化/反序列化 JSON。有问题的有效载荷是ApiGatewayAuthorizerContext。在里面,有一个HashMap<String, String>。但是在做from/to json的时候,字段命名策略并没有应用到Keys上。
@JsonIgnoreProperties(ignoreUnknown = true)
public class ApiGatewayAuthorizerContext {
//-------------------------------------------------------------
// Variables - Private
//-------------------------------------------------------------
private Map<String, String> contextProperties = new HashMap<>();
private String principalId;
private CognitoAuthorizerClaims claims;
}
AwsProxyRequest 类中的MultiValuedTreeMap<String, String> 也一样,这是一个MultivaluedMap<Key, Value>。
我的字段命名策略很简单,将-替换为_,例如下面的payload对于我使用的很多下游组件都不是有效的JSON,想把所有的'-'替换成'_' .
"MultiValueHeaders": {
"Accept": [
"application/json, text/plain, */*"
],
"Authorization": [
"Bearer ey...b9w"
],
"Content-Type": [
"application/json;charset=utf-8"
],
"Host": [
"aws-us-east-1-dev-dws-api.xxxxxxxx.com"
],
"User-Agent": [
"axios/0.20.0"
],
"X-Amzn-Trace-Id": [
"Root=1-xxxxxxxx-xxxxxxxxxxxxxxxx"
],
"X-Forwarded-For": [
"127.0.232.171"
],
"X-Forwarded-Port": [
"443"
],
"X-Forwarded-Proto": [
"https"
]
},
有什么想法吗?
编辑:添加字段命名策略。
public class ApiEventNamingStrategy implements FieldNamingStrategy {
/**
* Translates the field name into its {@link FieldNamingPolicy.UPPER_CAMEL_CASE} representation.
*
* @param field the field object that we are translating
* @return the translated field name.
*/
public String translateName(Field field) {
String fieldName = FieldNamingPolicy.UPPER_CAMEL_CASE.translateName(field);
if (fieldName.contains("-")) {
fieldName = fieldName.replace('-', '_');
}
return fieldName;
}
}
用于setFieldNamingStrategy如下图,
private static Gson gson =
(new GsonBuilder()).setFieldNamingStrategy(new ApiEventNamingStrategy()).create();
结果是,除了Map 中的成员变量之外的所有成员变量都被检查并重命名。似乎setFieldNamingStrategy 不会在Map 内部查看并重命名Keys。
现在我正在查看使用registerTypeAdapterFactory 注册TypeAdapter。似乎@linfaxin 在这里gson-wont-properly-serialise-a-class-that-extends-hashmap 的答案会来救援!但问题是,在哪里/如何和/或在RetainFieldMapFactory 类中引入字段命名策略的正确位置,因为我看到了很多破解它的途径。
欢迎提出任何想法!
顺便说一句,这些值由AWS APIGateway 和一个自定义授权 lambda 填充。我认为我无法改变APIGateway 的行为。
【问题讨论】:
-
请添加问题中缺少的关于字段命名转换的部分。到目前为止,您尝试了什么。
-
另外,您如何期望
Map<String, String> contextProperties被填满?你在做一些用元素填充地图的事情吗? -
正确,
contextProperties由自定义授权 lambda 填充。可以修改contextProperties,但MultiValueHeaders中的X-Amzn-Trace-Id、X-Forwarded-For等仍然过不去! -
您对字段命名策略的假设是错误的,因为它旨在翻译 类字段 名称(请参阅接口方法声明),而不是任意对象(提示:内部映射类型适配器工厂根本没有任何名称翻译功能)。此外,扩展哈希映射的链接问题是无关紧要的:它解决了 OP 试图将扩展类属性与 Gson 默认知道的映射接口合并的问题。最后,Gson 不知道非标准的
MultiValuedTreeMap,因此您必须实现自定义类型适配器。
标签: java json amazon-web-services hashmap gson