Go语言练习:网络编程实例——简易图片上传网站
1、代码结构
2、运行实例
1、代码结构
$ tree
.
├── photoweb.go
├── public
│ ├── css
│ ├── images
│ └── js
├── uploads
└── views
├── list.html
└── upload.html
1.1)photoweb.go
package main import (
"io"
"os"
"log"
"net/http"
"io/ioutil"
"html/template"
"path"
//"debug"
"fmt"
) const (
UPLOAD_DIR = "./uploads"
TEMPLATE_DIR = "./views"
ListDir = 0x0001
) var templates map[string] * template.Template = make(map[string] * template.Template) func init() {
fileInfoArr, err := ioutil.ReadDir(TEMPLATE_DIR)
check(err) var templateName, templatePath string
for _, fileInfo := range fileInfoArr {
templateName = fileInfo.Name()
if ext := path.Ext(templateName); ext != ".html" {
continue
}
templatePath = TEMPLATE_DIR + "/" + templateName;
t := template.Must(template.ParseFiles(templatePath))
rlname := realName(templateName)
log.Println("Loading template:", rlname)
templates[rlname] = t
}
} func realName(str string) string {
str = path.Base(str)
if str == "" {
return str
}
for i := ; i < len(str); i++ {
if '.' == str[i] {
return str[:i]
}
}
return str
} func uploadHandler(w http.ResponseWriter, r * http.Request) {
if r.Method == "GET" {
readerHtml(w, "upload", nil);
} if r.Method == "POST" {
f, h , err := r.FormFile("image")
if err != nil {
http.Error(w, err.Error(),
http.StatusInternalServerError)
return
}
filename := h.Filename
defer f.Close()
t, err := os.Create(UPLOAD_DIR + "/" + filename)
if err != nil {
http.Error(w, err.Error(),
http.StatusInternalServerError)
return
}
defer t.Close()
if _, err := io.Copy(t, f); err != nil {
http.Error(w, err.Error(),
http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/view?id="+filename,
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("./uploads")
if err != nil {
http.Error(w, err.Error(),
http.StatusInternalServerError)
fmt.Println("faild @ listHandler")
return
} locals := make(map[string]interface{})
images := []string{}
for _, fileInfo := range fileInfoArr {
if fileInfo.Name() != ".svn" {
images = append(images, fileInfo.Name())
}
}
locals["images"] = images readerHtml(w, "list", locals);
} func readerHtml(w http.ResponseWriter, tmpl string, locals map[string]interface{}){
err := templates[tmpl].Execute(w, locals)
check(err)
} func check(err error) {
if err != nil {
panic(err)
}
} func safeHandler(fn http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r * http.Request) {
defer func() {
if e , ok := recover().(error); ok {
http.Error(w, e.Error(), http.StatusInternalServerError)
log.Println("WARN: panic in %v - %v", fn, e)
// log.Println(string(debug.Stack()))
}
}()
fn(w, r)
}
} func staticDirHandler(mux * http.ServeMux, prefix string, staticDir string, flags int) {
mux.HandleFunc(prefix, func(w http.ResponseWriter, r * http.Request) {
file := staticDir + r.URL.Path[len(prefix) - :]
if (flags & ListDir) == {
if exists := isExists(file); !exists {
http.NotFound(w, r)
fmt.Println(file, "not found")
return
}
}
fmt.Println("handle static dir")
http.ServeFile(w, r, file)
})
} func main() {
mux := http.NewServeMux()
staticDirHandler(mux, "/assets/", "./public", )
mux.HandleFunc("/", safeHandler(listHandler))
mux.HandleFunc("/view", safeHandler(viewHandler))
mux.HandleFunc("/upload", safeHandler(uploadHandler))
err := http.ListenAndServe(":8090", mux)
if err != nil {
log.Fatal("ListenAndServe: ", err.Error())
}
}
1.2)views/list.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>List</title>
</head>
<body>
<ol>
{{range $.images}}
<li><a href="/view?id={{.|urlquery}}">{{.|html}}</a></li>
{{end}}
</ol>
</body>
</html>
1.3)views/upload.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Upload</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>
</body>
</html>
2、运行及结果
2.1)运行
$ go run photoweb.go
2015/07/25 02:15:24 Loading template: list
2015/07/25 02:15:24 Loading template: upload
2.2)在浏览器端输入服务器地址

Go语言练习:网络编程实例——简易图片上传网站的更多相关文章
- Java网络编程(TCP协议-练习-上传文本文件)
客户端: package WebProgramingDemo; import java.io.BufferedReader; public class UploadTextClient { /** * ...
- Thinkphp整合阿里云OSS图片上传实例
Thinkphp3.2整合阿里云OSS图片上传实例,图片上传至OSS可减少服务器压力,节省宽带,安全又稳定,阿里云OSS对于做负载均衡非常方便,不用传到各个服务器了 首先引入阿里云OSS类库 < ...
- layui加tp5图片上传实例
<div class="layui-fluid"> <div class="layui-row"> <form class=&qu ...
- Java学习之网络编程实例
转自:http://www.cnblogs.com/springcsc/archive/2009/12/03/1616413.html 多谢分享 网络编程 网络编程对于很多的初学者来说,都是很向往的一 ...
- php网络编程实例
php网络编程实例 一.总结 一句话总结: socket_create():创建socket socket_bind():绑定IP和端口 socket_listen():监听客户端信息 <?ph ...
- java网络编程之图片上传
输入输出流核心代码 所有的文件传输都是靠流,其中文件复制最具代表性.输入流和输出流,从输入流中读取数据写入到输出流中. InputStream in = 输入源; OutputStream os = ...
- PHP多图片上传实例demo
upload.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ ...
- 网游中的网络编程3:在UDP上建立虚拟连接
目录 网游中的网络编程系列1:UDP vs. TCP 网游中的网络编程2:发送和接收数据包 网游中的网络编程3:在UDP上建立虚拟连接 TODO 二.在UDP上建立虚拟连接 介绍 UDP是无连接的,一 ...
- asp.net 百度编辑器 UEditor 上传图片 图片上传配置 编辑器配置 网络连接错误,请检查配置后重试
1.配置ueditor/editor_config.js文件,将 //图片上传配置区 ,imageUrl:URL+"net/imageUp.ashx" //图片上传提交地址 ,im ...
随机推荐
- Spring XML配置文件示例(一)——<Servlet name>-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- Oracle ASM
一 Oracle ASM簡介 Oracle 10g推出的管理磁盤的新方式,用於取代LVM技術.主要用于RAC環境 二 Oracle ASM的配置安裝 1.安裝asm包 RedHat Linux5.x ...
- go sample - mongodb
简单的mongodb 操作 package mainimport ( "fmt" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2 ...
- hdu 4784 Dinner Coming Soon(spfa + 优先队列)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4784 思路:建图,对于同一个universe来说,就按题目给的条件相连,对于相邻的universe,连 ...
- Struts2请求参数校验
校验的分类 客户端数据校验 和 服务器端数据校验 客户端数据校验 ,通过JavaScript 完成校验 (改善用户体验,使用户减少出错 ) 服务器数据校验 ,通过Java代码 完成校验 struts2 ...
- JMeter中BeanShell用法总结(一)
一.什么是Bean Shell BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法; BeanShell是一种松散类型的脚本语言(这点和JS类似); BeanS ...
- JDK BIO编程
网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请求,通过三次握手建 ...
- POJ 1159 回文串-LCS
题目链接:http://poj.org/problem?id=1159 题意:给定一个长度为N的字符串.问你最少要添加多少个字符才能使它变成回文串. 思路:最少要添加的字符个数=原串长度-原串最长回文 ...
- json返回数据库的时间格式为/Date(1477294037000)/,怎样在前台进行格式化转换
方法一: 原理是取中间的数,再转换成js的Date类型 function ChangeDateFormat(val) { if (val != null) { var date = new Date( ...
- Swift3.0语言教程字符串与文件的数据转换
Swift3.0语言教程字符串与文件的数据转换 Swift3.0语言教程字符串与文件的数据转换,如果想要对字符串中的字符进行永久保存,可以将字符串中的字符写入到文件中.当然,开发者也可以将写入的内容进 ...