使用JacksonYAMLMapper进行反序列化和反序列化时,YAML(YAML标记)中的感叹号导致异常行为

jpfvwuh4  于 2022-11-08  发布在  其他
关注(0)|答案(1)|浏览(151)

我尝试使用JacksonYAMLMapper反序列化和重新序列化以下YAML内容。但是,缺少标记!ImportValue。请告诉我如何保留YAML标记!ImportValue

原始内容:

AWSTemplateFormatVersion: 2010-09-09
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketEncryption:
        ServerSideEncryptionConfiguration:
        - ServerSideEncryptionByDefault:
            KMSMasterKeyID: !ImportValue DefaultCustomerMasterKeyForThisRegionArn
            SSEAlgorithm: aws:kms
      BucketName: blahblah.com

在反序列化与重新序列化之后:

AWSTemplateFormatVersion: 2010-09-09
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketEncryption:
        ServerSideEncryptionConfiguration:
        - ServerSideEncryptionByDefault:
            KMSMasterKeyID: DefaultCustomerMasterKeyForThisRegionArn
            SSEAlgorithm: aws:kms
      BucketName: blahblah.com
evrscar2

evrscar21#

通常,在YAML加载过程中,一旦将数据加载到本机类型中,标记就会被删除。

(来源:yaml.org
这意味着如果你想保留一个标签,你应该在Map到原生数据类型之前停止加载。大多数YAML实现都提供了一个API。Jackson使用了SnakeYAML,它确实提供了这个API,但是Jackson没有公开它。这意味着你需要直接使用SnakeYAML来完成这个任务。
你这样做:

StreamReader sr = /* whatever you want to load */;
Resolver resolver = new Resolver();
Composer composer = new Composer(new ParserImpl(sr), resolver);
Node root = composer.getSingleNode();

当你想再次写出YAML时,你需要:

DumperOptions do = new DumperOptions();
Serializer serializer = new Serializer(new Emitter(output, do), resolver, do, null);
Writer w = /* whereever you want to write */;
serializer.serialize(root);

请注意,如果要更改任何内容,现在需要使用Node子类来遍历数据。

相关问题