Java GSON不会重命名HashMap中的字段
我试图使用GSON序列化/反序列化JSON。所涉及的有效负载是Java GSON不会重命名HashMap中的字段,java,json,amazon-web-services,hashmap,gson,Java,Json,Amazon Web Services,Hashmap,Gson,我试图使用GSON序列化/反序列化JSON。所涉及的有效负载是ApiGatewayAuthorizerContext。在它里面,有一个HashMap。但是,在执行从/到json的操作时,字段命名策略不会应用于键 @JsonIgnoreProperties(ignoreUnknown = true) public class ApiGatewayAuthorizerContext { //--------------------------------------------------
ApiGatewayAuthorizerContext
。在它里面,有一个HashMap
。但是,在执行从/到json的操作时,字段命名策略不会应用于键
@JsonIgnoreProperties(ignoreUnknown = true)
public class ApiGatewayAuthorizerContext {
//-------------------------------------------------------------
// Variables - Private
//-------------------------------------------------------------
private Map<String, String> contextProperties = new HashMap<>();
private String principalId;
private CognitoAuthorizerClaims claims;
}
有什么想法吗
编辑:添加字段命名策略
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;
}
}
用于设置字段命名策略,如下所示
private static Gson gson =
(new GsonBuilder()).setFieldNamingStrategy(new ApiEventNamingStrategy()).create();
结果是,除了映射
中的成员变量之外的所有成员变量都将被检查并重命名。似乎setFieldNamingStrategy
不会查看地图的内部
并重命名键
现在,我正在研究如何利用registerTypeAdapterFactory
注册TypeAdapter
。看来@linfaxin的答案会来拯救我们!但问题是,在RetainieldMapFactory
类中,在哪里/如何和/或在正确的位置引入字段命名策略,因为我看到了很多破解方法
欢迎任何意见
顺便说一句,这些值由AWS APIGateway
和自定义授权lambda填充。我想我不能改变<代码> AgigaTead 的行为。 < P> GSON将不会进入内部地图并考虑你想做什么。杰克逊也是
考虑到您的内容已经存在于地图中,我认为只使用3行代码转换地图要容易得多,而不是试图破解库如何序列化和反序列化对象
Map<String, String> contextPropertiesNormalized= contextProperties.keySet()
.stream()
.collect(Collectors.toMap(k-> k.contains("-") ? k.replace("-","_"): k, v -> contextProperties::get));
Map contextProperties normalized=contextProperties.keySet()
.stream()
.collect(Collectors.toMap(k->k.contains(“-”)?k.replace(“-”,“”):k,v->contextProperties::get));
请添加问题中缺少的关于字段命名转换的部分。到目前为止,您尝试了什么。您又如何期望Map contextProperties
得到填充?您正在使用元素填充该映射吗?正确,contextProperties
由自定义授权lambda填充。可以修改contextProperties
,但是X-Amzn-Trace-Id
,X-Forwarded-For
等MultiValueHeaders
中的!关于字段命名策略的假设是错误的,因为它被设计为转换类字段名称(请参见接口方法声明),而不是任意对象(提示:内部映射类型适配器工厂根本没有任何名称转换功能)。此外,扩展哈希映射的链接问题是不相关的:它解决了OP试图将扩展类属性与Gson默认知道的映射接口合并的问题。最后,Gson不知道非标准的多值treemap
,因此您必须实现自定义类型适配器。是的,这是最简单的方法,但是有时中间映射是不需要的,因此创建反序列化程序是有意义的。此外,此类场景中的映射通常应从条目()
中收集,而不是密钥集()
:它可以保证正确收集条目,即使是不引用源映射的并行流,也不一定是线程安全的(通常,流函数应该没有副作用,并且不绑定到“外部世界”)当前词汇范围的上下文)。另外,我相信您还指的是String.replaceAll()
(然后是Pattern.compile()
,以便使用匹配器加快速度)。
Map<String, String> contextPropertiesNormalized= contextProperties.keySet()
.stream()
.collect(Collectors.toMap(k-> k.contains("-") ? k.replace("-","_"): k, v -> contextProperties::get));