GSON不会重命名HashMap中的字段

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

我尝试使用GSON序列化/反序列化JSON。有问题的有效负载是ApiGatewayAuthorizerContext。在它里面,有一个HashMap<String, String>。但是当执行from/to json时,字段命名策略不应用于键。

@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>
我的字段命名策略很简单,将-替换为_,例如,下面的有效负载对于我使用的许多下游组件来说不是有效的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的行为。

lb3vh1jj

lb3vh1jj1#

GSON不会进入Map内部并考虑你想做什么。Jackson也不会。
考虑到您已经在Map中有了内容,我认为用3行代码转换Map要容易得多,而不是试图破解库如何序列化和反序列化对象。

Map<String, String> contextPropertiesNormalized= contextProperties.keySet()
                       .stream()
                       .collect(Collectors.toMap(k-> k.contains("-") ? k.replace("-","_"): k, v -> contextProperties::get));

相关问题