【问题标题】:How to get the full host and url in go-restful如何在 go-restful 中获取完整的主机和 url
【发布时间】:2017-01-06 01:31:18
【问题描述】:

我正在使用 https://github.com/emicklei/go-restful 在 Go 中编写一个 REST API

在我的 JSON 输出中,我想输出到其他 REST 资源的绝对路径,但我不知道如何获取构建路径的所有相关部分,例如传输 (http/https)、主机、端口、根路径。

我需要自己跟踪这个吗,我是否以某种方式从Request 获取它?

【问题讨论】:

    标签: rest http url go go-restful


    【解决方案1】:

    在玩了一段时间之后,我最终尝试了两种方式。事实证明,至少可以从Request 中提取一些信息(注意:我假设如果使用绝对 url 定义路由,那么所有这些信息都可以从Request.URL 中获得)

    package main
    
    import (
        "github.com/emicklei/go-restful"
        "io"
        "net/http"
    )
    
    func main() {
        ws := new(restful.WebService)
        ws.Route(ws.GET("/hello").To(hello))
        restful.Add(ws)
        http.ListenAndServe(":8080", nil)
    }
    
    func hello(req *restful.Request, resp *restful.Response) {
        io.WriteString(resp, "Protocol: " + req.Request.Proto + "\nHost: " + req.Request.Host + "\nPath: " + req.Request.URL.Path)
    }
    

    上面将以下内容打印到浏览器。我想人们可以使用它来构造 jsonify 的 url,尽管在没有基本路径或特定路径的先验知识或区分两者的语法约定的情况下,如何解析基本路径尚不清楚。

    Protocol: HTTP/1.1
    Host: localhost:8080
    Path: /hello
    

    我尝试的第二件事是在包级别定义 URL 并使用它来构建自定义解析函数。 url.URL 维护一个 URL 的结构表示;可以使用URL.parse(string) 解析相对(或绝对)路径并将其与现有的URL 合并。方便的是,URL 可以通过其 String() 方法输出其自身的字符串表示形式。

    自定义解析函数只保留包级别 URL 的副本,每次使用特定路径调用它时,它都会将新路径粘贴到 URL.Path 的末尾并返回一个新的 @ 987654332@ 除了新的连接路径外,其他都是相同的(因为这是 URL.parse() 在我们将相对路径传递给它时所做的事情)。然后可以在新 URL 上调用 URL.String() 以将 URL 字符串化为我们要编组的字符串。

    package main
    
    import (
        "github.com/emicklei/go-restful"
        "io"
        "net/http"
        "net/url"
        "fmt"
        "encoding/json"
    )
    
    var myurl = url.URL{
    Scheme:"http",
    Host: "localhost:8080",
    Path:"basepath",
    }
    
    var parse = getParseFn(myurl)
    
    func main() {
        ws := new(restful.WebService)
        ws.Route(ws.GET("/jsonUrls").To(jsonUrls))
        restful.Add(ws)
        http.ListenAndServe(":8080", nil)
    }
    
    func jsonUrls(req *restful.Request, resp *restful.Response) {
        urls := []string{}
        for _, s := range []string{"get", "put", "whatever"} {
            u, err := parse(s)
            if err != nil {
                fmt.Println(err)
            }
            urls = append(urls, u.String())
        }
        json_urls, err := json.Marshal(urls)
        if err != nil {
            fmt.Println(err)
        }
        io.WriteString(resp, string(json_urls))
    }
    
    func getParseFn (myUrl url.URL) func (string) (*url.URL, error) {
        parse := func (s string) (*url.URL, error) {
            u, err := myUrl.Parse(myUrl.Path + "/" + s)
            return u, err
        }
        return parse
    } 
    

    这会在浏览器中打印以下内容:

    ["http://localhost:8080/basepath/get","http://localhost:8080/basepath/put","http://localhost:8080/basepath/whatever"]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-02
      • 2019-04-08
      • 2012-04-28
      • 2015-03-11
      • 2016-07-05
      • 1970-01-01
      • 2011-05-13
      相关资源
      最近更新 更多