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 ...
随机推荐
- apache linux 安装
sudo apt-get install zlib1g-dev 1.到官网下载,然后解压httpd-2.4.18.tar.gz 2.下载apr-1.5.2.tar.gz并解压 http://ar ...
- 3-1创建Sql Sever数据库登录名
登录名:连接Sql Sever 服务器 数据库用户名: Sql Sever 的使用者 每个用来登录Sql Sever 的账户都是一个用户. 同一个数据库可以拥有多个用户,每一个用户也同时可以访问多个数 ...
- 新浪微博的账号登录及api操作
.sina.php <?php /** * PHP Library for weibo.com * * @author */ class sinaPHP { function __constru ...
- VS2015上又一必备免费插件:Refactoring Essentials
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:Refactoring Essentials是一款用于代码分析和重构的开源免费VS20 ...
- codeforce ABBYY Cup 3.0 - Finals (online version) B2. Shave Beaver! 线段树
B2. Shave Beaver! The Smart Beaver has recently designed and built an innovative nanotechnologic a ...
- javascript概述
在我们进行javascript视频的时候,第一集,看到的学习要点: 1.什么是javascript? a.一种具有面向对象能力的.解释型的程序设计语言(直接读取运行,而非编译型) ...
- 战斗住的DPS才是DPS,持续的执行力才是执行力
工作久了,真的发现执行力这个东西太难被贯彻,计划时信心满满,冲劲十足,持续一段时间后就喇叭腔了.
- 简单用DOM4J结合XPATH解析XML
由于DOM4J在解析XML时只能一层一层解析,所以当XML文件层数过多时使用会很不方便,结合XPATH就可以直接获取到某个元素 使用dom4j支持xpath的操作的几种主要形式 第一种形式 ...
- jsp网站环境搭建
工具:tomcat7(exe安装版).jre7.javaxcms(安装版.非源码).mysql 1.先安装jre7,或者安装java7(自带了jre7) 2.安装tomcat7,期间要选择jre7安装 ...
- 【转】Hive配置文件中配置项的含义详解(收藏版)
http://www.aboutyun.com/thread-7548-1-1.html 这里面列出了hive几乎所有的配置项,下面问题只是说出了几种配置项目的作用.更多内容,可以查看内容问题导读:1 ...