#scala #generics #json4s
#scala #обобщения #json4s
Вопрос:
Я не уверен, достижимо ли это, и у меня есть очень базовое понимание того, как дженерики работают в scala. Но мне было интересно, возможно ли это. Допустим, у меня есть метод:
case class Person(id:String,name:String)
case class Student(id:String,name:String, class:String)
def convertToJson[A](fileName:String):{
//read file
parse[A]
}
Возможно ли написать этот универсальный метод, который будет анализировать json на основе типа класса, который я отправляю при вызове метода convertToJson?
Что-то вроде:
convertToJson[Student](fileName)
convertToJson[Person](fileName)
Кстати, приведенный выше код дает мне :
Отсутствует доступный манифест для A. ошибка.
Использование json4s для синтаксического анализа. Любая помощь приветствуется.
Ответ №1:
Это преобразует строку JSON в case class
import org.json4s._
import org.json4s.jackson.JsonMethods._
def convertToJson[T](json: String)(implicit fmt: Formats = DefaultFormats, mf: Manifest[T]): T =
Extraction.extract(parse(json))
Как только это определено, вы можете проанализировать соответствующие строки до требуемого типа:
case class Person(id: String, name: String)
case class Student(id: String, name: String, `class`: String)
val person = convertToJson[Person]("""{"name":"Jane","id":45}""")
val student = convertToJson[Student]("""{"name":"John","id":63, "class": "101"}""")
Обратите внимание, что при этом будут игнорироваться данные JSON, которые не соответствуют полям в case class
. Если поле в JSON является необязательным, сделайте его Option
в case class
, и вы получите, None
если поля там нет.
Комментарии:
1. Это сработало! Спасибо. Кстати, есть ли способ устранить случай, когда у нас неверные данные? Скажем, создать исключение или что-то в этомроде?
2. @Achilleus Если у вас неверные данные,
extract
выдаст исключение. Вы можете позволить вызывающей стороне обработать это или обернутьextract
вызов вTry
и вернутьTry[T]
, что, возможно, более стандартно в Scala.3. На самом деле, это не вызовет исключения в ситуации, когда мы имеем дело с вложенным json и объект в нем, скажем, имеет поле, написанное неправильно. Он просто обнулит этот объект и продолжит работу. Мне было интересно, можем ли мы каким-то образом указать, что это сбой, или выдать исключение вместо того, чтобы обнулять его.
4. Можете ли вы привести пример этого? Если я переименую одно из полей из строки JSON, я получу
MappingException: No usable value for <fieldname>
.5. На самом деле, это создает исключение для классов case. Но я использую класс регистра записей, специфичный для Avro. Это класс case, который расширяет org.apache.avro.specific.SpecificRecordBase. Но каким-то образом в этом случае он сериализуется до null.