使用@Pattern验证UUID或UUID.toString()

时间:2018-12-31 01:04:15

标签: java spring annotations uuid

我们知道,@Pattern批注只能用于CharSequence的实现,例如String。因此,以下对UUID的验证将无效。

@Pattern(regexp="^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$")
private UUID                id;

是否可以直接在UUID上或基于UUID.toString()使用@Pattern注释?

实际情况:

public class IndexController {
    ...
    public ResponseEntity<Void> postIndexes(@ApiParam(value = INDEXES_DESC, required = true) @Valid @RequestBody @Size(min = 1, max = 2000) List<Index> indexes) {
        ...
    }
    ...
}

@JsonInclude(JsonInclude.Include.NON_NULL)
public class Index implements Serializable {
    @ApiModelProperty(value = ID_DESC, example = SINGLE_ID)
    @NotNull
    private UUID                id;
    ...
}

当用户输入如下所示的JSON格式的请求正文时

[
  {
    ...
    "id": "40336c2b-591a-4472-a270-A46339",
    ...
  }
]

它看起来不像普通的UUID。最后部分应包含12位数字,并且不应包含任何大写字母。 但是,此类输入将成功转换为UUID为“ 40336c2b-591a-4472-a270-000000a46339”的有效索引。 我们希望通过添加验证注释来使这种输入失败。

1 个答案:

答案 0 :(得分:2)

UUID!= String

您必须了解UUID不是 文本。 java.util.UUID对象不是String对象。 UUID是128-bit value,其中某些位每个the standard spec都有特殊含义。

人类在读写128位(例如128个01位)上的表现不佳。

  

1010 1111 0111 0000 0000 0101 1001 1100

     

1111 0110 0000 0100 0100 1100 1011 1101

     

1001 1101 0010 0111 0010 1100 1111 1111

     

0111 1110 0010 1000 0000 1011 0001 0011

因此,当提供供人类使用的UUID时,我们会将128位值转换为32个字符的hexadecimal字符串。典型地,这些十六进制字符与四个连字符分组,总共为36个字符。

每个UuidGenerator.net的示例:

  

af70059c-f604-4cbd-9d27-2cff7e280b13

这样的十六进制字符串不是UUID,它表示一个UUID值,这是一种方便的方式来读取或写入128位。

如果您手头有一个UUID Java对象,则您无需进行任何验证。确实,您没有针对任何字符串进行验证。因此正则表达式是无关紧要的。在大多数实现中,只有128位,内部存储为一对64位整数。

要验证规范格式的传入字符串,无需验证您的模式,只需使用UUID类进行分析并捕获异常。

通过UUID标准规范,要求所有小写形式都必须生成任何十六进制表示形式。许多实施(包括Apple和Microsoft的实施)都违反了此规则。规范还要求解析输入以容许大写。