Как обслуживать веб-сервис Lift/Scala Json из класса mapper persistent
Хорошо, во-первых, я новичок в размещении вопросов здесь, так что будьте спокойны со мной.
Я чувствую, как будто я поразил межплетение, чтобы понять это, и я уверен, что должен быть медленным, потому что я просто не могу понять это правильно - я знаю, что это должно быть просто.
У меня есть класс:
class Produce extends LongKeyedMapper[Produce] with IdPK {
def getSingleton = Produce
object producetype extends MappedString(this,20)
object name extends MappedString(this,20)
object description extends MappedString(this,255)
}
У объекта есть несколько вспомогательных методов и некоторые другие вещи, которые я собрал вместе, чтобы попытаться заставить это работать:
object Produce extends Produce with LongKeyedMetaMapper[Produce] {
private implicit val formats = net.liftweb.json.DefaultFormats
override def fieldOrder = List(producetype, name, description)
def search(str: String): List[Produce] = {
val strLC = str.toLowerCase()
Produce.findAll(By(Produce.producetype, strLC))
}
implicit def toJson(item: Produce): JValue = Extraction.decompose(item)
implicit def toJson(items: List[Produce]): JValue = Extraction.decompose(items)
}
моя служба отдыха выполняет основные вещи и соответствует этому:
serve( "api" / "item" prefix {
case "search" :: q JsonGet _ =>
(for {
searchString <- q ::: S.params("q")
item <- Produce.search(searchString)
} yield item): JValue
})
Так что, к моему удовольствию, это сработало, я получил его соответствие... и возвращая Json, проблема в следующем: допустим, у меня есть 3 строки в БД с производным типом: a, если я вызываю сервис с 'a', он возвращает:
[{
},{
},{
}]
Итак, он возвращается, он просто не сериализует какие-либо данные... Я пытался перегрузить неприменимые методы и пытаться выяснить, могут ли классы случаев помочь мне - но это не щелкает моим слабым умом. Любая помощь?
2 ответа
Я думаю, что вам может понадобиться добавить обертку. Кажется, картостроители не могут справиться с этим без небольшой помощи, хотя это имеет смысл иметь в Lift - со всеми другими замечательными функциями REST и Json.
Что-то вроде следующего, а затем поменяйте местами между Wrapper и Mapper в ваших вызовах REST:
case class ProduceWrapper(producetype: String, name: String, description: String)
object ProduceWrapper {
private implicit val formats = net.liftweb.json.DefaultFormats
def apply(in: JValue): Box[ProduceWrapper] = Helpers.tryo{in.extract[ProduceWrapper]}
def unapply(in: JValue): Option[ProduceWrapper] = apply(in)
def unapply(in: Any): Option[(String, String, String)] = {
in match {
case i: ProduceWrapper => Some((i.producetype, i.name, i.description))
case _ => None
}
}
implicit def toJson(item: ProduceWrapper): JValue = Extraction.decompose(item)
implicit def toJson(items: List[ProduceWrapper]): JValue = Extraction.decompose(items)
}
В классе REST:
serve( "api" / "produce" prefix {
case Nil JsonPut ProduceWrapper(item) -> _ => Produce.add(item): JValue
}
А затем в классе Produce:
def add(item: ProduceWrapper): ProduceWrapper = {
Produce.create.name(item.name).description(item.description).save
item
}
Я считаю, что поддержка JSON в Lift требует использования case-классов и, следовательно, не работает с объектами Mapped.
Вы можете попробовать создать класс case, созданный из полей Produce в методах toJson.
Я также нашел это, которое выглядит полезным: http://scala-programming-language.1934581.n4.nabble.com/Mapper-lt-gt-JObject-bridge-td1981293.html