1. 程式人生 > 其它 >go web學習筆記

go web學習筆記

- 基於Go的簡單web應用
- 應用的多資料來源訪問
- 模擬表單上傳
- 解析JSON格式的HTTP請求響應

基於Go的簡單web應用

訪問localhost:9090/login可以開啟一個登入頁面,填入使用者名稱和密碼提交後可以在後臺看到輸出。
訪問localhost:9090/upload可以開啟一個檔案上傳頁面,選擇檔案提交後可以在後臺看到輸出,同時在當前專案的test子目錄下可以看到上傳的檔案。

package main

import (
	"fmt"
	"html/template"
	"net/http"
	"log"
	"io"
	"os"
)

func login(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method:", r.Method)
	if r.Method == "GET" {
		t, _ := template.ParseFiles("login.gtpl")
		log.Println(t.Execute(w, nil))
	} else {
		r.ParseForm()
		fmt.Println("username:", r.Form["username"])
		fmt.Println("password:", r.Form["password"])
        //此處可以做使用者名稱和密碼的驗證
	}
}

func upload(w http.ResponseWriter, r *http.Request) {
	fmt.Println("method: ", r.Method)
	if r.Method == "GET" {
		t, _ := template.ParseFiles("upload.gtpl")
		t.Execute(w, nil)
	} else {
		r.ParseMultipartForm(32 << 20)
		file, handler, err := r.FormFile("uploadFile")
		if err != nil {
			fmt.Println(err)
			return
		}
		defer file.Close()
		fmt.Fprintf(w, "%v", handler.Header)
		f, err := os.OpenFile("./test/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
		if err != nil {
			fmt.Println(err)
			return
		}
		defer f.Close()
		io.Copy(f, file)
	}
}

func main() {
	http.HandleFunc("/login", login)
	http.HandleFunc("/upload", upload)
	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		log.Fatal("ListenAndServer: ", err)
	}
}

多資料來源訪問

package main


func main()  {
	http.HandleFunc("/getAccessToken", controller.GetAccessToken)
	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		log.Fatal("ListenAndServer: ", err)
	}
}

//註冊資料庫,此處以兩個MySQL為例,也可以註冊多種不同資料庫
func init()  {
	orm.RegisterDriver("mysql", orm.DRMySQL)
	orm.RegisterDataBase("default", "mysql", "賬號:密碼@tcp(資料庫1地址)/hdfs?charset=utf8")
	orm.RegisterDataBase("db2", "mysql", "賬號:密碼@tcp(資料庫2地址)/tx_log_analysis_test?charset=utf8")
	orm.Debug = true
}

package model


type ResponseToken struct {
	Success bool
	Msg		string
	Token	string
}

type Tadmin struct {
	MailNum string `orm:"column(mailNum);PK"`
	UserName string `orm:"column(userName)"`
	UserDepart string `orm:"column(userDepart)"`
	Password string
	RoleName string
	CreateTime string `orm:"column(createTime)"`
	CreatedByWho string `orm:"column(createdByWho)"`
	UpdateTime string `orm:"column(updateTime)"`
	UpdatedByWho string `orm:"column(updatedByWho)"`
}

func init()  {
	orm.RegisterModel(new(Tadmin))
}

package controller


func GetAccessToken(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	emailnum := r.FormValue("emailnum")
	password := r.FormValue("password")
	result := model.ResponseToken{}
	if emailnum == "" || password == "" {
		result.Msg = "使用者名稱或密碼為空"
		result.Success = false
	} else {
		o := orm.NewOrm()
		//此處切換資料庫
		o.Using("db2")
		user := model.Tadmin{MailNum: emailnum}
		err := o.Read(&user)
		if err != nil {
			fmt.Println(err)
		} else {
			passwordTrue := user.Password
			if passwordTrue == getPwd(password) {
				//此處密碼判斷通過,生成令牌
			} else {
				result.Msg = "密碼錯誤"
				result.Success = false
			}
		}
	}
}

func encrypt(dataStr string) string {
	md5Ctx := md5.New()
	io.WriteString(md5Ctx, dataStr)
	cipherStr := md5Ctx.Sum(nil)
	return hex.EncodeToString(cipherStr)
}

func getPwd(password string) string {
	return encrypt(password + "混淆程式碼")
}

- 模擬表單上傳

模擬本地檔案上傳,執行程式將專案目錄下的Swagger2.docx上傳到http://localhost:9090/upload

import (
	"bytes"
	"mime/multipart"
	"fmt"
	"os"
	"io"
	"net/http"
	"io/ioutil"
)

func postFile(filename string, targetUrl string) error {
	//開啟一個Buffer,用於寫入檔案
	bodyBuf := &bytes.Buffer{}
	bodyWriter := multipart.NewWriter(bodyBuf)

	fileWriter, err := bodyWriter.CreateFormFile("uploadFile", filename)
	if err != nil {
		fmt.Println("寫入快取時發生錯誤")
		return err
	}

	//開啟需要上傳的檔案
	fh, err := os.Open(filename)
	if err != nil {
		fmt.Println("開啟檔案時發生錯誤")
		return err
	}

	//將檔案內容複製到快取
	_, err = io.Copy(fileWriter, fh)
	if err != nil {
		return err
	}

	//提交表單(檔案上傳)
	contentType := bodyWriter.FormDataContentType()
	bodyWriter.Close()

	resp, err := http.Post(targetUrl, contentType, bodyBuf)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
    
	//讀取響應
	resp_body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	fmt.Println(resp.Status)
	fmt.Println(string(resp_body))
	return nil
}

func main() {
	targetUrl := "http://localhost:9090/upload"
	filename := "Swagger2.docx"
	postFile(filename, targetUrl)
}

- 解析JSON格式的HTTP請求響應

func main() {
	tokenUrl := "http://10.2.8.136:19006/getAccessToken"
	var token = getToken(tokenUrl).AccessToken
	fmt.Println(token)
}

type Response struct {
	Success string
	AccessToken string `json:"access_token"`
	ErrorInfo string `json:"error_info"`
}

func getToken(tokenUrl string) Response {
	//請求資料,獲得響應
	resp, err := http.Get(tokenUrl)
	if err != nil {
		fmt.Println(err)
	}
	
  //讀取響應內容
	defer resp.Body.Close()
	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
	}
    
  //將響應內容解析成實體
	var s Response
	json.Unmarshal([]byte(string(respBody)), &s)
	return s
}