java在android上解析查询字符串

bzzcjhmw  于 2021-07-05  发布在  Java
关注(0)|答案(25)|浏览(419)

java ee拥有 ServletRequest.getParameterValues() .
在非ee平台上, URL.getQuery() 只返回一个字符串。
当不在javaee上时,正确解析url中的查询字符串的正常方法是什么?
在答案中,尝试创建自己的解析器是很流行的。这是一个非常有趣和令人兴奋的微编码项目,但我不能说这是一个好主意。
下面的代码片段通常是有缺陷或损坏的。打破它们对读者来说是一个有趣的练习。以及攻击使用它们的网站的黑客。
解析查询字符串是一个定义良好的问题,但是阅读规范并理解其中的细微差别是非常重要的。最好让一些平台库编码人员来为您做艰苦的工作,并进行修复!

yk9xbfzb

yk9xbfzb1#

此方法获取par name和par value的uri和返回Map

public static Map<String, String> getQueryMap(String uri) {

    String queryParms[] = uri.split("\\?");

    Map<String, String> map = new HashMap<>();// 

    if (queryParms == null || queryParms.length == 0) return map;

    String[] params = queryParms[1].split("&");
    for (String param : params) {
        String name = param.split("=")[0];
        String value = param.split("=")[1];
        map.put(name, value);
    }
    return map;
}
siv3szwd

siv3szwd2#

这对我很有用。。我不知道为什么每个人都想要一张Map,我只需要一张简单的名值Map。
为了简单起见,我使用了内置的uri.getquery();

public static Map<String, String> getUrlParameters(URI uri)
    throws UnsupportedEncodingException {
    Map<String, String> params = new HashMap<String, String>();
    for (String param : uri.getQuery().split("&")) {
        String pair[] = param.split("=");
        String key = URLDecoder.decode(pair[0], "UTF-8");
        String value = "";
        if (pair.length > 1) {
            value = URLDecoder.decode(pair[1], "UTF-8");
        }
        params.put(new String(key), new String(value));
    }
    return params;
}
4nkexdtk

4nkexdtk3#

仅供参考,这是我最终得到的结果(基于urlencodedutils,并返回一个Map)。
特征:
它接受url的查询字符串部分(您可以使用 request.getQueryString() )
一个空的查询字符串将产生一个空的 Map 没有值(?test)的参数将Map到空值 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;
}

兼容性帮助程序(值存储在字符串数组中,就像在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;
}
x6h2sr28

x6h2sr284#

Guava的多重Map更适合这种情况。下面是一个简短的干净版本:

Multimap<String, String> getUrlParameters(String url) {
        try {
            Multimap<String, String> ret = ArrayListMultimap.create();
            for (NameValuePair param : URLEncodedUtils.parse(new URI(url), "UTF-8")) {
                ret.put(param.getName(), param.getValue());
            }
            return ret;
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }
vql8enpb

vql8enpb5#

在android上,我尝试使用@diyism answer,但遇到了@rpetrich提出的空格字符问题,例如:我填写了一个表单,其中 username = "us+us" 以及 password = "pw pw" 导致url字符串如下所示:

http://somewhere?username=us%2Bus&password=pw+pw

但是,@diyism代码返回 "us+us" 以及 "pw+pw" ,即不检测空格字符。如果url是用 %20 标识空格字符:

http://somewhere?username=us%2Bus&password=pw%20pw

这将导致以下修复:

Uri uri = Uri.parse(url_string.replace("+", "%20"));
uri.getQueryParameter("para1");
dl5txlt9

dl5txlt96#

ApacheAxis2有一个querystringparser.java的独立实现。如果您不使用axis2,只需从这里下载源代码和测试用例-
http://svn.apache.org/repos/asf/axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/transport/http/util/querystringparser.java
http://svn.apache.org/repos/asf/axis/axis2/java/core/trunk/modules/kernel/test/org/apache/axis2/transport/http/util/querystringparsertest.java

zlhcx6iw

zlhcx6iw7#

在android上:

import android.net.Uri;

[...]

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

dluptydi8#

我认为jre里没有。您可以在其他包(如apachehttpclient)中找到类似的函数。如果您不使用任何其他软件包,您只需编写自己的软件包。没那么难。这是我用的,

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;
 } 
}
zazmityj

zazmityj9#

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;
}
sshcrbum

sshcrbum10#

对于servlet或jsp页面,可以使用request.getparameter(“paramname”)获取querystring键/值对

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

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

628mspwn

628mspwn11#

使用apache httpcomponents并将其与一些集合代码连接起来,以便按值访问参数:http://www.joelgerard.com/2012/09/14/parsing-query-strings-in-java-and-accessing-values-by-key/

q9yhzks0

q9yhzks012#

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;
}
wvyml7n5

wvyml7n513#

如果类路径上有jetty(服务器或客户机)libs,则可以使用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");
niknxzdl

niknxzdl14#

在android上,apache库提供了一个查询解析器:
http://developer.android.com/reference/org/apache/http/client/utils/urlencodedutils.html 以及http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/utils/urlencodedutils.html

6ovsh4lw

6ovsh4lw15#

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
        }
    }
}

相关问题