我有一个要求,用户希望通过restapi(get call)过滤表(api过滤应该允许使用括号来定义操作优先级,并使用可用字段的任何组合)。支持的操作应包括or、and、eq(equals)、ne(not equals)、gt(greater than)、lt(lower than)、in、like)
用例示例:
假设表中有一列user\u id、first\u name、last\u name、food\u take\u carries,创建于
查询应支持(在公式'2016-05-01'中创建)和((食物摄入热量gt 20)或(食物摄入热量lt 10))。
我首先想到用“=”代替eq,用“!=”代替ne然后直接将其附加到sql的where子句并运行查询,但这将再次邀请sql注入。我不知道如何处理这件事。我使用java和dropwizard作为后端服务器。
3条答案
按热度按时间y3bcpkx11#
我的建议是使用jexl表达式解析器来形式化这个解析。
可以替换一些大括号并使用自定义代码来处理请求,但是随着需求的缓慢变化,您会得到一个解析rest请求的复杂代码。
jdzmm42g2#
小田是正确的选择。它有为用户用例设计的规范。使用这种标准的数据表示方式的优点是,只要每个人都遵循标准的odata查询,他们就可以使用您的api。
结帐:https://www.odata.org/
希望这有帮助!!
6tr1vspr3#
我认为把解析完整表达式的责任转移到sql上并不一定有问题,只要您先检查它。你可以设计一套规则:
无需更换支架
在和或上分开
剩下的语句集必须是
column operator 'value'
列必须在已知列的集合中运算符必须在已知运算符集中
值必须以“开始”和“结束”,介于之间的所有内容都将被视为一个值
替换实际值
value
对于db参数占位符,并将给定的数据值放入该参数的值中—将这些值放入哈希Map键集中以消除重复数据,然后在原始api查询字符串中逐个替换它们,并将它们作为参数添加到db命令中现在,您将得到这样一种状态:查询适合在没有注入风险的db上运行—列和运算符位于已知集合中,并且值是参数化的
如果 predicate 是如此自由的形式,您可能需要考虑限制结果或执行的数量/用于这些查询的db时间量