如何在Java中解析和解码URI为URI组件?

6
我正在尝试查找一种方法来解析URL,对它进行解码并以一种明确的方式返回已解码的组件。
因为URLDecoder可能会返回含糊不清的字符串(例如),它并不是合适的选择。
URLDecoder.decode("http://www.google.com?q=abc%26def", "UTF-8")

返回:

http://www.google.com?q=abc&def 

因此,关于转义的 & 的信息丢失了。

我想要类似于:

DecodedUrlComponents cmp = GreatURLDecoder.decode(url);
Map<String, List<String>> decodedQuery = cmp.getQuery();
decodedQuery.get("q").get(0); //returns "abc&def"

我该如何实现这个?
编辑: 谢谢回答,但我的问题有点不同:我想以一种明确的方式获取解码组件,因此以下任何一种都无法满足我的需求:
  • new URI("http://www.google.com?q=abc%26def").getRawQuery() 返回编码查询:q=abc%26def
  • new URI("http://www.google.com?q=abc%26def").getQuery() 返回模棱两可的值:q=abc&def
  • URLDecoder.decode("http://www.google.com?q=abc%26def", "UTF-8") 返回模棱两可的值:http://www.google.com?q=abc&def
  • org.springframework.web.util.UriComponentsBuilder.fromUriString("http://www.google.com?q=abc%26def").build(true).getQueryParams() - 接近了,但仍然不是我想要的,因为它返回一个编码的参数映射:{q=[abc%26def]}
5个回答

2

使用Spring框架(org.springframework.web.util),您可以执行以下操作:

URI uri = <your_uri_here>;
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUri(uri);
UriComponents uriComponents = uriComponentsBuilder.build();
String path = uriComponents.getPath();
MultiValueMap<String, String> queryParams = uriComponents.getQueryParams(); //etc.

4
很遗憾,它不能正确解码使用百分号编码的查询参数。因此,如果您的URL可能包含查询参数,我建议不要使用它。 - Codo

1
你可以使用 javax.ws.rs.core.UriInfo 的实现。一个例子是org.jboss.resteasy.spi.ResteasyUriInfo。如果你正在使用maven,只需要将以下内容添加到pom.xml中即可:
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxrs</artifactId>
    <version>3.0.6.Final</version>
</dependency>

然后以下代码应该可以满足您的需求:
UriInfo ui = new ResteasyUriInfo(new URI("http://www.google.com?q=abc%26def"));
List<String> qValues = ui.getQueryParameters().get("q");
for (String q : qValues) {
    System.out.println(q);
}

谢谢,看起来它完成了它的工作。但我对它并不是非常满意——仅仅为了解析和解码URL而依赖于JAX-RS似乎有些过度设计了。 - tomkur
同意,这确实是很多额外的东西。你最好只从他们的源代码库中复制该类,并包含那个文件。 - Petter
1
此外,如果您使用的是Jersey 2而不是RESTEasy进行JAX-RS,则可以使用org.glassfish.jersey.uri.UriComponent.decodeQuery(URI,boolean)和相关的decode *方法。 - Ben Hutchison

0
请使用以下内容:
String url = "http://www.google.com?test=34%3fg";
URL testUrl = new java.net.URL(url);
System.out.println(testUrl.getQuery());

应该打印出 test=34%3fg。


0

URLDecoder 不会将您的 URL 拆分为组件,它只是将其字符串表示形式转换为特定格式,正如它的 JavaDoc 和签名所示,该签名返回一个字符串。正如其他人提到的,您应该从您的字符串构建一个 URL 对象,它公开了您需要的所有功能。请参见 这里


-1

从您的URL字符串生成一个java.net.URL,然后使用像url.getQuery()url.getProtocol()url.getHost()等方法 - 一切都在那里。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接