Java EE有ServletRequest.getParameterValues()。

在非ee平台上,URL.getQuery()只是返回一个字符串。

当不在Java EE上时,正确解析URL中的查询字符串的正常方法是什么?


在回答中,尝试创建自己的解析器是很受欢迎的。这是一个非常有趣和令人兴奋的微编码项目,但我不能说这是一个好主意。

下面的代码段通常是有缺陷或损坏的。对读者来说,打破它们是一项有趣的练习。还有攻击使用它们的网站的黑客。

解析查询字符串是一个明确定义的问题,但阅读规范并理解其中的细微差别并非易事。最好是让一些平台库编码器为您做艰苦的工作,并进行修复!


当前回答

在Android上:

import android.net.Uri;

[...]

Uri uri=Uri.parse(url_string);
uri.getQueryParameter("para1");

其他回答

我认为JRE中没有。您可以在其他包(如Apache HttpClient)中找到类似的函数。如果不使用任何其他包,则只需编写自己的包。这并不难。这是我用的,

public class QueryString {

 private Map<String, List<String>> parameters;

 public QueryString(String qs) {
  parameters = new TreeMap<String, List<String>>();

  // Parse query string
     String pairs[] = qs.split("&");
     for (String pair : pairs) {
            String name;
            String value;
            int pos = pair.indexOf('=');
            // for "n=", the value is "", for "n", the value is null
         if (pos == -1) {
          name = pair;
          value = null;
         } else {
       try {
        name = URLDecoder.decode(pair.substring(0, pos), "UTF-8");
              value = URLDecoder.decode(pair.substring(pos+1, pair.length()), "UTF-8");            
       } catch (UnsupportedEncodingException e) {
        // Not really possible, throw unchecked
           throw new IllegalStateException("No UTF-8");
       }
         }
         List<String> list = parameters.get(name);
         if (list == null) {
          list = new ArrayList<String>();
          parameters.put(name, list);
         }
         list.add(value);
     }
 }

 public String getParameter(String name) {        
  List<String> values = parameters.get(name);
  if (values == null)
   return null;

  if (values.size() == 0)
   return "";

  return values.get(0);
 }

 public String[] getParameterValues(String name) {        
  List<String> values = parameters.get(name);
  if (values == null)
   return null;

  return (String[])values.toArray(new String[values.size()]);
 }

 public Enumeration<String> getParameterNames() {  
  return Collections.enumeration(parameters.keySet()); 
 }

 public Map<String, String[]> getParameterMap() {
  Map<String, String[]> map = new TreeMap<String, String[]>();
  for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
   List<String> list = entry.getValue();
   String[] values;
   if (list == null)
    values = null;
   else
    values = (String[]) list.toArray(new String[list.size()]);
   map.put(entry.getKey(), values);
  }
  return map;
 } 
}

在Android上,代码如下所示:

UrlQuerySanitizer sanitzer = new UrlQuerySanitizer(url);
String value = sanitzer.getValue("your_get_parameter");

另外,如果你不想注册每个预期的查询键使用:

sanitzer.setAllowUnregisteredParamaters(true)

在调用之前:

sanitzer.parseUrl(yourUrl)
if (queryString != null)
{
    final String[] arrParameters = queryString.split("&");
    for (final String tempParameterString : arrParameters)
    {
        final String[] arrTempParameter = tempParameterString.split("=");
        if (arrTempParameter.length >= 2)
        {
            final String parameterKey = arrTempParameter[0];
            final String parameterValue = arrTempParameter[1];
            //do something with the parameters
        }
    }
}

如果你的类路径上有jetty(服务器或客户端)库,你可以使用jetty util类(参见javadoc),例如:

import org.eclipse.jetty.util.*;
URL url = new URL("www.example.com/index.php?foo=bar&bla=blub");
MultiMap<String> params = new MultiMap<String>();
UrlEncoded.decodeTo(url.getQuery(), params, "UTF-8");

assert params.getString("foo").equals("bar");
assert params.getString("bla").equals("blub");

在Android上:

import android.net.Uri;

[...]

Uri uri=Uri.parse(url_string);
uri.getQueryParameter("para1");