开始
按照《Go语言编程》第五章的例子来的…(有很大改动,不然运行不了)
这本书是2012年左右出的,那时候Golang还没出1.0版本.
而现在Golang已经1.8版本了,改了不少东西才能正常的跑起来……
大概2017-03-11 0:30 开始写的…
这会3:15
……
搞完静态文件(就一个妹子UI的CSS),
已经3.40了…
还查了不少golang的文档,这下算是入坑了..
这是昨天改的一个梨子,也先贴一下吧.
Go相册网站程序
还有个问题,就是上传的图片名称会多一段数字,暂时没处理,但是不影响查看。
使用Go版本1.8
uploads目录下面的文件是上传的,上传之后就可以看到了
package main // 文件:photoweb.go import ( "io" "os" "log" "path" "net/http" "fmt" "io/ioutil" "html/template" "runtime/debug" "path/filepath" ) /* -----------------**********-------------------------------- 运行方式: Golang 1.8 ,sublime text3 (安装之后要设置一个Go项目文件夹[go.exe只会从这个目录下面找可执行文件],具体百度) 文件放在:E:\TMP\go\ 目录下面,项目名字叫photoweb 然后直接启动就行,接着打开浏览器访问: http://localhost:8080/ 搞定. 按照《Go语言编程》第五章的例子来的...(有很大改动,不然运行不了) 这本书是2012年左右出的,那时候Golang还没出1.0版本. 而现在Golang已经1.8版本了,改了不少东西才能正常的跑起来...... 大概2017-03-11 0:30 开始写的... 这会3:15 ...... 搞完静态文件(就一个妹子UI的CSS), 已经3.40了... 还查了不少golang的文档,这下算是入坑了.. by prd. */ const( ListDir = 0x0001 UPLOAD_DIR="E:\\TMP\\go\\photoweb\\uploads\\" TEMPLATE_DIR = "./views" ) var templates = make(map[string]*template.Template) var tmpl = "tmpl" /* 用不了,换了 // 静态文件读取 func staticDirHandler(mux *http.ServeMux,prefix string, staticDir string,flags int) { mux.HandleFunc(prefix,func(w http.ResponseWriter,r *http.Request){ fileinfo := staticDir + r.URL.Path[len(prefix)-1:] fmt.Println(fileinfo) if (flags & ListDir) == 0 { if exists := isExists(fileinfo); !exists{ http.NotFound(w,r) return } } http.ServeFile(w,r,fileinfo) }) }*/ // 错误处理 func check(err error) { if err != nil { panic(err) } } /* 上传图片. */ func uploadHandler(w http.ResponseWriter,r *http.Request) { if r.Method == "GET"{ renderHtml(w,"upload.html",nil) //t.Execute(w,nil) } if r.Method == "POST"{ f,h,err := r.FormFile("image") if err != nil { check(err) return } var filenamesinfo = h.Filename defer f.Close() fmt.Println(filenamesinfo) t,err := ioutil.TempFile(UPLOAD_DIR,filenamesinfo) check(err) defer t.Close() io.Copy(t,f) check(err) fainfo := filepath.Base(t.Name()) fmt.Println("____________________") fmt.Println(fainfo) fmt.Println("____________________") http.Redirect(w,r,"view?id="+fainfo,http.StatusFound) } } /* 显示图片. */ func viewHandler(w http.ResponseWriter,r *http.Request) { imageId := r.FormValue("id") imagePath := UPLOAD_DIR + "\\" + imageId if exists := isExists(imagePath);!exists{ http.NotFound(w,r) return } w.Header().Set("Content-Type","image") http.ServeFile(w,r,imagePath) } // 检查文件是否存在. func isExists(path string) bool { _,err := os.Stat(path) if err == nil { return true } return os.IsExist(err) } // 列出所有图片. func listHandler(w http.ResponseWriter,r *http.Request) { fileInfoArr,err := ioutil.ReadDir("E:\\TMP\\go\\photoweb\\uploads\\") check(err) //var listHtml string locals := make(map[string]interface{}) images := []string{} for _,fileInfo := range fileInfoArr{ //fmt.Println(fileInfo) images = append(images,fileInfo.Name()) } locals["images"] = images renderHtml(w,"list.html",locals) } // 模板渲染方法. func renderHtml(w http.ResponseWriter,tmpl string,locals map[string]interface{}){ err := templates[tmpl].Execute(w,locals) check(err) } // 初始化方法,在main之前运行. func init() { fileInfoArr,err := ioutil.ReadDir(TEMPLATE_DIR) fmt.Println(err) //panic(err) var templateName,templatePath string for _,fileInfo := range fileInfoArr{ fmt.Println("_____") fmt.Println(fileInfo.Name()) templateName = fileInfo.Name() //fileInfo.Name if ext := path.Ext(templateName); ext !=".html"{ continue } templatePath = TEMPLATE_DIR + "\\" + templateName log.Println("Loading template:", templatePath) var t = template.Must(template.ParseFiles(templatePath)) templates[fileInfo.Name()] = t } } // 闭包. func safeHandler(fn http.HandlerFunc)http.HandlerFunc { return func (w http.ResponseWriter,r *http.Request) { defer func(){ if err,ok := recover().(error); ok { http.Error(w,err.Error(),http.StatusInternalServerError) // 或者输出自定义的50X错误页面 // w.WriteHeader(http.StatusInternalServerError) // renderHtml(w,"error",e) // logging log.Println("WARN: panic in %v - %v ",fn,err) log.Println(string(debug.Stack())) } }() fn(w,r) } } func main() { http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) http.HandleFunc("/",safeHandler(listHandler)) http.HandleFunc("/upload",safeHandler(uploadHandler)) http.HandleFunc("/view",safeHandler(viewHandler)) // 端口. err := http.ListenAndServe(":8080",nil) if err != nil { log.Fatal("ListenAndServe: ",err.Error()) } }
列表页:list.html
<!doctype html> <html> <head> <meta charset="utf-8" /> <title>列表</title> <link rel="stylesheet" type="text/css" href="/static/amazeui.min.css" /> </head> <body> <ol> {{ range $.images }} <li><a href="/view?id={{.|urlquery}}" target="_blank">{{.|html}}</a></li> {{end}} </ol> <pre> 搞定. 按照《Go语言编程》第五章的例子来的...(有很大改动,不然运行不了) 这本书是2012年左右出的,那时候Golang还没出1.0版本. 而现在Golang已经1.8版本了,改了不少东西才能正常的跑起来...... 大概2017-03-11 0:30 开始写的... 这会3:15 ...... 搞完静态文件(就一个妹子UI的CSS), 已经3.40了... 还查了不少golang的文档,这下算是入坑了.. by prd. </pre> <a href="/upload">上传</a> </body> </html>
上传页面:upload.html
<!doctype html> <html> <head> <meta charset="utf-8" /> <title>上传</title> </head> <body> <form method="POST" action="/upload" enctype="multipart/form-data"> Choose an image to upload: <input name="image" type="file" /> <input type="submit" value="Upload" /> </form> <a href="/">首页</a> </body> </html>
还有一个文件是妹子UI的css,可以在网上直接保存一份(ctrl+s),只是保存到指定目录就可以.[参考地址]
解析JSON数据
JSON解析成Go结构体,可以使用这个工具,直接获取相关结构体
源码如下(优先从网络获取数据,若从网络获取、解析失败,则直接使用本地数据[网络获取的数据与本地数据一样]):
package main import ( "fmt" "net/http" "encoding/json" "io/ioutil" ) /** 参考(json to go): https://mholt.github.io/json-to-go/ golang 解析json字符串. date:2017-03-11 by:prd. */ type JsonInfoObj struct { Sites []struct { Name string `json:"Name"` URL string `json:"Url"` Country string `json:"Country"` } `json:"sites"` } /* 获取json数据-本地数据. */ func getJson() ([]byte) { return []byte(`{"sites":[{"Name":"菜鸟教程","Url":"www.runoob.com","Country":"CN"},{"Name":"Google","Url":"www.google.com","Country":"USA"},{"Name":"Facebook","Url":"www.facebook.com","Country":"USA"},{"Name":"微博","Url":"www.weibo.com","Country":"CN"}]}`) } /* 从网络上获取Json数据. 此函数获取的结果与getJson()中的内容一致. */ func getNetWorkJson() ([]byte) { fmt.Println("-----------从网络获取Json数据开始------------") resp, err := http.Get("http://www.runoob.com/try/angularjs/data/sites.php") if err != nil { // panic(err.Error()) fmt.Println("-----------从网络获取失败,直接返回本地数据------------") return getJson() } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { // panic(err.Error()) fmt.Println("-----------解析网络数据失败,直接返回本地数据------------") return getJson() } fmt.Println("-----------从网络获取Json数据成功------------") return body } /* 显示JSON. */ func showJson() { jsoninfo := getNetWorkJson() var siteinfoJson JsonInfoObj err := json.Unmarshal(jsoninfo, &siteinfoJson) if err != nil { fmt.Println("error:", err) } fmt.Printf("%+v", siteinfoJson) } func main() { showJson() }