四 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類,每個類都有兩個參數
id
和
name
,當然,他們構造函數的差別也很明顯.那麼這幾種不同的定義方式,有什麼差別呢?
- 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>();
()
}
};
()
}