【问题标题】:How to serialize a java.util.regex.Pattern using protobuf?如何使用 protobuf 序列化 java.util.regex.Pattern?
【发布时间】:2019-02-12 12:23:55
【问题描述】:

我有一个对象,我想使用协议缓冲区序列化并存储在 redis 中。该对象包含一个java.util.regex.Pattern,该对象在实例化时被编译。

public class SerializableEntity {
    private Pattern pattern;
    private List<String> options;
}

此模式用于验证对某个 api 的输入。由于每次编译模式都是expensive,所以我在实例化期间编译一次模式,然后在每次调用 api 时重用相同的模式实例。如何在以下架构中序列化此 compile Pattern 字段,以便在反序列化对象时无需再次编译模式即可使用它?

 message SerializableEntityProto {
     repeated string option = 1;
     // compiled pattern
 }

谢谢。

【问题讨论】:

  • 存储pattern.pattern()? (和pattern.flags(),如果您可以使用非默认标志编译它)。
  • @AndyTurner 所以每次我从redis检索它时都必须编译它?
  • 您可能需要对模式进行一些延迟初始化。首次访问时仅从 redis 读取一次,编译模式字符串并使用编译后的模式。检查lazy initialization on demand holder idom
  • @dpr 每次调用 api 时我都会从 redis 读取它,我需要执行一些正则表达式操作。无法将其存储在本地。
  • 其实Pattern实现了Serializable,也就是说你可以依赖Java的(反)序列化。见stackoverflow.com/questions/2836646/…也许将其转换为base64并将字符串存储在redis中。但我不明白你为什么要为此使用 protobufs。

标签: java serialization protocol-buffers protobuf-java


【解决方案1】:

java.util.regex.Pattern 本身没有实现编码和解码 proto 函数。但是,您可以很容易地自己实现(正如 Andy Turner 建议的那样)。像这样的:

原型

syntax = "proto2";

package termin4t0r;
option java_package = "com.example.termin4t0r";

// Proto for java.util.regex.Pattern
message RegexPatternProto {
  // See Pattern.pattern()
  optional string pattern = 1;
  // See Pattern.flags()
  optional int64 flags = 2;
}

Java 编码和解码函数

class RegexpPatternProtos {
  public static RegexPatternProto encode(java.util.regex.Pattern pattern) {
    return RegexPatternProto.newBuilder()
        .setPattern(pattern.pattern())
        .setFlags(pattern.flags())
        .build();
  }

  public static java.util.regex.Pattern decode(RegexPatternProto patternProto) {
    return new RegexPatternProto(
      patternProto.getPattern(), patternProto.getFlags());
  }
}

我将单元测试作为练习 :) 我什至发现以这种方式进行序列化更可取,因为协议缓冲区具有向前和向后兼容性,而 java 序列化则存在问题。

【讨论】:

    【解决方案2】:

    我认为这是方钉圆孔的情况,protobuf和序列化不应该这样使用。

    无论如何,您似乎在每次 API 调用时都初始化了一个正则表达式。我不知道您的应用程序如何决定将哪个 Regex 用于特定 API,但您必须从 Regex 字符串开始进行编译。 与其尝试序列化模式,不如将其存储在内存中HashMap&lt;String,Pattern&gt;(正则表达式字符串作为键,编译模式作为值)。然后在需要时获取模式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-09
      • 2012-01-06
      • 2015-12-26
      • 2012-05-01
      • 2012-12-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多