go web接口

普通接口

web服务器

import (
    "io"
    "net/http"
)

func hello(w http.ResponseWriter, r *http.Request) {
    io.WriteString(w, "Hello world!")
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", hello)
    http.ListenAndServe(":8000", mux)
}

静态文件服务器

   import (
       "net/http"
       "log"
   )

   func main() {
       s := "/Users/admin/go/src/demo";
       http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(s))))
       err := http.ListenAndServe(":8088", nil)
       if err != nil {
           log.Fatalln("err===", err);
       }
   }

文件接口

文件上传接口

一般情况下的服务器接收文件代码

// 处理/upload 逻辑

func upload( w http.ResponseWriter, r *http.Request) {
    r.ParseMultipartForm(2024)//缓存为1k
    file, handler, err := r.FormFile("uploadfile")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer file.Close()
    fmt.Println("文件大小===", handler.Size)
    fmt.Println("文件名===", handler.Filename)
    //打开一个文件,如果没有就创建
    f,err := os.Create("文件名")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer f.Close()
    f.Chmod(777)//设置文件权限
    buf := make([]byte,1024)//创建一个初始容量为1024的slice,作为缓冲容器
    for{
        //循环读取文件数据到缓冲容器中,返回读取到的个数
        n,err:= file.Read(buf)
        if err != nil {
            fmt.Println(err)
            return
        }
        if 0==n{
            break //如果读到个数为0,则读取完毕,跳出循环
        }
        //从缓冲slice中写出数据,从slice下标0到n,通过os.Stdout写出到控制台
        f.Write(buf[:n])
    }
}

base64接收接口

const file_root = "/Users/admin/go/src/lu-activity/file/"

type upload struct {
    Base_64 string `json:"base_64"` //
}

// 文件上传接口
func uploadHandler(w http.ResponseWriter, r *http.Request) {
    success, encodeByte, file_suf := uploadHandlerParmCheck(w, r)
    if !success {
        return
    }
    url, err := saveImgeToFile(file_suf, encodeByte)
    if err != nil {
        return
    }
    info := make(map[string]string)
    info["url"] = "/v1/file" + url
    fmt.Fprintf(w,"%+v" ,info)
    return
}

// 参数校验
func uploadHandlerParmCheck(w http.ResponseWriter, r *http.Request) (bool, []byte, string) {
    Body := r.Body
    body := make([]byte, 0)
    buffer := make([]byte, 2048)
    for {
        n, err := Body.Read(buffer)
        if err == io.EOF {
            body = append(body, buffer[0:n]...)
            break
        }
        body = append(body, buffer[0:n]...)
    }
    defer Body.Close()
    info := upload{}
    err := json.Unmarshal(body, &info)
    if err != nil || info.Base_64 == "" {
        return false, nil, ""
    }
    data := strings.Split(info.Base_64, ";base64,")
    if !(len(data) >= 2) {
        return false, nil, ""
    }
    encodeByte, err := base64.StdEncoding.DecodeString(data[1]) //成图片文件并把文件写入到buffer
    if err != nil {
        return false, nil, ""
    }
    data_type := data[0]
    file_suf := ""
    switch data_type {
    case "data:image/png": //image/jpeg 显示文件内容  试图显示图片2 试图显示图片  试图显示图片  试图显示图片
        file_suf = "png"
    case "data:image/jpeg":
        file_suf = "jpg"
    }
    return true, encodeByte, file_suf
}

// 保存文件到磁盘
// file_url     图片要保存的文件夹
// file_name    图片要保存的图片名称
// file_suf     图片的后缀名
// data         图片数据
func saveImgeToFile(file_suf string, data []byte) (string, error) {
    timenow := time.Now()
    pak_name := timenow.Format("2006-01-02 15:04:05")[0:7]
    file_name := strconv.FormatInt(timenow.Unix(), 10)
    if exist, _ := pathExists(file_root + pak_name); !exist {
        err := os.Mkdir(file_root+pak_name, 0777)
        if err != nil {
            return "", err
        }
    }
    return "/" + file_suf + "/" + file_name, ioutil.WriteFile(file_root+pak_name+"/"+file_name+"."+file_suf, data, 0664) //buffer输出到jpg文件中(不做处理,直接写到文件)
}

/*
 * 判断文件是否存在
 * 如果返回的错误为nil,说明文件或文件夹存在
 * 如果返回的错误类型使用os.IsNotExist()判断为true,说明文件或文件夹不存在
 * 如果返回的错误为其它类型,则不确定是否在存在
 *
 */
func pathExists(path string) (bool, error) {
    _, err := os.Stat(path)
    if err == nil {
        return true, nil
    }
    if os.IsNotExist(err) {
        return false, nil
    }
    return false, err
}

图片文件查看接口

// 查看文件的路径
func fileHandler(w http.ResponseWriter, r *http.Request) {
    success, file_path, content_type := fileHandlerParmCheck(w, r)
    if !success {
        return
    }
    w.Header().Set("Content-Type", content_type+"; charset=UTF-8")
    // 下载文件接口需要加的文件名
    //  w.Header().Set("Content-Type", "application/octet-stream")
    //  w.Header().Set("content-disposition", "attachment; filename=\""+"aa.xlsx"+"\"")
    http.ServeFile(w, r, file_path)
}

// 文件接口的参数校验
func fileHandlerParmCheck(w http.ResponseWriter, r *http.Request) (bool, string, string) {
    // 从路由中获取图片的信息
    image_type := mux.RouteVars(r)["type"] // 图片的类型
    content_type := ""
    switch image_type {
    case "png": //image/jpeg    显示文件内容  试图显示图片2 试图显示图片  试图显示图片  试图显示图片
        content_type = "image/png"
    case "jpg":
        content_type = "image/jpeg"
    }
    if content_type == "" {
        return false, "", content_type
    }
    // 从路由中获取图片的信息
    image_id := mux.RouteVars(r)["id"] // 图片的路径及ID
    image_nuix, err := strconv.ParseInt(image_id, 10, 64)
    if image_id == "" || err != nil {
        return false, "", content_type
    }
    image_time := time.Unix(image_nuix, 0)
    return true, file_root + image_time.Format("2006-01-02 15:04:05")[0:7] + "/" + image_id + "." + image_type, content_type
}

const file_root = "/Users/admin/go/src/lu-activity/file/"

文件客户端

上传文件

// filename 上传的文件名称
// reader   文件的读取流
func postFile("文件名",post_url string, reader io.Reader) (PostImageResult, error) {
    result := PostImageResult{}
    bodyBuf := &bytes.Buffer{}
    bodyWriter := multipart.NewWriter(bodyBuf)
    //关键的一步操作
    fileWriter, err := bodyWriter.CreateFormFile("取文件的key值", filename)
    if err != nil {
        fmt.Println("error writing to buffer")
        return result, err
    }
    _, err = io.Copy(fileWriter, reader)
    if err != nil {
        return result, err
    }
    contentType := bodyWriter.FormDataContentType()
    bodyWriter.Close()
    resp, err := http.Post(post_url, contentType, bodyBuf)
    if err != nil {
        return result, err
    }
    defer resp.Body.Close()
    resp_body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return result, err
    }
    err = json.Unmarshal(resp_body, &result)
    if err != nil {
        return result, err
    }
    return result, nil
}

下载文件

func main() {
    f, err := os.Create("./file.exe")  //其实这里的 O_RDWR应该是 O_RDWR|O_CREATE,也就是文件不存在的情况下就建一个空文件,但是因为windows下还有BUG,如果使用这个O_CREATE,就会直接清空文件,所以这里就不用了这个标志,你自己事先建立好文件。
    if err != nil { panic(err) }
    stat, err := f.Stat()    //获取文件状态
    if err != nil { panic(err) }
    f.Seek(stat.Size(), 0)    //把文件指针指到文件末,当然你说为何不直接用 O_APPEND 模式打开,没错是可以。我这里只是试验。
    url := "http://dl.google.com/chrome/install/696.57/chrome_installer.exe"
    resp, err := http.Get(url)
    if err != nil { panic(err) }
    written, err := io.Copy(f, resp.Body)
    if err != nil { panic(err) }
    println("written: ", written)
}

你可能感兴趣的:(go web接口)