Play 2.0 中文资料 - Play JSON 库

Play 2.0 中文资料 - Play JSON 库

2013-01-13 — Yanbin

概述

推荐的处理  JSON 的方式是使用 Play 基于 JSON 库的类型类, 位置在 play.api.libs.json.

这个库是构建于 Jerkson, 之上的,它又是基于 Java 的超快的 JSON 库 Jackson 的 Scala 封闭。

Unmi 注:在 Play 1.x 所用的 JSON 库是 Gson,而 Play 2.0 后更换成了 Jackson。还得 Play 2.0 是基于 SBT 构建的,所以 Play 2.0 的所有的 jar 都是在 $PLAY_HOME/repository/local 目录中。

这样做的好处是无论是 Java 还是 Scala 的 Play 应用依赖了相同的底层库 (Jackson), 同时 Scala 用户可以享受到  Play’s JSON 所带来的额外的类型安全性.

play.api.libs.json 包含有七种 JSON 数据类型:

  • JsObject
  • JsNull
  • JsUndefined
  • JsBoolean
  • JsNumber
  • JsArray
  • JsString

上面的类型都继承自通用的 JSON 值类型, JsValue.

解析 Json 字符串

你可很轻易的解析任意的 JSON 字符串为一个 JsValue:

1
val json : JsValue  = Json.parse(jsonString)

遍历  Json 树

一旦你得到了一个 JsValue 你就可以遍历这个 Json 树. 这个 API 看起来像是  Scala 使用 NodeSeq 进行遍历 XML 文档一样的:

1
2
3
4
val json  = Json.parse(jsonString)
 
val maybeName  = (json \  "user" \ name).asOpt[String]
val emails  = (json \  "user" \\  "emails" ).map( _ .as[String])

 使用 \ 来导航是不会失败的. 当用 asOpt[T] 不存在值时会返回 None,所以这时候你需要自己来处理错误. 而用 as[T] 时,如果不存在值时就会报出异常.

Unmi 注:对于以上的代码我还需要用代码来加以说明:

01
02
03
04
05
06
07
08
09
10
       val jsonString  = "" " {" users ":{
                  " user 1 ":{" name ":" Unmi ", " email ":" fantasia @ sina.com "},
                  " user 2 ":{" name ":" Unmi.cc ", " email ":" unmi @ unmi.cc "}
            }
        } " ""
       val json  = Json.parse(jsonString)
       val maybeName  = (json \  "users" "user1" "name" ).asOpt[String]
       println(maybeName)
       val emails  = (json \  "users" \\  "email" ).map( _ .as[String])
       println(emails)

如果试图访问不存在的属性,如 (json \ "users"  \ "user1"  \ "userLaLa").asOpt[String] 时不会报错,得到的是 None 值。而换成 (json \ "users"  \ "user1"  \ "userLaLa").as[String] 就会有异常 [RuntimeException: String expected] 。

继续查看  println(json \ "users" \ "user1" \ "nameLaLa") 输出的是  null

上面的 Json 是 play.api.libs.json.Json,不是 play.mvc.Json, 也不是  play.libs.Json,play.libs.Json.parse() 返回的是  JsonNode,而 play.mvc.Json 没有 parse() 方法。

\ 和 \\ 是定义在  play.api.libs.json.Json 中的方法,\ 和  XPath 的 / 相似,直接的属性,\\ 和 XPath 的 // 相似,子孙属性

前面代码两个 println 语句的输出是:

Unmi
List(fantasia@sina.com, unmi@unmi.cc)

对 JSON 字符串的要求还是较严格的,没有 JavaScript 的 JSON 那么随意,属性名一定要加上双引号,单引号都不行。示例中的:

(json \ "user" \ name).asOpt[String]

name 代表的是前面定义的一个变量,如果是字面常量必须用双引号框上,否则报错:not found: value name。

转换 Scala 值为 Json

只要你有一个能够被转换为 Json 的 Scala 类型, 那就会非常容易由 Scala 值生成 Json. 例如我们来创建一个简单的 Json 对象:

1
val jsonNumber  = Json.toJson( 4 )

或者创建一个 json 数组:

1
val jsonArray  = Json.toJson(Seq( 1 2 3 4 ))

这儿把 Seq[Int] 转换成 Json 数组是没有问题的. 然而,假如 Seq 包含了不同的类型值是事情就变得复杂了:

1
val jsonArray  = Json.toJson(Seq( 1 "Bob" 3 4 ))

因为还没办法把 Seq[Any] 转换为 Json (Any 代表着任何类型,包括 Json 无法支持的类型,不是吗?)

Unmi 注: 报错为 No Json deserializer found for type Seq[Any]. Try to implement an implicit Writes or Format for this type.

一个简单的解决方案是按照 Seq[JsValue] 来处理:

1
2
3
val jsonArray  = Json.toJson(Seq(
   toJson( 1 ), toJson( "Bob" ), toJson( 3 ), toJson( 4 )
))

现在我们最后来看一个创建复杂 Json 对象的例子:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
val  jsonObject  = Json.toJson(
   Map(
     "users" -> Seq(
       toJson(
         Map(
           "name" -> toJson( "Bob" ),
           "age" -> toJson( 31 ),
           "email" -> toJson( "bob@gmail.com" )
         )
       ),
       toJson(
         Map(
           "name" -> toJson( "Kiki" ),
           "age" -> toJson( 25 ),
           "email" -> JsNull
         )
       )
     )
   )
)

上面产生的 Json 结果是:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
{
   "users" : [
     {
       "name" : "Bob" ,
       "age" : 31.0 ,
       "email" : "bob@gmail.com"
     },
     {
       "name" : "Kiki" ,
       "age" :   25.0 ,
       "email" : null
     }
   ]
}

序列化 Json

序列一个 JsValue 为它的 json 字符串表示格式很简单:

1
val jsonString : String  = Json.stringify(jsValue)

其他选择

虽然我们推荐用上面方案所描述的类型类(Unmi 注: typeclass 意思是?), 但是没什么能阻止用户有需求时去使用其他的 JSON 库.

例如, 这里一个小片段演示了使用基 Jerkson 库的 bundled, 反射机制,来编组原始的 scala 对象成 JSON 并进行传输:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
import com.codahale.jerkson.Json. _
 
val json  = generate(
   Map(
     "url" ->  "http://nytimes.com" ,
     "attributes" -> Map(
       "name" ->  "nytimes" ,
       "country" ->  "US" ,
       "id" ->  25
     ),
     "links" -> List(
       "http://link1" ,
       "http://link2"
     )
   )
)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将 Play Framework、MyBatis-Plus 和 Spring 集成起来,可以按照以下步骤进行操作: 1. 添加 MyBatis-Plus 和 Spring 依赖项到 Play Framework 项目中。 ``` libraryDependencies ++= Seq( "com.baomidou" %% "mybatis-plus" % "3.4.2", "org.springframework" % "spring-context" % "5.2.9.RELEASE" ) ``` 2. 创建一个 Spring Context 配置文件,例如 applicationContext.xml,并在文件中配置 MyBatis-Plus 和数据源。 ```xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mybatis-plus="http://mybatis.org/schema/mybatis-plus" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://mybatis.org/schema/mybatis-plus http://mybatis.org/schema/mybatis-plus/mybatis-plus.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- MyBatis-Plus 配置 --> <mybatis-plus:configuration> <mybatis-plus:global-config> <mybatis-plus:db-config id="dbConfig" /> </mybatis-plus:global-config> </mybatis-plus:configuration> <!-- 数据源配置 --> <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test" /> <property name="username" value="root" /> <property name="password" value="password" /> </bean> <!-- MyBatis-Plus SqlSessionFactory 配置 --> <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:mybatis-config.xml" /> <property name="mapperLocations" value="classpath*:mapper/**/*.xml" /> <property name="globalConfig" ref="dbConfig" /> </bean> <!-- MyBatis-Plus MapperScannerConfigurer 配置 --> <bean class="com.baomidou.mybatisplus.extension.spring.MybatisMapperScannerConfigurer"> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> </beans> ``` 3. 创建 MyBatis-Plus 配置文件,例如 mybatis-config.xml,并在文件中配置 MyBatis-Plus 的一些参数和插件。 ```xml <?xml version="1.0" encoding="UTF-8"?> <configuration> <settings> <setting name="cacheEnabled" value="true" /> <setting name="lazyLoadingEnabled" value="true" /> <setting name="aggressiveLazyLoading" value="false" /> </settings> <plugins> <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor" /> </plugins> </configuration> ``` 4. 在 Play Framework 中,可以使用 SpringApplicationBuilder 创建 Spring Context,并将其与应用程序一起启动。 ```java package controllers; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import play.mvc.Controller; import play.mvc.Result; public class HomeController extends Controller { public Result index() { // 使用 SpringApplicationBuilder 创建 Spring Context ApplicationContext context = new AnnotationConfigApplicationContext(); context.registerShutdownHook(); // 或者使用 ClassPathXmlApplicationContext 加载 applicationContext.xml 文件 // ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // 获取 MyBatis-Plus Mapper 接口实例 UserMapper userMapper = context.getBean(UserMapper.class); // 调用接口方法,执行 SQL 操作 User user = userMapper.selectById(1L); return ok(user.toString()); } } ``` 这样,就可以在 Play Framework 中集成 MyBatis-Plus 和 Spring 了。当然,还需要根据项目实际情况进行进一步的配置和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值