я пытаюсь написать код для маскировки вложенных полей json..
def maskRecursively(map :mutable.Map[String,Object]):mutable.Map[String,Object] = {
val maskColumns = PII_Data.getPIIData()
for((k,v) <- map){
if (v.isInstanceOf[Map[String,Object]]){
maskRecursively(map.get(k).asInstanceOf[mutable.Map[String,Object]])
}else if (v.isInstanceOf[List[Object]]) {
} else {
if (maskColumns.contains(k)){map+=(k->"*****")}
}
}
map }
вызов этого метода из ..
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
val result = mapper.readValue(jsonStr, classOf[ java.util.Map[String,Object] ])
import scala.collection.JavaConverters._
val myScalaMap = result.asScala
maskRecursively(result.asScala)
я получаю сообщение об ошибке при попытке выполнить итерацию вложенного объекта json..
Cannot cast value of type 'scala.Some' to type 'scala.collection.mutable.Map'
как мне рекурсивно использовать сложный вложенный объект json таким образом?
Ваша ошибка была
if (v.isInstanceOf[Map[String,Object]]){
maskRecursively(map.get(k).asInstanceOf[mutable.Map[String,Object]])
Есть несколько вопросов:
v
экземпляром Map
, но затем пытаетесь привести его к mutable.Map
. Технически это разные типы (изменяемые и неизменяемые).v
, но затем применяете приведение к map.get(k)
, значение и тип которого будут отличаться от v
. Метод get
карты возвращает Option, отсюда и сообщение об ошибке.Map[String, Object]
и Map[SomethingElse, Whatever]
- оба будут выглядеть как Map
во время выполнения. По этой причине компилятор должен был предупредить вас о вызове isInstanceOf
.Если вы выполняете комбинацию isInstanceOf / asInstanceOf
, убедитесь, что операнд каждый раз один и тот же. У вас уже есть v
, поэтому вам не нужно искать его во второй раз на карте. И убедитесь, что вы используете один и тот же тип для обоих вызовов instanceOf.
Исправьте это, изменив его на
if (v.isInstanceOf[mutable.Map[_, _]]){
maskRecursively(v.asInstanceOf[mutable.Map[String,Object]])
После некоторого копания я смог решить эту проблему.
def maskJson(jsonStr: String): String = {
implicit val formats = org.json4s.DefaultFormats
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
val result = mapper.readValue(jsonStr, classOf[Map[String, Object]])
val maskedJson = maskRecursively(result)
mapper.writeValueAsString(maskedJson)
}
def maskRecursively(map: Map[String, Object]): collection.mutable.Map[String, Object] = {
val mutable = collection.mutable.Map[String, Object]()
val maskColumns = PII_Data.getJsonPIIFields()
for ((k, v) <- map) {
if (v.isInstanceOf[Map[String, Object]]) {
mutable += k -> maskRecursively(v.asInstanceOf[Map[String, Object]])
} else if (v.isInstanceOf[List[Object]]) {
val list = v.asInstanceOf[List[Map[String, Object]]].map(i => maskRecursively(i)).toList
mutable += k -> list
} else {
if (maskColumns.contains(k)) {
mutable += (k -> "*****")
}
else {
mutable += k -> v
}
}
}
mutable
}