【问题标题】:How to map dynamic query parameters in Spring Boot RestController如何在 Spring Boot RestController 中映射动态查询参数
【发布时间】:2019-01-07 13:36:01
【问题描述】:

是否可以使用 Spring Boot 将查询参数映射到动态名称?我想映射这些参数:

/products?filter[name]=foo
/products?filter[length]=10
/products?filter[width]=5

我可以做这样的事情,但它需要知道每个可能的过滤器,我希望它是动态的:

@RestController
public class ProductsController {
    @GetMapping("/products")
    public String products(
            @RequestParam(name = "filter[name]") String name,
            @RequestParam(name = "filter[length]") String length,
            @RequestParam(name = "filter[width]") String width
    ) {
        //
    }
}

如果可能的话,我正在寻找允许用户定义任意数量的可能过滤器值的东西,并且这些过滤器值可以通过 Spring Boot 映射为 HashMap

@RestController
public class ProductsController {
    @GetMapping("/products")
    public String products(
            @RequestParam(name = "filter[*]") HashMap<String, String> filters
    ) {
        filters.get("name");
        filters.get("length");
        filters.get("width");
    }
}

this question 上发布的答案建议使用@RequestParam Map&lt;String, String&gt; parameters,但这将捕获所有 查询参数,而不仅仅是匹配filter[*] 的那些。

【问题讨论】:

标签: java spring-boot spring-restcontroller query-parameters


【解决方案1】:

您可以映射多个参数,而无需使用映射在@RequestParam 中定义它们的名称:

@GetMapping("/api/lala")
public String searchByQueryParams(@RequestParam Map<String,String> searchParams) {
    ...
}

【讨论】:

    【解决方案2】:

    矩阵变量对您有用吗?如果我理解正确的话,可以是这样的:

    // GET /products/filters;name=foo;length=100
    

    @GetMapping("/products/filters") 公共无效产品( @MatrixVariable MultiValueMap matrixVars) {

    // matrixVars: ["name" : "foo", "length" : 100]
    

    }

    【讨论】:

    • 有意思,以前没见过这种格式化查询参数的方式。鉴于它在 Spring (@MatrixVariable) 中有自己的注释,那么 Spring/Java 服务通常就是这样做的。我习惯了使用 foo=barfilter[x]=ylist[]=x&amp;list[]=y 的 Rails - 我发现它更具可读性。
    【解决方案3】:

    这似乎是一个可以解决的问题。据我所知,解决方案并不理想,但有办法。

    之前的尝试似乎一心想要找到一个完美的解决方案,其中过滤器的整个成分在运输过程中都是已知的。

    Spring MVC populate

    用户定义的整个动态标准可以使用您定义的一些基本方案传输,作为来自客户端的一个 key=value 参数,然后在收到后分解为其元素。

    您还可以发送两个参数:“fields”和“values”,其中每个参数的列表分别在其中编码,并带有您选择的一些谨慎的分隔符(可能是用户无法实际输入的编码特殊字符,也许)。

    您仍然需要与客户端提交标准(如过滤标准)的所有其他方法一样,全面保护参数免受任何恶意使用,就像客户端试图在其中嵌入 SQL 标准(SQL 注入) .

    但只要客户端代码遵循约定的语法,您就可以一次性从它们那里接收任意数量的动态参数。

    客户:

    /products?filter=field1--value1||field2--value2||field3--value3... 
    

    这是一个简化的示例,显示了太容易“破坏”的分隔符,但这个想法是一些简单,甚至完全可读(这样做没有害处)的方案,只是为了将您的字段名称和值打包在一起交通便利。

    服务器:

    @RequestMapping(value = "/products", method = RequestMethod.GET)
        public String doTheStuff(@RequestParam(value = "filter") String encodedFilter) {
    
    .. decompose the filter here, filter everything they've sent for disallowed characters etc. 
    

    【讨论】:

    • 感谢您的回复。我选择使用我认为“标准”格式以及我习惯于来自 Ruby on Rails 背景的格式来格式化过滤器。我倾向于使用f[x]=y 格式。由于您引用的问题的可能性,例如 SQL 注入和确保分隔符正常工作,我建议采用自己的标准来表示过滤器。
    猜你喜欢
    • 2016-06-27
    • 1970-01-01
    • 2016-01-13
    • 2015-03-21
    • 2017-01-03
    • 2022-08-23
    • 2011-12-08
    • 2016-12-24
    • 1970-01-01
    相关资源
    最近更新 更多