即使使用 Scala Jackson 出现错误,我如何遍历 JSON 个对象

How can I iterate through JSON objects even there is error using Scala Jackson

目前,jackson 拒绝整个 JSON 当有空白 属性 值时。

我想使用 com.fasterxml.jackson.* 来解析 JSON 代码。

正如你在下面输入JSON看到的,一些元素的名称属性是空白的。

Hense 遍历 JSON 个对象将被 Jackson 忽略。

因此将形成 2 个元素作为输出的一部分。

我正在使用下面的代码,但运气不好

 def readJsonString[T](content: String)(implicit m: Manifest[T]): T = {
    val objectMapper = new ObjectMapper(new JsonFactory().enable(Feature.ALLOW_COMMENTS)) with ScalaObjectMapper
    objectMapper.registerModule(DefaultScalaModule)
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    objectMapper.configure(DeserializationFeature.WRAP_EXCEPTIONS, false)
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
    objectMapper.readValue(content)

  }

//我想用作输入的现有 Json,其中某些属性具有空白值 ​​

[
                {
                    "name": "Invalid",
                    "ruleType": "validation_1",
                    "inputs": [ { "Name": "", "country": ["USA"] } ]
                    
                },
                {
                    "name": "",
                    "ruleType": "validation_2",
                    "inputs": [ { "Name": "Test", "place": ["USA"] } ]
                    
                },
                {
                    "name": "Valid",
                    "ruleType": "validation_1",
                    "inputs": []
                    
                }
                {
                    "name": "Valid",
                    "ruleType": "validation_2",
                    "inputs": [ { "Name": "Test", "place": ["USA"] } ]
                    
                },
                {
                    "name": "Valid",
                    "ruleType": "validation_1",
                    "inputs": [ { "Name": "Test", "place": ["France"] } ]
                    
                }
        ]

//将从上面创建的具有正确名称属性值的新 Json

[
                {
                    "name": "Valid",
                    "ruleType": "validation_1",
                    "inputs": [ { "Name": "Test", "country": ["USA"] } ]
                    
                }
                 
                {
                    "name": "Valid",
                    "ruleType": "validation_1",
                    "inputs": [ { "Name": "Test", "place": ["France"] } ]
                    
                }
        ]

这是一个可以使用 jackson 的解决方案:

案例 类 将您的 json 映射到:

  case class NamePlace(Name: String, country: Seq[String])
  case class NameRuleTypeInputs(name: String, ruleType: String, inputs: Seq[NamePlace])

自定义序列化程序以在序列化之前包含字段验证:

  class NameRuleTypeInputsSerializer(defaultSerializer: JsonSerializer[Object]) extends JsonSerializer[NameRuleTypeInputs] {
    override def serialize(value: NameRuleTypeInputs, gen: JsonGenerator, serializers: SerializerProvider): Unit = {
      if (isValid(value)) {
        defaultSerializer.serialize(value, gen, serializers)
      }
    }

    private def isValid(value: NameRuleTypeInputs) = {
      !Option(value.name).getOrElse("").isEmpty &&
        Option(value.inputs).getOrElse(Seq.empty).nonEmpty &&
        !value.inputs.exists(i => Option(i.Name).getOrElse("").isEmpty)
    }
  }

更新了您的 objectMapper 以包含自定义序列化程序:

  val objectMapper = new ObjectMapper(new JsonFactory().enable(Feature.ALLOW_COMMENTS)) with ScalaObjectMapper
  objectMapper.registerModule(DefaultScalaModule)
  objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
  objectMapper.configure(DeserializationFeature.WRAP_EXCEPTIONS, false)
  objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
  objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
  objectMapper.registerModule(new SimpleModule(){
    override def setupModule(context: Module.SetupContext): Unit = {
      super.setupModule(context)
      context.addBeanSerializerModifier(new BeanSerializerModifier() {
        override def modifySerializer(config: SerializationConfig, beanDesc: BeanDescription, serializer: JsonSerializer[_]): JsonSerializer[_] = {
          if(classOf[NameRuleTypeInputs] isAssignableFrom beanDesc.getBeanClass) {
            new NameRuleTypeInputsSerializer(serializer.asInstanceOf[JsonSerializer[Object]])
          } else {
            serializer
          }
        }
      })
    }
  })

方法 read/write json:

  def readJsonString[T](content: String)(implicit m: Manifest[T]): T = {
    objectMapper.readValue(content)
  }

  def writeJsonString(nameRuleTypeInputsList: Seq[NameRuleTypeInputs]): String = {
    // Using pretty printer for readability
    objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(nameRuleTypeInputsList)
  }

小测试:

val testJson =
    """
        [
                {
                    "name": "Invalid",
                    "ruleType": "validation_1",
                    "inputs": [ { "Name": "", "country": ["USA"] } ]

                },
                {
                    "name": "",
                    "ruleType": "validation_2",
                    "inputs": [ { "Name": "Test", "country": ["USA"] } ]

                },
                {
                    "name": "Valid",
                    "ruleType": "validation_1",
                    "inputs": []

                },
                {
                    "name": "Valid",
                    "ruleType": "validation_2",
                    "inputs": [ { "Name": "Test", "country": ["USA"] } ]

                },
                {
                    "name": "Valid",
                    "ruleType": "validation_1",
                    "inputs": [ { "Name": "Test", "country": ["France"] } ]

                }
        ]
    """.stripMargin
  val namedRuleTypeInputs: Seq[NameRuleTypeInputs] = readJsonString[Seq[NameRuleTypeInputs]](testJson)

  println(writeJsonString(namedRuleTypeInputs))

输出:

[ {
  "name" : "Valid",
  "ruleType" : "validation_2",
  "inputs" : [ {
    "Name" : "Test",
    "country" : [ "USA" ]
  } ]
}, {
  "name" : "Valid",
  "ruleType" : "validation_1",
  "inputs" : [ {
    "Name" : "Test",
    "country" : [ "France" ]
  } ]
} ]

有用参考:https://www.baeldung.com/jackson-serialize-field-custom-criteria