开始
按照《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()
}