4.8. Transcoders 和 Data Conversion
Data Grid 使用 org.infinispan.commons.dataconversion.Transcoder
在 MediaType 格式之间转换数据。
public interface Transcoder { /** * Transcodes content between two different {@link MediaType}. * * @param content Content to transcode. * @param contentType The {@link MediaType} of the content. * @param destinationType The target {@link MediaType} to convert. * @return the transcoded content. */ Object transcode(Object content, MediaType contentType, MediaType destinationType); /** * @return all the {@link MediaType} handled by this Transcoder. */ Set<MediaType> getSupportedMediaTypes(); }
4.8.1. 根据需要转换数据
您可以在 Data Grid 上部署并运行自定义代码,如任务、监听器和合并策略。Data Grid 上的自定义代码可以直接访问数据,但还必须与通过不同端点访问相同数据的客户端进行互操作。例如,您可以创建处理自定义对象的任务,而 Hot Rod 客户端以二进制格式读取和写入数据。
在这种情况下,您可以将 application/x-protostream
配置为缓存编码以二进制格式存储数据,然后将自定义代码配置为使用不同的 MediaType 执行缓存操作。
例如:
DefaultCacheManager cacheManager = new DefaultCacheManager(); // The cache will store POJO for keys and values ConfigurationBuilder cfg = new ConfigurationBuilder(); cfg.encoding().key().mediaType("application/x-java-object"); cfg.encoding().value().mediaType("application/x-java-object"); cacheManager.defineConfiguration("mycache", cfg.build()); Cache<Integer, Person> cache = cacheManager.getCache("mycache"); cache.put(1, new Person("John","Doe")); // Wraps cache using 'application/x-java-object' for keys but JSON for values Cache<Integer, byte[]> jsonValuesCache = (Cache<Integer, byte[]>) cache.getAdvancedCache().withMediaType("application/x-java-object", "application/json"); byte[] json = jsonValuesCache.get(1);
将以 JSON 格式返回值:
{ "_type":"org.infinispan.sample.Person", "name":"John", "surname":"Doe" }
4.8.2. 以嵌入式 Deloyments 安装 Transcoders
默认情况下,Data Grid Server 包括 transcoders。但是,当以库的形式运行 Data Grid 时,您必须将以下内容添加到项目中:
org.infinispan:infinispan-server-core
4.8.3. Transcoders 和 Encoders
通常,缓存操作中没有或只有一个数据转换:
- 在嵌入式或服务器模式中使用 的缓存上,默认没有转换;
- 对没有配置 MediaType 的嵌入式缓存进行基于编码的转换,但使用 OFF_HEAP 或 BINARY;
- 对于在多个 REST 和 Hot Rod 客户端以不同格式发送和接收数据的服务器模式中使用的基于 Transcoder 的转换。这些缓存将配置 MediaType 描述存储。
但是,可以在高级用例中同时使用 encoders 和 transcoders。
例如,一个存储 marshalled 对象(带有 jboss marshaller)内容的缓存,但出于安全原因应该添加透明加密层以避免将"plain"数据存储在外部存储中。客户端应该能以多种格式读取和写入数据。
这可以通过使用描述存储的 MediaType 配置缓存来实现,而不考虑编码层:
ConfigurationBuilder cfg = new ConfigurationBuilder(); cfg.encoding().key().mediaType("application/x-jboss-marshalling"); cfg.encoding().key().mediaType("application/x-jboss-marshalling");
可以通过使用特殊 Encoder 对缓存进行加密/解密并存储/检索来添加透明加密,例如:
class Scrambler implements Encoder { public Object toStorage(Object content) { // Encrypt data } public Object fromStorage(Object content) { // Decrypt data } @Override public boolean isStorageFormatFilterable() { } public MediaType getStorageFormat() { return new MediaType("application", "scrambled"); } @Override public short id() { //return id } }
为确保写入缓存的所有数据都会加密,需要使用上面的 Encoder 分离缓存并执行此解码缓存中的所有缓存操作:
Cache<?,?> secureStorageCache = cache.getAdvancedCache().withEncoding(Scrambler.class).put(k,v);
通过减少使用所需 MediaType 的缓存,可以添加以多种格式读取数据的功能:
// Obtain a stream of values in XML format from the secure cache secureStorageCache.getAdvancedCache().withMediaType("application/xml","application/xml").values().stream();
在内部,数据网格首先应用 存储操作中的 encoder 获取 条目,该条目将采用 "application/x-jboss-marshalling" 格式,然后使用适当的 Transcoder 将连续转换应用到"application/xml"。