zoukankan      html  css  js  c++  java
  • Scala微服务架构 三

    四 Controller层

    之前我们已经把基层架构搭建好了,那么要如何使用呢?
    首先看看我的Controller层代码

    @Singleton
    class BMAuthController @Inject()(implicit cc: ControllerComponents, actorSystem: ActorSystem)
                extends AbstractController(cc) with Circe with CirceJsonapiSupport {
    
        val entry = PlayEntry()
    
        def parseJson(jsonString: String) : Json = io.circe.parser.parse(jsonString).right.get
        def decodeJson[T](json: Json)(implicit d: io.circe.Decoder[T]) : T = json.as[T].right.get
    
        def login = Action(circe.json[RootObject]) { implicit request =>
                request
            import model.request.requestsJsonApiOpt.requestsJsonapiRootObjectReader._
            val tt = fromJsonapi(request.body)
            val reVal = entry.commonExcution(
                    SequenceSteps(testStep(tt.reqs.head) :: Nil, None))
    
            val ctest = company("12", "alfred")
            val ctestj = asJsonApi(ctest)
            println(ctestj)
    
            val result = asJsonApiResult(reVal.asInstanceOf[userdetailresult])
            Ok(result.asJson)
        }
    }
    

    4.1 Controller 的声明

    4.1.1 @Inject() 注解

    @Inject()(implicit cc: ControllerComponents, actorSystem: ActorSystem)
    

    首先这个@Inject会查询Play的System环境,并将查到的单例实例注入到参数中.

    4.1.2 AbstractController 特质

    官网解释

    • AbstractController: an abstract class extending BaseController with a ControllerComponents constructor parameter that can be injected using constructor injection.

    也就是说,这就是BaseController的抽象子类,但是要带有一个ControllerComponents作为构造函数.

    4.1.3 Circe 特质

    circe是一个Scala的Json解析库.并且目前已经支持Play.
    Play的使用方式很简单,首先引入项目:

    libraryDependencies += "com.dripower" %% "play-circe" % "2609.1"
    

    然后继承play.api.libs.circe.Circe特质

    使用起来也很简单,上面代码的
    circe.json[RootObject]
    部分就是在使用Circe解析JsonApi的Root部分.

    4.1.4 CirceJsonapiSupport 特质

    对JsonApi协议的支持,里面主要就是两个隐式,代码如下:

    trait CirceJsonapiSupport extends CirceJsonapiEncoders with CirceJsonapiDecoders {
        implicit val circeJsonapiMarshaller = Marshaller.delegate[RootObject, String](
            `application/vnd.api+json`,
            `application/json`,
            ContentTypes.`application/json`
        )(_.asJson.noSpaces)
        implicit val circeJsonapiUnmarshaller = Unmarshaller.delegate[String, RootObject](
            `application/vnd.api+json`,
            `application/json`
        )(decode[RootObject](_).right.get)
    }
    
    object CirceJsonapiSupport extends CirceJsonapiSupport
    

    4.2 login 代码解析

    对不起,各位,暂时没写!!! ,有兴趣的可以私信我,后期我会补上.

    ※. 本期语法糖

    ※.1 Scala的构造函数

    学自https://www.w3cschool.cn/scala/scala-constructors.html

    今天要说的当然不是大家熟知的构造函数,而是以前我们可能忽略的细节.

    class User1(var id: String, var name: String)
    
    class User2(val id: String, val name: String)
    
    class User3(private var id: String,private  var name: String)
    
    class User4(id: String, name: String)
    

    上面代码定义了四个User类,每个类都有两个参数idname,当然,他们构造函数的区别也很明显.那么这几种不同的定义方式,有什么区别呢?

    • User1,定义了可变构造参数,同时编译器会自动生成setter和getter方法,但因为是默认修饰符,所以外部可以直接访问user1.id,或者赋值user1.id("001")
    • User2,因为定义的构造参数是不可变的,所以只会生成getter方法,不会有setter方法,也是默认修饰符,所以外部只可以访问user2.id,无法赋值
    • User3,和User1很像,但是修饰符改为private,所以即便是var的构造参数,也不会生成getter方法和setter方法
    • User4,我们最常用的写法,其实就是private[this] val,也就是说对于自己和伴生类而言是可见的

    应杨总要求,我们打印上面四个User类的编译信息

    def tree1 = reify { class User1(var id: String, var name: String) }.tree
    def tree2 = reify { class User2(val id: String, val name: String) }.tree
    def tree3 = reify { class User3(private var id: String,private  var name: String) }.tree
    def tree4 = reify { class User4(id: String, name: String) }.tree
    

    然后分别打印上面的四个树,输出结果如下:

    tree1:

    {
      class User1 extends AnyRef {
        <paramaccessor> var id: Predef.String = _;
        <paramaccessor> var name: Predef.String = _;
        def <init>(id: Predef.String, name: Predef.String) = {
          super.<init>();
          ()
        }
      };
      ()
    }
    

    tree2:

    {
      class User2 extends AnyRef {
        <paramaccessor> val id: Predef.String = _;
        <paramaccessor> val name: Predef.String = _;
        def <init>(id: Predef.String, name: Predef.String) = {
          super.<init>();
          ()
        }
      };
      ()
    }
    

    tree3:

    {
      class User3 extends AnyRef {
        <paramaccessor> private var id: Predef.String = _;
        <paramaccessor> private var name: Predef.String = _;
        def <init>(id: Predef.String, name: Predef.String) = {
          super.<init>();
          ()
        }
      };
      ()
    }
    

    tree4:

    {
      class User3 extends AnyRef {
        <paramaccessor> private[this] val id: Predef.String = _;
        <paramaccessor> private[this] val name: Predef.String = _;
        def <init>(id: Predef.String, name: Predef.String) = {
          super.<init>();
          ()
        }
      };
      ()
    }
    
  • 相关阅读:
    spark学习
    推荐系统-摘录
    matplotlib安装问题解决
    秒杀系统分析
    大数据常用启动命令
    推荐系统简介
    java面试-JVM内存结构
    推荐算法-基于内容的推荐
    推荐算法-基于模型的协同过滤
    监督学习之模型评估与选择
  • 原文地址:https://www.cnblogs.com/clockq/p/9256235.html
Copyright © 2011-2022 走看看