用Go语言开发Web服务程序

概述

设计一个 web 小应用,展示静态文件服务、js 请求支持、模板输出、表单处理、Filter 中间件设计等方面的能力。(不需要数据库支持)

任务要求

编程 web 应用程序 cloudgo-io。 请在项目 README.MD 给出完成任务的证据!

实现内容

    1) 支持静态文件服务

    2) 支持简单 js 访问

    3) 提交表单,并输出一个表格

    4) 对 /unknown 给出开发中的提示,返回码 5xx

这次我实现的是一个基于Gin框架开发的Web服务程序,基础的网页前端是之前上Web 2.0课程中登陆界面的作业代码。具体来说是一个支持用户注册和信息查看的网页。用户可以登录并查看他们的信息,然后可以通过网址栏跳转到相应网页进行查看。做了一些关于用户信息的重复判断和一些鲁棒性方面的东西。

首先上一张预览图,让大家看看效果:

Gin框架简介

Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,已经发布了1.0版本。具有快速灵活,容错方便等特点。其实对于golang而言,web框架的依赖要远比Python,Java之类的要小。自身的net/http足够简单,性能也非常不错。框架更像是一些常用函数或者工具的集合。借助框架开发,不仅可以省去很多常用的封装带来的时间,也有助于团队的编码风格和形成规范

下面为了让大家能够对Gin有更好的认识和基本的上手,这里介绍一下使用Gin实现的Hello,World。

import (
    "gopkg.in/gin-gonic/gin.v1"
    "net/http"
)

func main(){
    
    router := gin.Default()

    router.GET("/", func(c *gin.Context) {
        c.String(http.StatusOK, "Hello World")
    })
    router.Run(":8000")
}

简单几行代码,就能实现一个web服务。使用gin的Default方法创建一个路由handler。然后通过HTTP方法绑定路由规则和路由函数。不同于net/http库的路由函数,gin进行了封装,把request和response都封装到gin.Context的上下文环境。最后是启动路由的Run方法监听端口。麻雀虽小,五脏俱全。当然,除了GET方法,gin也支持POST,PUT,DELETE,OPTION等常用的restful方法。

静态文件服务

在Gin中,搭建静态文件服务是比较容易的一件事情,下面贴一段代码:

func main() {
    router := gin.Default()
    router.Static("/assets", "./assets")
    // Listen and server on 0.0.0.0:8080
    router.Run(":8080")
}

上面这段代码,为路由器指定了一个Static Route,所有指向assets的访问,都会去./assets这个目录下面进行查找

简单js访问以及对于表单的处理

当客户端试图通过用POST方法向服务端发送请求的时候,它实际上是向服务端发送了一个POST方法的表单数据。因为,我们处理POST方法实际上是处理了一个表单数据,gin框架在这方面有也完备的做法:

// 这里创建的这个type是用来绑定数据并传送去服务端的
type registerJSON struct {
	Username string `form:"username" binding:"required"`
	Stuid    string `form:"stuid" binding:"required"`
	Tel      string `form:"tel" binding:"required"`
	Email    string `form:"email" binding:"required"`
}

// 创建一个type的实例用于绑定数据
var user registerJSON

// 试图绑定由客户端发送的数据
if err := c.Bind(&user); err != nil {
  c.JSON(http.StatusBadRequest, gin.H{
    "code":    "BAD_REQUEST",
    "message": "Something wrong with the server",
  })
  fmt.Println(err.Error())
  return
}

在上面的示例代码中,我们为其分配了表单中的字段,从而使它可以去解析一个 POST 表单。进而进行进一步的逻辑处理。通过 Bind 方法,我们就能将请求中的数据悉数传入到给定的绑定实例上,而如果有任何问题发生,一个 err 将会被返回给你。

/unknown与404的实现

/unknown实现也不是一个很难实现的东西,用一些基本的语法就可以实现了:

router.GET("/unknown", func(c *gin.Context) {
  c.JSON(http.StatusNotImplemented, gin.H{
    "code":    "NOT_IMPLEMENTED",
    "message": "This page has not been implemented.",
  })
})

所谓的404问题,也就是找不到对应的page嘛,Gin框架里面有一个NoRoute方法,它可以捕获到所有未能通过Route方法指定处理函数的请求,并且为这些未处理的请求统一分配函数。

router.NoRoute(func(c *gin.Context) {
  c.JSON(http.StatusNotFound, gin.H{
    "code":    "PAGE_NOT_FOUND",
    "message": "Target page not found.",
  })
})

posted @ 2018-11-16 14:28  Xiongzj  阅读(3894)  评论(0编辑  收藏  举报