我有一组要匹配请求的策略。如果该策略存在,我想匹配请求并查看值是否匹配。
策略为List<Policies> -> (key: String, value: String)
,请求中可以包含不同的密钥。
示例:
策略是请求应匹配的一组规则。
class Policy {
val key: String,
val value: String
}
请求是一个数据类,其中包含不同的值(所有可选值),例如姓,名,地址,++++
data class Request (
id: Long = 12,
firstName: String = "test",
surname: String = "test",
address: String = "somewhere"
...// more fields
)
策略列表如下所示(列表):
List<Policy> => [
{
key: "surname",
value: "test"
},
{
key: "firstName",
value: "test"
}
]
我不知道如何将策略与请求匹配。 Policy.key是字符串,并且Request可以包含属性的所有不同变体。
如何将策略列表与我的数据类Request相匹配?
答案 0 :(得分:1)
出于您的目的,您需要使用反射(您想按名称查找字段并获取值),或更改模型中的某些内容。
反射解决方案如下:
data class Policy(
val key: String,
val value: String?
)
data class Request(
val id: Int,
val firstName: String? = null,
val surname: String? = null,
val address: String? = null
)
class PolicyException : Exception()
fun checkPolicies(request: Request, policies: List<Policy>) {
policies.forEach { policy ->
val member = request::class.members.find { member -> member.name == policy.key }
val requestMemberValue = member?.call(request)
if (requestMemberValue != policy.value) throw PolicyException()
}
}
fun main(args: Array<String>) {
println("Hello, reflection!")
checkPolicies(Request(id = 0, firstName = "Johnn"), listOf(Policy("firstName", "John")))
}
此外,我更改了策略模型以处理可为空的值(并且仍然正确地将“ null”作为字符串处理)。
但是,使用此解决方案时,更改模型名称必须非常小心。并且要注意不要混淆您的模型。
另外,更好的解决方案是添加Annotation(注释),该策略将策略名称保留为注释属性(然后,在应用程序中更改字段名称的问题将消失)。