Java EE有ServletRequest.getParameterValues()。

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

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


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

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

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


当前回答

我有方法来实现这一点:

1):

public static String getQueryString(String url, String tag) {
    String[] params = url.split("&");
    Map<String, String> map = new HashMap<String, String>();
    for (String param : params) {
        String name = param.split("=")[0];
        String value = param.split("=")[1];
        map.put(name, value);
    }

    Set<String> keys = map.keySet();
    for (String key : keys) {
        if(key.equals(tag)){
         return map.get(key);
        }
        System.out.println("Name=" + key);
        System.out.println("Value=" + map.get(key));
    }
    return "";
}

2)和最简单的方法来做这个使用Uri类:

public static String getQueryString(String url, String tag) {
    try {
        Uri uri=Uri.parse(url);
        return uri.getQueryParameter(tag);
    }catch(Exception e){
        Log.e(TAG,"getQueryString() " + e.getMessage());
    }
    return "";
}

这是一个如何使用两种方法之一的例子:

String url = "http://www.jorgesys.com/advertisements/publicidadmobile.htm?position=x46&site=reform&awidth=800&aheight=120";      
String tagValue = getQueryString(url,"awidth");

tagValue的值为800

其他回答

对于servlet或JSP页面,您可以使用request.getParameter("paramname")获取查询字符串的键/值对。

String name = request.getParameter("name");

还有其他方法,但我在创建的所有servlet和jsp页面中都是这样做的。

你说“Java”,但“不是Java EE”。您的意思是您正在使用JSP和/或servlet,而不是完整的Java EE堆栈?如果是这种情况,那么您应该仍然可以使用request.getParameter()。

如果你的意思是你正在编写Java,但你没有编写jsp或servlet,或者你只是使用Java作为参考点,但你在一些没有内置参数解析的其他平台上……哇,这听起来像是一个不太可能的问题,但如果是这样的话,原则是:

xparm=0
word=""
loop
  get next char
  if no char
    exit loop
  if char=='='
    param_name[xparm]=word
    word=""
  else if char=='&'
    param_value[xparm]=word
    word=""
    xparm=xparm+1
  else if char=='%'
    read next two chars
    word=word+interpret the chars as hex digits to make a byte
  else
    word=word+char

(我可以编写Java代码,但这将是毫无意义的,因为如果您有Java可用,您可以只使用request.getParameters。)

public static Map <String, String> parseQueryString (final URL url)
        throws UnsupportedEncodingException
{
    final Map <String, String> qps = new TreeMap <String, String> ();
    final StringTokenizer pairs = new StringTokenizer (url.getQuery (), "&");
    while (pairs.hasMoreTokens ())
    {
        final String pair = pairs.nextToken ();
        final StringTokenizer parts = new StringTokenizer (pair, "=");
        final String name = URLDecoder.decode (parts.nextToken (), "ISO-8859-1");
        final String value = URLDecoder.decode (parts.nextToken (), "ISO-8859-1");
        qps.put (name, value);
    }
    return qps;
}
public static Map<String, List<String>> getUrlParameters(String url)
        throws UnsupportedEncodingException {
    Map<String, List<String>> params = new HashMap<String, List<String>>();
    String[] urlParts = url.split("\\?");
    if (urlParts.length > 1) {
        String query = urlParts[1];
        for (String param : query.split("&")) {
            String pair[] = param.split("=", 2);
            String key = URLDecoder.decode(pair[0], "UTF-8");
            String value = "";
            if (pair.length > 1) {
                value = URLDecoder.decode(pair[1], "UTF-8");
            }
            List<String> values = params.get(key);
            if (values == null) {
                values = new ArrayList<String>();
                params.put(key, values);
            }
            values.add(value);
        }
    }
    return params;
}

仅供参考,这是我最终得到的结果(基于URLEncodedUtils,并返回一个Map)。

特点:

它接受url的查询字符串部分(你可以使用request.getQueryString()) 空查询字符串将产生空Map 没有值的参数(?test)将被映射为空List<String>

代码:

public static Map<String, List<String>> getParameterMapOfLists(String queryString) {
    Map<String, List<String>> mapOfLists = new HashMap<String, List<String>>();
    if (queryString == null || queryString.length() == 0) {
        return mapOfLists;
    }
    List<NameValuePair> list = URLEncodedUtils.parse(URI.create("http://localhost/?" + queryString), "UTF-8");
    for (NameValuePair pair : list) {
        List<String> values = mapOfLists.get(pair.getName());
        if (values == null) {
            values = new ArrayList<String>();
            mapOfLists.put(pair.getName(), values);
        }
        if (pair.getValue() != null) {
            values.add(pair.getValue());
        }
    }

    return mapOfLists;
}

兼容性帮助器(值存储在String数组中,就像在ServletRequest.getParameterMap()中一样):

public static Map<String, String[]> getParameterMap(String queryString) {
    Map<String, List<String>> mapOfLists = getParameterMapOfLists(queryString);

    Map<String, String[]> mapOfArrays = new HashMap<String, String[]>();
    for (String key : mapOfLists.keySet()) {
        mapOfArrays.put(key, mapOfLists.get(key).toArray(new String[] {}));
    }

    return mapOfArrays;
}