【问题标题】:Spring-boot filter handling with query params使用查询参数处理 Spring-boot 过滤器
【发布时间】:2020-03-08 09:29:25
【问题描述】:

在 REST 端点中,我想接收过滤器作为查询参数。每个过滤器都定义在一个用逗号分隔的键值对中,如下所示:

www.example.com/things?filter=key:value,key2:value2,key3:value3

这个例子意味着我想要得到的东西列表必须有 key 作为value key2 作为value2 强> key3 as value3

在此端点中,我可以接收多个过滤器,如下所示:

www.example.com/things?filter=key:value&filter=key2:value2,key3:value3

这意味着事物列表必须有keyvalue key2value2key3value3

在spring-boot中,接收多个同名查询参数的方法是在你的控制器中定义一个@RequestParam("filter") String[] filters。但问题是:每当我只发送一个filter 查询参数时,我都会得到一个由每个键对值组成的字符串数组。如果我发送多个filter,我会得到一个包含每个过滤器的数组(如预期的那样)。

这意味着对于第一个示例,每个密钥对都有一个大小为 3 的数组,而在第二个示例中,我将收到一个大小为 2 的数组。

我需要这样,每当我只发送一个 filter 作为查询参数时,@RequestParam 标记都会提供一个大小为 1 的数组,其中整个字符串将在以后进行解析。有没有办法做到这一点?

【问题讨论】:

    标签: java spring-boot query-parameters


    【解决方案1】:

    可能有更好的方法来实现您的目标,但这是我的建议。

    概念的快速证明,使用Spring Boot 2.2.1.RELEASE,将每个过滤器打印在单独的行上

    import org.springframework.util.MultiValueMap;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/things")
    public class ThingController {
    
        @GetMapping
        public void filters(@RequestParam MultiValueMap<String, String> filters) {
            System.out.println("Filters:");
            filters.get("filter").forEach(System.out::println);
        }
    }
    

    仅使用单个 filter 查询参数的 curl 命令:

    curl -v 'http://localhost:8080/things/?filter=key:value,key2:value2,key3:value3'
    

    打印:

    Filters:
    key:value,key2:value2,key3:value3
    

    仅使用多个 filter 查询参数的 curl 命令:

    curl -v 'http://localhost:8080/things/?filter=key:value&filter=key2:value2,key3:value3'
    

    打印:

    Filters:
    key:value
    key2:value2,key3:value3
    

    【讨论】:

    • 这正是我所需要的。但实际上我已经复制并粘贴了代码,我得到了Failed to convert value of type 'java.lang.String' to required type 'org.springframework.util.MultiValueMap'。也许我错过了一个进口?
    • 将导入添加到 ThingController 示例。还包括 Spring Boot 版本(也使用 Spring Boot 2.1.6.RELEASE 进行了测试)。您是否逐字复制了ThingController,并尝试使用提供的curl 命令?
    • 问题是我将粘贴的代码更改为 @RequestParam("filter") 以某种方式使其失败。正如您的示例所述,当我将其留空时,它起作用了。
    【解决方案2】:

    您想要实现的实际上是默认行为。如果你在@RequestParam 中声明一个数组,无论你发送多少个参数,你都会在数组中拥有查询参数。

    编辑: 例如,给定这个控制器:

    @GetMapping("/things")
    public ResponseEntity getThings(@RequestParam("filter") String[] filters) {
    
        return ResponseEntity.ok(filters);
    }
    

    您可以通过两种不同的方式调用它:

    • www.example.com/things?filter=key:value,key2:value2,key3:value3
    • www.example.com/things?filter=key:value&filter=key2:value2&filter=key3:value3

    它们都映射到同一个数组:

    [
     "key:value",
     "key2:value2",
     "key3:value3"
    ]
    

    EDIT2:我刚刚检查过你不能混合使用这两种方式。如果这样做,逗号分隔的项目将在同一个数组项目中。也许这发生在你身上

    【讨论】:

    • 我想要的是逗号分隔的项目都在数组中的一个位置,对于我定义的每个 filter 查询参数。
    • 现在我完全理解你的问题了。那么恐怕你需要实现自己的转换器,看看这个:stackoverflow.com/questions/4998748/…
    猜你喜欢
    • 2018-08-29
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 2018-06-27
    • 1970-01-01
    • 2016-03-25
    • 2016-12-15
    相关资源
    最近更新 更多