程式碼片段 - Golang 實現簡單的 Web 服務器

來源:互聯網
上載者:User

標籤:

------------------------------  下面一段代碼,實現了最簡單的 Web 服務器:編譯環境:  Linux Mint 18 Cinnamon 64-bit  Golang 1.7------------------------------// main.gopackage mainimport ("fmt""log""net/http")// 處理首頁請求func index(w http.ResponseWriter, r *http.Request) {// 向用戶端寫入內容fmt.Fprintf(w, "Hello World!")}func main() {http.HandleFunc("/", index)              //設定訪問的路由err := http.ListenAndServe(":9090", nil) //設定監聽的連接埠if err != nil {log.Fatal("ListenAndServe: ", err)}}------------------------------  執行上面的程式之後,開啟 網頁瀏覽器,在地址欄輸入:127.0.0.1:9090 就可以訪問這個伺服器了。它只實現了最簡單的單一頁面的輸出。  接下來我們讓伺服器接受用戶端輸入的資料,然後將其反饋給用戶端。  首先,我們要向用戶端寫入一個表單頁面,以便用戶端有地方可以填寫資料和提交資料。然後還需要在服務端添加一個頁面處理函數,用來處理使用者提交的資料。下面就開始實現這個功能。------------------------------// main.gopackage mainimport ("fmt""log""net/http")// 向用戶端寫入這些資料,以便用戶端可以填寫文本並提交var indexHTML = `<html><head><meta http-equiv="Content-type" content="text/html; charset=utf-8" /><title>測試</title></head><body><form action="/page" method="post">使用者名稱:<br /><input name="username" type="text" /><br />請輸入文本:<br /><textarea name="usertext"></textarea><br /><input type="submit" value="提交"></form></body></html>`// 用於將頁面重新導向到首頁var redirectHTML = `<html><head><meta http-equiv="Content-type" content="text/html; charset=utf-8"><meta http-equiv="Refresh" content="0; url={{.}}"></head><body></body></html>`// 處理首頁請求func index(w http.ResponseWriter, r *http.Request) {// 向用戶端寫入我們準備好的頁面fmt.Fprintf(w, indexHTML)}// 處理用戶端提交的資料func page(w http.ResponseWriter, r *http.Request) {// 我們規定必須通過 POST 提交資料if r.Method == "POST" {// 解析用戶端請求的資訊if err := r.ParseForm(); err != nil {log.Println(err)}// 擷取用戶端輸入的內容userName := r.Form.Get("username")userText := r.Form.Get("usertext")// 將內容反饋給用戶端fmt.Fprintf(w, "你好 %s,你輸入的內容是:%s", userName, userText)} else {// 如果不是通過 POST 提交的資料,則將頁面重新導向到首頁fmt.Fprintf(w, redirectHTML)}}func main() {http.HandleFunc("/", index)              // 設定訪問的路由http.HandleFunc("/page", page)           // 設定訪問的路由err := http.ListenAndServe(":9090", nil) // 設定監聽的連接埠if err != nil {log.Fatal("ListenAndServe: ", err)}}------------------------------  到此,我們已經實現了用戶端和服務端的自由互動,但是將“頁面內容”和“邏輯代碼”混在一起總是不好的,下我們把“頁面內容”和“邏輯代碼”分開存放。  在 views 目錄中建立 3 個 html 檔案用於存放首頁、反饋頁面、重新導向頁面,內容如下:------------------------------<!-- views/index.html --><html><head><meta http-equiv="Content-type" content="text/html; charset=utf-8" /><title>測試</title></head><body><form action="/page" method="post">使用者名稱:<br /><input name="username" type="text" /><br />請輸入文本:<br /><textarea name="usertext"></textarea><br /><input type="submit" value="提交"></form></body></html>------------------------------<!-- views/page.html --><html><head><meta http-equiv="Content-type" content="text/html; charset=utf-8"></head><body><h3>你好 {{.Name}},你輸入的內容是:</h3><pre>{{.Text}}</pre><p><a href="/">返回</a></p></body></html>------------------------------<!-- views/redirect.html --><html><head><meta http-equiv="Content-type" content="text/html; charset=utf-8"><meta http-equiv="Refresh" content="0; url={{.}}"></head><body></body></html>------------------------------main.go 的內容如下:------------------------------// main.gopackage mainimport ("html/template""log""net/http")func checkErr(err error) {if err != nil {log.Println(err)}}// 存放使用者資料type UserData struct {Name stringText string}// 渲染頁面並輸出func renderHTML(w http.ResponseWriter, file string, data interface{}) {// 擷取頁面內容t, err := template.New(file).ParseFiles("views/" + file)checkErr(err)// 將頁面渲染後反饋給用戶端t.Execute(w, data)}// 處理首頁請求func index(w http.ResponseWriter, r *http.Request) {// 渲染頁面並輸出renderHTML(w, "index.html", "no data")}// 處理使用者提交的資料func page(w http.ResponseWriter, r *http.Request) {// 我們規定必須通過 POST 提交資料if r.Method == "POST" {// 解析用戶端請求的資訊if err := r.ParseForm(); err != nil {log.Println("Handler:page:ParseForm: ", err)}// 擷取用戶端輸入的內容u := UserData{}u.Name = r.Form.Get("username")u.Text = r.Form.Get("usertext")// 渲染頁面並輸出renderHTML(w, "page.html", u)} else {// 如果不是通過 POST 提交的資料,則將頁面重新導向到首頁renderHTML(w, "redirect.html", "/")}}func main() {http.HandleFunc("/", index)              // 設定訪問的路由http.HandleFunc("/page", page)           // 設定訪問的路由err := http.ListenAndServe(":9090", nil) // 設定監聽的連接埠if err != nil {log.Fatal("ListenAndServe: ", err)}}------------------------------  一般在收到用戶端資料後,我們都希望把它儲存在伺服器中,以便用戶端隨時可以讀取,下面我們就來實現這個功能,將使用者提交的資料存放區到伺服器的 SQLite 資料庫中(SQLite 僅用於測試,實際網站推薦使用 MongoDb)。  當然需要 "github.com/mattn/go-sqlite3" 這個包和 SQLite 開發環境:1、在 Linux Mint 的終端輸入“go get github.com/mattn/go-sqlite3”擷取包檔案。2、在 Linux Mint 的軟體管理器中搜尋“Golang-github-mattn-go-sqlite3-dev”並安裝。3、在 Linux Mint 的軟體管理器中搜尋“SQLiteman”並安裝(可選),用於查看 SQLite 資料庫。  開發環境搭建好後,下面就是資料庫作業碼:------------------------------// main.gopackage mainimport ("database/sql""html/template""log""net/http"_ "github.com/mattn/go-sqlite3")func checkErr(err error) {if err != nil {log.Println(err)}}// 存放使用者資料type UserData struct {Name stringText string}// 渲染頁面並輸出func renderHTML(w http.ResponseWriter, file string, data interface{}) {// 擷取頁面內容t, err := template.New(file).ParseFiles("views/" + file)checkErr(err)// 將頁面渲染後反饋給用戶端t.Execute(w, data)}// 寫入資料庫(返回寫入後的資料)func writeData(userData *UserData) string {// 開啟資料庫db, err := sql.Open("sqlite3", "./data.db")checkErr(err)defer db.Close()// 如果資料表不存在則建立(如果存在則跳過)db.Exec(`create table data (id integer not null primary key, name text, data string);`)var olddata string // 資料庫中已存在的資料var sqlStmt string // sql 內容// 查詢使用者是否存在,同時讀取使用者資料err = db.QueryRow("select data from data where name = ?", userData.Name).Scan(&olddata)if err != nil { // 使用者不存在sqlStmt = "insert into data(data, name) values(?,?)" // 添加資料} else { // 使用者存在sqlStmt = "update data set data = ? where name == ?" // 更新資料// 如果 data 為空白,則刪除使用者if len(userData.Text) == 0 {sqlStmt = "delete from data where data >= ? and name == ?" // 刪除欄位}}// 準備 SQLstmt, err := db.Prepare(sqlStmt)checkErr(err)defer stmt.Close()// 如果 data 為空白,則刪除使用者,否則將 data 追加到資料庫if len(userData.Text) > 0 {userData.Text = olddata + "\n" + userData.Text}// 執行 SQL_, err = stmt.Exec(userData.Text, userData.Name)checkErr(err)return userData.Text}// 處理首頁請求func index(w http.ResponseWriter, r *http.Request) {// 渲染頁面並輸出renderHTML(w, "index.html", "no data")}// 處理使用者提交的資料func page(w http.ResponseWriter, r *http.Request) {// 我們規定必須通過 POST 提交資料if r.Method == "POST" {// 解析用戶端請求的資訊if err := r.ParseForm(); err != nil {log.Println("Handler:page:ParseForm: ", err)}// 擷取用戶端輸入的內容u := UserData{}u.Name = r.Form.Get("username")u.Text = r.Form.Get("usertext")// 寫入資料庫,同時擷取處理後的資料u.Text = writeData(&u)// 渲染頁面並輸出renderHTML(w, "page.html", u)} else {// 如果不是通過 POST 提交的資料,則將頁面重新導向到首頁renderHTML(w, "redirect.html", "/")}}func main() {http.HandleFunc("/", index)              // 設定訪問的路由http.HandleFunc("/page", page)           // 設定訪問的路由err := http.ListenAndServe(":9090", nil) // 設定監聽的連接埠if err != nil {log.Fatal("ListenAndServe: ", err)}}------------------------------  上面的例子只是簡陋的代碼,協助入門,更深入的內容,請學習《Go Web 編程》:  https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/preface.md------------------------------

程式碼片段 - Golang 實現簡單的 Web 服務器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.