操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    【CSDN 編者按】大家都知道Web和API服務器在互聯網中的重要性,在計算機網絡方面提供了最基本的界面。本文主要介紹了怎樣利用Scala實現實時聊天網站和API服務器,通過本篇文章,你定將受益匪淺。

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

    以下為譯文:

    Web和API服務器是互聯網系統的骨干,它們為計算機通過網絡交互提供了基本的界面,特別是在不同公司和組織之間。這篇指南將向你介紹如何利用Scala簡單的HTTP服務器,來提供Web內容和API。本文還會介紹一個完整的例子,告訴你如何構建簡單的實時聊天網站,同時支持HTML網頁和JSON API端點。

    這篇文及章的目的是介紹怎樣用Scala實現簡單的HTTP服務器,從而提供網頁服務,以響應API請求。我們會建立一個簡單的聊天網站,可以讓用戶發表聊天信息,其他訪問網站的用戶都可以看見這些信息。為簡單起見,我們將忽略認證、性能、用戶掛歷、數據庫持久存儲等問題。但是,這篇文章應該足夠你開始用Scala構建網站和API服務器了,并為你學習并構建更多產品級項目打下基礎。

    我們將使用Cask web框架:

    Cask是一個Scala的HTTP為框架,可以用來架設簡單的網站并迅速運行。

    開始

    要開始使用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

    運行find來看看有哪些文件:

    $?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進行構建:

    html提交表單到服務器_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",
    ????)

    ??}
    }

    如果你使用,那么可以運行如下命令來設置項目配置:

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

    現在你可以在中打開-0.3.0/目錄html提交表單到服務器,查看項目的目錄,也可以進行編輯。

    可以利用Mill構建工具運行該程序,只需執行./mill:

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

    該命令將在后臺運行Cask Web服務器,同時監視文件系統,如果文件發生了變化,則重啟服務器。然后我們可以使用瀏覽器瀏覽服務器,默認網址是:8080:

    在/do-thing上還有個POST端點,可以在另一個終端上使用curl來訪問:

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

    可見,它接受數據hello,然后將反轉的字符串返回給客戶端。

    然后可以運行app/test/src/.scala中的自動化測試:

    $?./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

    現在基本的東西已經運行起來了,我們來重新運行Web服務器:

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

    html select 選中提交表單_html提交表單到服務器_表單提交 html

    然后開始實現我們的聊天網站!

    提供HTML服務

    第一件事就是將純文本的"Hello, World!"轉換成HTML網頁。最簡單的方式就是利用這個HTML生成庫。要在項目中使用,只需將其作為依賴項加入到build.sc文件即可:

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

    如果使用,那么還需要重新運行./mill mill../idea命令,來發現依賴項的變動,然后重新運行./mill -w app.讓Web服務器重新監聽改動。

    然后,我們可以在.scala中導入:

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

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

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

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

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

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

    html select 選中提交表單_html提交表單到服務器_表單提交 html

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

    現在字體不太一樣了:

    雖然還不是最漂亮的網站,但現在已經足夠了。

    在本節的末尾,我們修改一下的HTML模板,加上硬編碼的聊天文本和假的輸入框,讓它看起來更像一個聊天應用程序。

    ?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%")
    +??????????)
    ?????????)
    ???????)

    現在我們有了一個簡單的靜態網站,其利用Cask web框架和 HTML庫提供HTML網頁服務。現在的服務器代碼如下所示:

    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()
    }

    接下來,我們來看看怎樣讓它支持交互!

    表單和數據

    為網站添加交互的第一次嘗試是使用HTML表單。首先我們要刪掉硬編碼的消息列表,轉而根據數據來輸出HTML網頁:

    ?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)
    ???????????),

    這里我們簡單地使用了內存上的存儲。關于如何將消息持久存儲到數據庫中,我將在以后的文章中介紹。

    html提交表單到服務器_表單提交 html_html select 選中提交表單

    接下來,我們需要讓頁面底部的兩個input支持交互。為實現這一點,我們需要將它們包裹在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%")
    ??????????)

    這樣我們就有了一個可以交互的表單,外觀跟之前的差不多。但是,提交表單會導致Error 404: Not Found錯誤。這是因為我們還沒有將表單與服務器連接起來,來處理表單提交并獲取新的聊天信息。我們可以這樣做:

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

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

    驗證

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

    實現這一點很簡單:

    ??@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,但出現了另一個問題:用戶輸入了非法的名字或信息并提交,那么這些信息就會消失,而且不會為錯誤產生任何反饋。解決方法是,給hello()頁面渲染一個可選的錯誤信息,用它來告訴用戶出現了什么問題:

    ?@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提交表單到服務器_表單提交 html

    現在,當名字或信息非法時,就可以正確地顯示出錯誤信息了。

    下一次提交時錯誤信息就會消失。

    記住名字和消息

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

    ?@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查詢參數,如果它們存在,則將其作為HTML input標簽的value的默認值。

    接下來在的處理函數中渲染頁面時,填充和msg,再發送給用戶:

    ??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,但只有錯誤的情況才保留msg。這樣做是正確的,因為我們只希望用戶在出錯時才進行編輯并重新提交。

    完整的代碼.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實現動態頁面更新

    現在有了一個簡單的、基于表單的聊天網站,用戶可以發表消息,其他用戶加載頁面即可看到已發表的消息。下一步就是讓網站變成動態的,這樣用戶不需要刷新頁面就能發表消息了。

    為實現這一點,我們需要做兩件事情:

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

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

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有