hive将list转成string_Play JSON类库将List[(String, String)]转换成Json字符串

最近在一个项目中使用到Writes即可;而将Json字符串转换成一个类直接写个Reads即可。所有的操作只需要引入play.api.libs.json._即可。

但昨天在将List[(String, String)]类型的对象转换成Json遇到了一点麻烦。如果是List[String]我们可以这么写: val list = List("www", "iteblog", "com")

println(Json.toJson(list).toString())

["www","iteblog","com"]

可以直接转换成一个Json数组,如果List[(String, String)]也那么写行不行呢? val info = List(("web_site", ""), ("weixin", "iteblog_hadoop"))

println(Json.toJson(info))

上面代码还没运行,在编译的时候就出现问题了(这个很不错,错误出现越早越好!): Error:(15, 24) No Json serializer found for type List[(String, String)]. Try to implement an implicit Writes or Format for this type.

println(Json.toJson(info))

^

上面的错误大概的意思就是Play Json框架找不到如何将List[(String, String)]类型的对象序列化成Json,需要我们指定一个Writes或者Format告诉Play Json框架如何将它序列化成Json。我们先来看看Json.toJson方法的原型: def toJson[T](o: T)(implicit tjs: Writes[T]): JsValue

这个方法其实接受两个参数,其中Writes是通过隐式传入的。有些人可能会问:那为什么上面将List[String]转换成Json却不要写Writes呢?原因很简单,因为对于这些基本的类型,Play Json框架已经内置了这些Writes: /**

* Serializer for Int types.

*/

implicit object IntWrites extends Writes[Int] {

def writes(o: Int) = JsNumber(o)

}

/**

* Serializer for Short types.

*/

implicit object ShortWrites extends Writes[Short] {

def writes(o: Short) = JsNumber(o)

}

/**

* Serializer for Long types.

*/

implicit object LongWrites extends Writes[Long] {

def writes(o: Long) = JsNumber(o)

}

/**

* Serializer for Float types.

*/

implicit object FloatWrites extends Writes[Float] {

def writes(o: Float) = JsNumber(o)

}

/**

* Serializer for Double types.

*/

implicit object DoubleWrites extends Writes[Double] {

def writes(o: Double) = JsNumber(o)

}

/**

* Serializer for BigDecimal types.

*/

implicit object BigDecimalWrites extends Writes[BigDecimal] {

def writes(o: BigDecimal) = JsNumber(o)

}

/**

* Serializer for Boolean types.

*/

implicit object BooleanWrites extends Writes[Boolean] {

def writes(o: Boolean) = JsBoolean(o)

}

/**

* Serializer for String types.

*/

implicit object StringWrites extends Writes[String] {

def writes(o: String) = JsString(o)

}

/**

* Serializer for Jackson JsonNode

*/

implicit object JsonNodeWrites extends Writes[JsonNode] {

def writes(o: JsonNode): JsValue = JacksonJson.jsonNodeToJsValue(o)

}

/**

* Serializer for Array[T] types.

*/

implicit def arrayWrites[T: ClassTag](implicit fmt: Writes[T]): Writes[Array[T]] = new Writes[Array[T]] {

def writes(ts: Array[T]) = JsArray((ts.map(t => toJson(t)(fmt))).toList)

}

可以从上面看出,基本类型转换已经内置了,所以我们根本不需要自己定义Writes。但是List[(String,String)]并不是内置的类型,所以我们需要自己定义一个Writes。根据上面内置的Writes启发,我们可以这么定义一个(String,String)类型的Writes如下: implicit object iteblogWrites extends Writes[(String, String)] {

def writes(o: (String, String)) = Json.obj(o._1 -> o._2)

}

然后我们再将上面List[(String,String)]对象转换成Json: val info = List(("web_site", ""), ("weixin", "iteblog_hadoop"))

println(Json.toJson(info))

[{"web_site":""},{"weixin":"iteblog_hadoop"}]

可以看出,经过自定义iteblogWrites已经告诉Play Json框架如何系列化List[(String,String)]类型的对象了!如果List[(String,String)]定义在一个case class中又该如何弄,如下: case class IteblogInfo(blog: String, blogInfo: List[(String, String)])

val iteblogInfo = IteblogInfo("iteblog", info)

println(Json.toJson(iteblogInfo))

运行上面代码也会出错,我们需要告诉Play Json框架如何系列化IteblogInfo类型成Json,如下: implicit val IteblogInfoWrites: Writes[IteblogInfo] = (

(JsPath \ "blog").write[String] and

(JsPath \ "blogInfo").write[List[(String,String)]]

) (unlift(IteblogInfo.unapply))

这样运行上面的代码得到如下的结果: {"blog":"iteblog","blogInfo":[{"web_site":""},{"weixin":"iteblog_hadoop"}]}

当然,定义Writes的方法有很多,上面的例子我们还可以这么定义一个Writes,如下: implicit val IteblogInfoWrites: Writes[IteblogInfo] = (

(JsPath \ "iteblog").write[String] and

(JsPath \ "blogInfo").write[JsArray]

.contramap[List[(String, String)]](list => JsArray(list.map(g => Json.obj(g._1 -> g._2))))

) (unlift(IteblogInfo.unapply))

这样也可以得到正确的结果。在使用Play Json框架发现这个框架真是太方便了,太强大了。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值