Я сейчас экспериментирую с Spring-Boot 2 Kotlin Reactive. Одна из моих конечных точек должна иметь возможность разрешать номер телефона из MongoDB человеку, компании или отделу.
В результате отображаемое имя должно, например, для телефона должна быть возвращена в виде строки.
Результат можно изменить с помощью параметров в запросе:
Значения имени, фамилии, компании и отдела указывают порядок в отображаемом имени.
Если «xxxxxxxxxxx» - это номер человека, ответ должен выглядеть следующим образом:
"фамилия, имя, компания, отдел"
Я нашел решение этого, но мне интересно, нет ли лучшего способа.
fun findNumberOwner(serverRequest: ServerRequest) =
numberRepository.findByNumber(serverRequest.pathVariable("number")).flatMap { n ->
serverRequest.queryParam("asString")
.filter {
it.trim()
.isNotEmpty().and(it.toBoolean())
}
.map { searchNumberWithStringResult(n, serverRequest.queryParam("firstname"), serverRequest.queryParam("lastname"), serverRequest.queryParam("company"), serverRequest.queryParam("department")) }
.orElse(searchNumberWithJsonResult(n))
}.switchIfEmpty(ServerResponse.notFound().build())
private fun searchNumberWithStringResult(number: Number, firstname: Optional<String>, lastname: Optional<String>, company: Optional<String>, department: Optional<String>): Mono<ServerResponse> {
val ownerId = number.numberOwner
if (ownerId.startsWith("CO-")) {
return ok().body(companyRepository.findById(ownerId).map { it.name })
} else if (ownerId.startsWith("DE-")) {
return ok().body(departmentRepository.findById(ownerId)
.map { dep ->
companyRepository.findById(dep.company)
.map {
it.name
}.zipWith(dep.toMono())
}.flatMap { it ->
it
}.map {
it.t1 + ", " + it.t2.name
})
} else {
val templateMap = mapOf(
Pair("firstname", firstname.orElse("2").toInt()),
Pair("lastname", lastname.orElse("1").toInt()),
Pair("company", company.orElse("0").toInt()),
Pair("department", department.orElse("0").toInt())
)
return ok().body(personRepository.findById(ownerId)
.map { person ->
companyRepository.findById(person.company)
.map {
it.name
}
.switchIfEmpty(Mono.just(""))
.zipWith(person.toMono())
}.flatMap { it ->
it
}.map { t ->
departmentRepository.findById(t.t2.department).map {
mapOf(
Pair(templateMap["firstname"], t.t2.firstName) as Pair<Int, String>,
Pair(templateMap["lastname"], t.t2.lastName) as Pair<Int, String>,
Pair(templateMap["company"], t.t1) as Pair<Int, String>,
Pair(templateMap["department"], it.name) as Pair<Int, String>)
.filter { it.key > 0 }.filter { !it.value.equals("") }.toSortedMap()
}
.switchIfEmpty(Mono.just(
mapOf(
Pair(templateMap["firstname"], t.t2.firstName) as Pair<Int, String>,
Pair(templateMap["lastname"], t.t2.lastName) as Pair<Int, String>,
Pair(templateMap["company"], t.t1) as Pair<Int, String>)
.filter { it.key > 0 }.filter { !it.value.equals("") }.toSortedMap()
))
}.flatMap { it -> it }
.map { it }
.map { myMap ->
var finalDisplayString = ""
myMap.forEach {
finalDisplayString += buildDisplayString(it.key, myMap.size, it.value)
}
finalDisplayString
})
}
}
private fun buildDisplayString(index: Int, maxSize: Int, value: String?): String {
if (value == null) return ""
if (index == 0) {
return "$value, "
} else if (index == maxSize) {
return "$value"
} else {
return "$value, "
}
}
map{it}ничего не делает. Вместоmap, за которым следуетflatMap{it->it}, вы можете просто сделатьflatMap.