Использование дженериков 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 для парсинга. Любая помощь приветствуется.


person Achilleus    schedule 26.03.2019    source источник


Ответы (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, если поля нет.

person Tim    schedule 26.03.2019
comment
Это сработало! Спасибо. Кстати, есть ли способ справиться с обнулением случая, когда у нас есть неверные данные? Скажем, бросить исключение или что-то в этом роде? - person Achilleus; 26.03.2019
comment
@Achilleus Если у вас неверные данные, extract выдаст исключение. Вы можете позволить вызывающей стороне справиться с этим или обернуть вызов extract в Try и вернуть Try[T], что, возможно, более стандартно для Scala. - person Tim; 27.03.2019
comment
На самом деле, это не вызовет исключения в ситуации, когда мы имеем дело с вложенным json, а объект в нем, скажем, имеет неправильно написанное поле. Он просто обнуляет этот объект и движется дальше. Мне было интересно, можем ли мы каким-то образом указать, чтобы он терпел неудачу или выдавал исключение, а не обнулял его. - person Achilleus; 27.03.2019
comment
Можете ли вы привести пример этого? Если я переименую одно из полей из строки JSON, я получу MappingException: No usable value for <fieldname>. - person Tim; 27.03.2019
comment
На самом деле, это исключение для классов case. Но я использую специальный класс записей Avro. Это класс case, который расширяет org.apache.avro.specific.SpecificRecordBase. Но каким-то образом в этом случае он сериализуется до нуля. - person Achilleus; 27.03.2019
comment
Разместил здесь еще один вопрос класс"> stackoverflow.com/questions/55381927/ - person Achilleus; 27.03.2019