欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    【CSDN 編者按】大家都知道Web和API服務(wù)器在互聯(lián)網(wǎng)中的重要性,在計(jì)算機(jī)網(wǎng)絡(luò)方面提供了最基本的界面。本文主要介紹了怎樣利用Scala實(shí)現(xiàn)實(shí)時(shí)聊天網(wǎng)站和API服務(wù)器,通過(guò)本篇文章,你定將受益匪淺。

    作者 | Haoyi譯者 |彎月,責(zé)編 | 劉靜出品 | CSDN(ID:)

    以下為譯文:

    Web和API服務(wù)器是互聯(lián)網(wǎng)系統(tǒng)的骨干,它們?yōu)橛?jì)算機(jī)通過(guò)網(wǎng)絡(luò)交互提供了基本的界面,特別是在不同公司和組織之間。這篇指南將向你介紹如何利用Scala簡(jiǎn)單的HTTP服務(wù)器,來(lái)提供Web內(nèi)容和API。本文還會(huì)介紹一個(gè)完整的例子,告訴你如何構(gòu)建簡(jiǎn)單的實(shí)時(shí)聊天網(wǎng)站,同時(shí)支持HTML網(wǎng)頁(yè)和JSON API端點(diǎn)。

    這篇文及章的目的是介紹怎樣用Scala實(shí)現(xiàn)簡(jiǎn)單的HTTP服務(wù)器,從而提供網(wǎng)頁(yè)服務(wù),以響應(yīng)API請(qǐng)求。我們會(huì)建立一個(gè)簡(jiǎn)單的聊天網(wǎng)站,可以讓用戶發(fā)表聊天信息,其他訪問(wèn)網(wǎng)站的用戶都可以看見(jiàn)這些信息。為簡(jiǎn)單起見(jiàn),我們將忽略認(rèn)證、性能、用戶掛歷、數(shù)據(jù)庫(kù)持久存儲(chǔ)等問(wèn)題。但是,這篇文章應(yīng)該足夠你開(kāi)始用Scala構(gòu)建網(wǎng)站和API服務(wù)器了,并為你學(xué)習(xí)并構(gòu)建更多產(chǎn)品級(jí)項(xiàng)目打下基礎(chǔ)。

    我們將使用Cask web框架:

    Cask是一個(gè)Scala的HTTP為框架,可以用來(lái)架設(shè)簡(jiǎn)單的網(wǎng)站并迅速運(yùn)行。

    開(kāi)始

    要開(kāi)始使用Cask,只需下載并解壓示例程序:

    $?curl?-L?https://github.com/lihaoyi/cask/releases/download/0.3.0/minimalApplication-0.3.0.zip?>?cask.zip

    $?unzip?cask.zip

    $?cd?minimalApplication-0.3.0

    運(yùn)行find來(lái)看看有哪些文件:

    $?find?.?-type?f
    ./build.sc
    ./app/test/src/ExampleTests.scala
    ./app/src/MinimalApplication.scala
    ./mill

    我們感興趣的大部分代碼都位于app/src/.scala中。

    package?app
    object?MinimalApplication?extends?cask.MainRoutes{
    ??@cask.get("/")
    ??def?hello()?=?{
    ????"Hello?World!"
    ??}

    ??@cask.post("/do-thing")
    ??def?doThing(request:?cask.Request)?=?{
    ????new?String(request.readAllBytes()).reverse
    ??}

    ??initialize()
    }

    用build.sc進(jìn)行構(gòu)建:

    html提交表單到服務(wù)器_html select 選中提交表單_表單提交 html

    import?mill._,?scalalib._

    object?app?extends?ScalaModule{
    ??def?scalaVersion?=?"2.13.0"
    ??def?ivyDeps?=?Agg(
    ????ivy"com.lihaoyi::cask:0.3.0"
    ??)

    ??object?test?extends?Tests{
    ????def?testFrameworks?=?Seq("utest.runner.Framework")

    ????def?ivyDeps?=?Agg(
    ??????ivy"com.lihaoyi::utest::0.7.1",
    ??????ivy"com.lihaoyi::requests::0.2.0",
    ????)

    ??}
    }

    如果你使用,那么可以運(yùn)行如下命令來(lái)設(shè)置項(xiàng)目配置:

    $?./mill?mill.scalalib.GenIdea/idea

    現(xiàn)在你可以在中打開(kāi)-0.3.0/目錄html提交表單到服務(wù)器,查看項(xiàng)目的目錄,也可以進(jìn)行編輯。

    可以利用Mill構(gòu)建工具運(yùn)行該程序,只需執(zhí)行./mill:

    $?./mill?-w?app.runBackground

    該命令將在后臺(tái)運(yùn)行Cask Web服務(wù)器,同時(shí)監(jiān)視文件系統(tǒng),如果文件發(fā)生了變化,則重啟服務(wù)器。然后我們可以使用瀏覽器瀏覽服務(wù)器,默認(rèn)網(wǎng)址是:8080:

    在/do-thing上還有個(gè)POST端點(diǎn),可以在另一個(gè)終端上使用curl來(lái)訪問(wèn):

    $?curl?-X?POST?--data?hello?http://localhost:8080/do-thing
    olleh

    可見(jiàn),它接受數(shù)據(jù)hello,然后將反轉(zhuǎn)的字符串返回給客戶端。

    然后可以運(yùn)行app/test/src/.scala中的自動(dòng)化測(cè)試:

    $?./mill?clean?app.runBackground?#?stop?the?webserver?running?in?the?background

    $?./mill?app.test
    [50/56]?app.test.compile
    [info]?Compiling?1?Scala?source?to?/Users/lihaoyi/test/minimalApplication-0.3.0/out/app/test/compile/dest/classes?...
    [info]?Done?compiling.
    [56/56]?app.test.test
    --------------------------------?Running?Tests?--------------------------------
    +?app.ExampleTests.MinimalApplication?629ms

    現(xiàn)在基本的東西已經(jīng)運(yùn)行起來(lái)了,我們來(lái)重新運(yùn)行Web服務(wù)器:

    $?./mill?-w?app.runBackground

    html select 選中提交表單_html提交表單到服務(wù)器_表單提交 html

    然后開(kāi)始實(shí)現(xiàn)我們的聊天網(wǎng)站!

    提供HTML服務(wù)

    第一件事就是將純文本的"Hello, World!"轉(zhuǎn)換成HTML網(wǎng)頁(yè)。最簡(jiǎn)單的方式就是利用這個(gè)HTML生成庫(kù)。要在項(xiàng)目中使用,只需將其作為依賴(lài)項(xiàng)加入到build.sc文件即可:

    ??def?ivyDeps?=?Agg(
    +????ivy"com.lihaoyi::scalatags:0.7.0",???
    ?????ivy"com.lihaoyi::cask:0.3.0"
    ???)

    如果使用,那么還需要重新運(yùn)行./mill mill../idea命令,來(lái)發(fā)現(xiàn)依賴(lài)項(xiàng)的變動(dòng),然后重新運(yùn)行./mill -w app.讓W(xué)eb服務(wù)器重新監(jiān)聽(tīng)改動(dòng)。

    然后,我們可以在.scala中導(dǎo)入:

    package?app
    +import?scalatags.Text.all._
    ?object?MinimalApplication?extends?cask.MainRoutes{

    然后用一段最簡(jiǎn)單的 HTML模板替換"Hello, World!"。

    ?def?hello()?=?{
    -????"Hello?World!"
    +????html(
    +??????head(),
    +??????body(
    +????????h1("Hello!"),
    +????????p("World")
    +??????)
    +????).render
    ???}

    我們應(yīng)該可以看到./mill -w app.命令重新編譯了代碼并重啟了服務(wù)器。然后刷新網(wǎng)頁(yè)額,就會(huì)看到純文本已經(jīng)被替換成HTML頁(yè)面了。

    為了讓頁(yè)面更好看一些,我們使用這個(gè)CSS框架。只需按照它的指南,使用link標(biāo)簽引入:

    ?????head(
    +????????link(
    +??????????rel?:=?"stylesheet",?
    +??????????href?:=?"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
    +????????)
    ???????),

    html select 選中提交表單_html提交表單到服務(wù)器_表單提交 html

    ??body(
    -????????h1("Hello!"),
    -????????p("World")
    +????????div(cls?:=?"container")(
    +??????????h1("Hello!"),
    +??????????p("World")
    +????????)
    ???????)

    現(xiàn)在字體不太一樣了:

    雖然還不是最漂亮的網(wǎng)站,但現(xiàn)在已經(jīng)足夠了。

    在本節(jié)的末尾,我們修改一下的HTML模板,加上硬編碼的聊天文本和假的輸入框,讓它看起來(lái)更像一個(gè)聊天應(yīng)用程序。

    ?body(
    ?????????div(cls?:=?"container")(
    -??????????h1("Hello!"),
    -??????????p("World")
    +??????????h1("Scala?Chat!"),
    +??????????hr,
    +??????????div(
    +????????????p(b("alice"),?"?",?"Hello?World!"),
    +????????????p(b("bob"),?"?",?"I?am?cow,?hear?me?moo"),
    +????????????p(b("charlie"),?"?",?"I?weigh?twice?as?much?as?you")
    +??????????),
    +??????????hr,
    +??????????div(
    +????????????input(`type`?:=?"text",?placeholder?:=?"User?name",?width?:=?"20%"),
    +????????????input(`type`?:=?"text",?placeholder?:=?"Please?write?a?message!",?width?:=?"80%")
    +??????????)
    ?????????)
    ???????)

    現(xiàn)在我們有了一個(gè)簡(jiǎn)單的靜態(tài)網(wǎng)站,其利用Cask web框架和 HTML庫(kù)提供HTML網(wǎng)頁(yè)服務(wù)。現(xiàn)在的服務(wù)器代碼如下所示:

    package?app
    import?scalatags.Text.all._
    object?MinimalApplication?extends?cask.MainRoutes{
    ??@cask.get("/")
    ??def?hello()?=?{
    ????html(
    ??????head(
    ????????link(
    ??????????rel?:=?"stylesheet",
    ??????????href?:=?"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
    ????????)
    ??????),
    ??????body(
    ????????div(cls?:=?"container")(
    ??????????h1("Scala?Chat!"),
    ??????????hr,
    ??????????div(
    ????????????p(b("alice"),?"?",?"Hello?World!"),
    ????????????p(b("bob"),?"?",?"I?am?cow,?hear?me?moo"),
    ????????????p(b("charlie"),?"?",?"I?weigh?twice?as?much?as?you")
    ??????????),
    ??????????hr,
    ??????????div(
    ????????????input(`type`?:=?"text",?placeholder?:=?"User?name",?width?:=?"20%"),
    ????????????input(`type`?:=?"text",?placeholder?:=?"Please?write?a?message!",?width?:=?"80%")
    ??????????)
    ????????)
    ??????)
    ????).render
    ??}

    ??initialize()
    }

    接下來(lái),我們來(lái)看看怎樣讓它支持交互!

    表單和數(shù)據(jù)

    為網(wǎng)站添加交互的第一次嘗試是使用HTML表單。首先我們要?jiǎng)h掉硬編碼的消息列表,轉(zhuǎn)而根據(jù)數(shù)據(jù)來(lái)輸出HTML網(wǎng)頁(yè):

    ?object?MinimalApplication?extends?cask.MainRoutes{
    +??var?messages?=?Vector(
    +????("alice",?"Hello?World!"),
    +????("bob",?"I?am?cow,?hear?me?moo"),
    +????("charlie",?"I?weigh?twice?as?much?as?you"),
    +??)
    ??@cask.get("/")

    ?div(
    -????????????p(b("alice"),?"?",?"Hello?World!"),
    -????????????p(b("bob"),?"?",?"I?am?cow,?hear?me?moo"),
    -????????????p(b("charlie"),?"?",?"I?weight?twice?as?much?as?you")
    +????????????for((name,?msg)?<-?messages)
    +????????????yield?p(b(name),?"?",?msg)
    ???????????),

    這里我們簡(jiǎn)單地使用了內(nèi)存上的存儲(chǔ)。關(guān)于如何將消息持久存儲(chǔ)到數(shù)據(jù)庫(kù)中,我將在以后的文章中介紹。

    html提交表單到服務(wù)器_表單提交 html_html select 選中提交表單

    接下來(lái),我們需要讓頁(yè)面底部的兩個(gè)input支持交互。為實(shí)現(xiàn)這一點(diǎn),我們需要將它們包裹在form元素中:

    ????hr,
    -??????????div(
    -????????????input(`type`?:=?"text",?placeholder?:=?"User?name",?width?:=?"20%"),
    -????????????input(`type`?:=?"text",?placeholder?:=?"Please?write?a?message!",?width?:=?"80%")
    +??????????form(action?:=?"/",?method?:=?"post")(
    +????????????input(`type`?:=?"text",?name?:=?"name",?placeholder?:=?"User?name",?width?:=?"20%"),
    +????????????input(`type`?:=?"text",?name?:=?"msg",?placeholder?:=?"Please?write?a?message!",?width?:=?"60%"),
    +????????????input(`type`?:=?"submit",?width?:=?"20%")
    ??????????)

    這樣我們就有了一個(gè)可以交互的表單,外觀跟之前的差不多。但是,提交表單會(huì)導(dǎo)致Error 404: Not Found錯(cuò)誤。這是因?yàn)槲覀冞€沒(méi)有將表單與服務(wù)器連接起來(lái),來(lái)處理表單提交并獲取新的聊天信息。我們可以這樣做:

    ???-??)
    +
    +??@cask.postForm("/")
    +??def?postHello(name:?String,?msg:?String)?=?{
    +????messages?=?messages?:+?(name?->?msg)
    +????hello()
    +??}
    +
    ???@cask.get("/")

    @cast.定義為根URL(即 / )添加了另一個(gè)處理函數(shù),但該處理函數(shù)處理POST請(qǐng)求,而不處理GET請(qǐng)求。Cask文檔()中還有關(guān)于@cask.*注釋的其他例子,你可以利用它們來(lái)定義處理函數(shù)。

    驗(yàn)證

    現(xiàn)在,用戶能夠以任何名字提交任何評(píng)論。但是,并非所有的評(píng)論和名字都是有效的:最低限度,我們希望保證評(píng)論和名字字段非空,同時(shí)我們還需要限制最大長(zhǎng)度。

    實(shí)現(xiàn)這一點(diǎn)很簡(jiǎn)單:

    ??@cask.postForm("/")
    ???def?postHello(name:?String,?msg:?String)?=?{
    -????messages?=?messages?:+?(name?->?msg)
    +????if?(name?!=?""?&&?name.length?10?&&?msg?!=?""?&&?msg.length?160){
    +??????messages?=?messages?:+?(name?->?msg)
    +????}
    ?????hello()
    ???}

    這樣就可以阻止用戶輸入非法的name和msg,但出現(xiàn)了另一個(gè)問(wèn)題:用戶輸入了非法的名字或信息并提交,那么這些信息就會(huì)消失,而且不會(huì)為錯(cuò)誤產(chǎn)生任何反饋。解決方法是,給hello()頁(yè)面渲染一個(gè)可選的錯(cuò)誤信息,用它來(lái)告訴用戶出現(xiàn)了什么問(wèn)題:

    ?@cask.postForm("/")
    ???def?postHello(name:?String,?msg:?String)?=?{
    -????if?(name?!=?""?&&?name.length?10?&&?msg?!=?""?&&?msg.length?160){
    -??????messages?=?messages?:+?(name?->?msg)
    -????}
    -?????hello()
    +????if?(name?==?"")?hello(Some("Name?cannot?be?empty"))
    +????else?if?(name.length?>=?10)?hello(Some("Name?cannot?be?longer?than?10?characters"))
    +????else?if?(msg?==?"")?hello(Some("Message?cannot?be?empty"))
    +????else?if?(msg.length?>=?160)?hello(Some("Message?cannot?be?longer?than?160?characters"))
    +????else?{
    +??????messages?=?messages?:+?(name?->?msg)
    +??????hello()
    +????}
    ???}

    ??@cask.get("/")
    -??def?hello()?=?{
    +??def?hello(errorOpt:?Option[String]?=?None)?=?{
    ?????html(

    ??hr,
    +??????????for(error?<-?errorOpt)?
    +??????????yield?i(color.red)(error),
    ???????????form(action?:=?"/",?method?:=?"post")(

    html select 選中提交表單_html提交表單到服務(wù)器_表單提交 html

    現(xiàn)在,當(dāng)名字或信息非法時(shí),就可以正確地顯示出錯(cuò)誤信息了。

    下一次提交時(shí)錯(cuò)誤信息就會(huì)消失。

    記住名字和消息

    現(xiàn)在比較煩人的是,每次向聊天室中輸入消息時(shí)html提交表單到服務(wù)器,都要重新輸入用戶名。此外,如果用戶名或信息非法,那消息就會(huì)被清除,只能重新輸入并提交。可以讓hello頁(yè)面處理函數(shù)來(lái)填充這些字段,這樣就可以解決:

    ?@cask.get("/")
    -??def?hello(errorOpt:?Option[String]?=?None)?=?{
    +??def?hello(errorOpt:?Option[String]?=?None,?
    +????????????userName:?Option[String]?=?None,
    +????????????msg:?Option[String]?=?None)?=?{
    ?????html(

    ??form(action?:=?"/",?method?:=?"post")(
    -????????????input(`type`?:=?"text",?name?:=?"name",?placeholder?:=?"User?name",?width?:=?"20%",?userName.map(value?:=?_)),
    -????????????input(`type`?:=?"text",?name?:=?"msg",?placeholder?:=?"Please?write?a?message!",?width?:=?"60%"),
    +????????????input(
    +??????????????`type`?:=?"text",?
    +??????????????name?:=?"name",?
    +??????????????placeholder?:=?"User?name",?
    +??????????????width?:=?"20%",?
    +??????????????userName.map(value?:=?_)
    +????????????),
    +????????????input(
    +??????????????`type`?:=?"text",
    +??????????????name?:=?"msg",
    +??????????????placeholder?:=?"Please?write?a?message!",?
    +??????????????width?:=?"60%",
    +??????????????msg.map(value?:=?_)
    +????????????),
    ?????????????input(`type`?:=?"submit",?width?:=?"20%")

    這里我們使用了可選的和msg查詢(xún)參數(shù),如果它們存在,則將其作為HTML input標(biāo)簽的value的默認(rèn)值。

    接下來(lái)在的處理函數(shù)中渲染頁(yè)面時(shí),填充和msg,再發(fā)送給用戶:

    ??def?postHello(name:?String,?msg:?String)?=?{
    -????if?(name?==?"")?hello(Some("Name?cannot?be?empty"))
    -????else?if?(name.length?>=?10)?hello(Some("Name?cannot?be?longer?than?10?characters"))
    -????else?if?(msg?==?"")?hello(Some("Message?cannot?be?empty"))
    -????else?if?(msg.length?>=?160)?hello(Some("Message?cannot?be?longer?than?160?characters"))
    +????if?(name?==?"")?hello(Some("Name?cannot?be?empty"),?Some(name),?Some(msg))
    +????else?if?(name.length?>=?10)?hello(Some("Name?cannot?be?longer?than?10?characters"),?Some(name),?Some(msg))
    +????else?if?(msg?==?"")?hello(Some("Message?cannot?be?empty"),?Some(name),?Some(msg))
    +????else?if?(msg.length?>=?160)?hello(Some("Message?cannot?be?longer?than?160?characters"),?Some(name),?Some(msg))
    ?????else?{
    ???????messages?=?messages?:+?(name?->?msg)
    -??????hello()
    +??????hello(None,?Some(name),?None)
    ?????}

    注意任何情況下我們都保留name,但只有錯(cuò)誤的情況才保留msg。這樣做是正確的,因?yàn)槲覀冎幌M脩粼诔鲥e(cuò)時(shí)才進(jìn)行編輯并重新提交。

    完整的代碼.scala如下所示:

    ??package?app
    import?scalatags.Text.all._
    object?MinimalApplication?extends?cask.MainRoutes{
    ??var?messages?=?Vector(
    ????("alice",?"Hello?World!"),
    ????("bob",?"I?am?cow,?hear?me?moo"),
    ????("charlie",?"I?weigh?twice?as?you"),
    ??)

    ??@cask.postForm("/")
    ??def?postHello(name:?String,?msg:?String)?=?{
    ????if?(name?==?"")?hello(Some("Name?cannot?be?empty"),?Some(name),?Some(msg))
    ????else?if?(name.length?>=?10)?hello(Some("Name?cannot?be?longer?than?10?characters"),?Some(name),?Some(msg))
    ????else?if?(msg?==?"")?hello(Some("Message?cannot?be?empty"),?Some(name),?Some(msg))
    ????else?if?(msg.length?>=?160)?hello(Some("Message?cannot?be?longer?than?160?characters"),?Some(name),?Some(msg))
    ????else?{
    ??????messages?=?messages?:+?(name?->?msg)
    ??????hello(None,?Some(name),?None)
    ????}
    ??}

    ??@cask.get("/")
    ??def?hello(errorOpt:?Option[String]?=?None,
    ????????????userName:?Option[String]?=?None,
    ????????????msg:?Option[String]?=?None)?=?{
    ????html(
    ??????head(
    ????????link(
    ??????????rel?:=?"stylesheet",
    ??????????href?:=?"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
    ????????)
    ??????),
    ??????body(
    ????????div(cls?:=?"container")(
    ??????????h1("Scala?Chat!"),
    ??????????hr,
    ??????????div(
    ????????????for((name,?msg)?<-?messages)
    ????????????yield?p(b(name),?"?",?msg)
    ??????????),
    ??????????hr,
    ??????????for(error?<-?errorOpt)
    ??????????yield?i(color.red)(error),
    ??????????form(action?:=?"/",?method?:=?"post")(
    ????????????input(
    ??????????????`type`?:=?"text",
    ??????????????name?:=?"name",
    ??????????????placeholder?:=?"User?name",
    ??????????????width?:=?"20%",
    ??????????????userName.map(value?:=?_)
    ????????????),
    ????????????input(
    ??????????????`type`?:=?"text",
    ??????????????name?:=?"msg",
    ??????????????placeholder?:=?"Please?write?a?message!",
    ??????????????width?:=?"60%",
    ??????????????msg.map(value?:=?_)
    ????????????),
    ????????????input(`type`?:=?"submit",?width?:=?"20%")
    ??????????)
    ????????)
    ??????)
    ????).render
    ??}

    ??initialize()
    }

    利用Ajax實(shí)現(xiàn)動(dòng)態(tài)頁(yè)面更新

    現(xiàn)在有了一個(gè)簡(jiǎn)單的、基于表單的聊天網(wǎng)站,用戶可以發(fā)表消息,其他用戶加載頁(yè)面即可看到已發(fā)表的消息。下一步就是讓網(wǎng)站變成動(dòng)態(tài)的,這樣用戶不需要刷新頁(yè)面就能發(fā)表消息了。

    為實(shí)現(xiàn)這一點(diǎn),我們需要做兩件事情:

網(wǎng)站首頁(yè)   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號(hào):冀ICP備2024067069號(hào)-3 北京科技有限公司版權(quán)所有