Реквестеры должны интерпретировать метаданные. Составные метаданные позволяют независимо форматировать значения метаданных (например, для маршрутизации, в целях безопасности, трассировки), каждое из которых имеет свой собственный MIME-тип. Приложениям необходим способ конфигурирования MIME-типов метаданных для обеспечения поддержки, а также способ получения доступа к извлеченным значениям.

MetadataExtractor – это контракт для получения сериализованных метаданных и возврата декодированных пар "имя-значение", к которым затем можно будет обращаться как к заголовкам по имени, например, через аннотацию @Header в аннотированных методах обработчика.

DefaultMetadataExtractor может быть передан экземплярам Decoder для декодирования метаданных. "Из коробки" он имеет встроенную поддержку "message/x.rsocket.routing.v0", который декодируется в String и сохраняется с ключом "route". Для любого другого MIME-типа необходимо указать Decoder и зарегистрировать MIME-тип следующим образом:

Java
DefaultMetadataExtractor extractor = new DefaultMetadataExtractor(metadataDecoders);
extractor.metadataToExtract(fooMimeType, Foo.class, "foo");
Kotlin
import org.springframework.messaging.rsocket.metadataToExtract
val extractor = DefaultMetadataExtractor(metadataDecoders)
extractor.metadataToExtract<Foo>(fooMimeType, "foo")

Составные метаданные хорошо подходят для объединения независимых значений метаданных. Однако реквестер может не поддерживать составные метаданные или не использовать их. В этом случае DefaultMetadataExtractor может потребоваться кастомная логика для отображения декодированного значения на Map вывода. Вот пример, в котором для метаданных используется формат JSON:

Java
DefaultMetadataExtractor extractor = new DefaultMetadataExtractor(metadataDecoders);
extractor.metadataToExtract(
MimeType.valueOf("application/vnd.myapp.metadata+json"),
new ParameterizedTypeReference<Map<String,String>>() {},
(jsonMap, outputMap) -> {
outputMap.putAll(jsonMap);
});
Kotlin
import org.springframework.messaging.rsocket.metadataToExtract
val extractor = DefaultMetadataExtractor(metadataDecoders)
extractor.metadataToExtract<Map<String, String>>(MimeType.valueOf("application/vnd.myapp.metadata+json")) { jsonMap, outputMap ->
outputMap.putAll(jsonMap)
}

При конфигурировании MetadataExtractor через RSocketStrategies можно позволить RSocketStrategies.Builder создать экстрактор с настроенными декодерами и просто использовать обратный вызов для настройки процедур регистрации следующим образом:

Java
RSocketStrategies strategies = RSocketStrategies.builder()
.metadataExtractorRegistry(registry -> {
registry.metadataToExtract(fooMimeType, Foo.class, "foo");
// ...
})
.build();
Kotlin
import org.springframework.messaging.rsocket.metadataToExtract
val strategies = RSocketStrategies.builder()
.metadataExtractorRegistry { registry: MetadataExtractorRegistry ->
    registry.metadataToExtract<Foo>(fooMimeType, "foo")
    // ...
}
.build()