如何在java中有效地解析查询参数?

Posted

技术标签:

【中文标题】如何在java中有效地解析查询参数?【英文标题】:How to parse query param effectively in java? 【发布时间】:2017-09-22 00:11:51 【问题描述】:

我所拥有的只是请求 URI,我必须从中解析查询参数。我正在做的是将它们添加到 json/hashmap 并再次获取,如下所示

String requestUri = "name=raju&school=abcd&college=mnop&color=black&fruit=mango";

我所要做的就是最终将它分配给如下变量

String name = "raju";
String school = "abcd";
String college = "mnop";
String color = "black";
String fruit = "mango";

所以我正在解析请求 uri,如下所示

String[] paramsKV = requestUri.split("&");
JSONArray jsonKVArr = new JSONArray();
for (String params : paramsKV) 
    String[] tempArr = params.split("=");
    if(tempArr.length>1) 
        String key = tempArr[0];
        String value = tempArr[1];
        JSONObject jsonObj = new JSONObject();
        jsonObj.put(key, value);
        jsonKVArr.put(jsonObj);
     
 

另一种方法是在哈希映射中填充相同的内容并获得相同的内容。另一种方法是将requestUri字符串与正则表达式匹配并获得结果。

举个例子来获取school 的值,我必须匹配字符串school 和下一个& 之间的值——这听起来不太好。

    在 java 中解析查询字符串的更好方法是什么? 我怎样才能更好地处理以下事情?

我需要从上面的结果中构造另一个像下面这样的哈希映射

Map<String, String> resultMap = new HashMap<String, String>;

resultMap.put("empname", name);
resultMap.put("rschool", school);
resultMap.put("empcollege", college);
resultMap.put("favcolor", color);
resultMap.put("favfruit", fruit);

为了简单起见,我所要做的就是解析查询参数并通过以不同的方式命名key 来构造一个hashMap。我怎么能以简单的方式做到这一点?非常感谢您提供任何帮助。

【问题讨论】:

【参考方案1】:

使用杰克逊 json 解析器。 Maven 依赖:

<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.5.3</version>
        </dependency>

现在使用 ObjectMapper 从 json 字符串创建地图:

ObjectMapper mapper = new ObjectMapper();
Map list = mapper.readValue(requestUri, Map.class);

【讨论】:

【参考方案2】:

您可以使用 Java 8 并通过一次操作将数据存储在 HashMap 中。

Map<String,String> map = Pattern.compile("\\s*&\\s*")
                .splitAsStream(requestUri.trim())
                .map(s -> s.split("=", 2))
                .collect(Collectors.toMap(a -> a[0], a -> a.length > 1 ? a[1]: ""));

【讨论】:

【参考方案3】:

简短回答:每个 HTTP 客户端库都会为您执行此操作。

示例:Apache HttpClient 的 URLEncodedUtils 类

String queryComponent = "name=raju&school=abcd&college=mnop&color=black&fruit=mango";
List<NameValuePair> params = URLEncodedUtils.parse(queryComponent, Charset.forName("UTF-8"));

他们基本上以同样的方式接近它。参数键值对由&amp; 分隔,值中的键由= 分隔,因此String 的split 对两者都适用。

据我所知,但是您的 hashmap 插入正在将新键映射到现有值,因此实际上没有优化,可能是为了提高可读性/维护和/或丢弃初始 jsonArray 并直接映射到 Java 8 Stream哈希图。

【讨论】:

【参考方案4】:

这是另一种可能的解决方案:

    Pattern pat = Pattern.compile("([^&=]+)=([^&]*)");
    Matcher matcher = pat.matcher(requestUri);
    Map<String,String> map = new HashMap<>();
    while (matcher.find()) 
        map.put(matcher.group(1), matcher.group(2));
    
    System.out.println(map);

【讨论】:

【参考方案5】:

您可以通过 Jersey 库(com.sun.jersey.api.uri.UriComponentorg.glassfish.jersey.uri.UriComponent 类)来实现:

String queryComponent = "name=raju&school=abcd&college=mnop&color=black&fruit=mango";
MultivaluedMap<String, String> params = UriComponent.decodeQuery(queryComponent, true);

【讨论】:

以上是关于如何在java中有效地解析查询参数?的主要内容,如果未能解决你的问题,请参考以下文章

如何有效地将 if 和 else 用于过滤构造?

如何在 JavaScript 中删除查询字符串参数?

如何在 Blender 中有效地更改多个对象的相同参数?

如何获取大量 GET 参数并根据它们干净地过滤查询?

如何在查询生成器中有效地转换嵌套 SQL [重复]

如何在 Access 中进行查询将 tempvar 识别为有效字段(参数)