根据 RFC 3986 的无效 URI 示例
Posted
技术标签:
【中文标题】根据 RFC 3986 的无效 URI 示例【英文标题】:Example of invalid URI as per RFC 3986 【发布时间】:2012-03-16 15:20:19 【问题描述】:对于我的单元测试,我想找到一个无法匹配 Spring MVC 3.1.1 中的 UriComponentsBuilder#URI_PATTERN
正则表达式的无效 URI 示例:
private static final String SCHEME_PATTERN = "([^:/?#]+):";
private static final String HTTP_PATTERN = "(http|https):";
private static final String USERINFO_PATTERN = "([^@/]*)";
private static final String HOST_PATTERN = "([^/?#:]*)";
private static final String PORT_PATTERN = "(\\d*)";
private static final String PATH_PATTERN = "([^?#]*)";
private static final String QUERY_PATTERN = "([^#]*)";
private static final String LAST_PATTERN = "(.*)";
// Regex patterns that matches URIs. See RFC 3986, appendix B
private static final Pattern URI_PATTERN = Pattern.compile(
"^(" + SCHEME_PATTERN + ")?" + "(//(" + USERINFO_PATTERN + "@)?" + HOST_PATTERN + "(:" + PORT_PATTERN +
")?" + ")?" + PATH_PATTERN + "(\\?" + QUERY_PATTERN + ")?" + "(#" + LAST_PATTERN + ")?");
我正在努力寻找一个会导致UriComponentsBuilder.fromUriString()
以IllegalArgumentException
失败的字符串。我尝试的任何东西都通过正则表达式检查作为有效的 URI。
【问题讨论】:
【参考方案1】:我认为任何东西都会匹配那个正则表达式。问题是正则表达式没有严格执行 RFC。相反,它被设计为允许的;即接受任何旧垃圾并尽最大努力将其解析为 URL。
(但是,我注意到它在解析非 HTTP URI 方面做得并不好。看看SCHEME_PATTERN
...然后哭泣。)
如果您想对 URI 进行严格的解析或验证,最好使用java.net.URI
。正则表达式不是此任务的正确工具。
【讨论】:
他们的 HTTP URL 模式更严格:private static final Pattern HTTP_URL_PATTERN = Pattern.compile( "^" + HTTP_PATTERN + "(//(" + USERINFO_PATTERN + "@)?" + HOST_PATTERN + "(:" + PORT_PATTERN + ")?" + ")?" + PATH_PATTERN + "(\\?" + LAST_PATTERN + ")?");
它不接受fragment
部分,这很奇怪,你认为这是一个错误吗?
“您认为这是一个错误吗?” - 您需要与 Spring MVC 开发人员争论这一点。我的看法是,使用正则表达式进行 URL/URI 解析是一大堆错误。只是不要这样做。以上是关于根据 RFC 3986 的无效 URI 示例的主要内容,如果未能解决你的问题,请参考以下文章
当相对 URI 包含空路径时,Java 的 URI.resolve 是不是与 RFC 3986 不兼容?
为啥 %(百分比)在 RFC 3986(URI 语法)中不被视为保留字符?
Java URL 类 getPath()、getQuery() 和 getFile() 与 RFC3986 URI 语法不一致
The valid characters are defined in RFC 7230 and RFC 3986报错处理
The valid characters are defined in RFC 7230 and RFC 3986报错处理