Exercise Requirement

Go语言的语法及基本概念

包net/http的一些基本函数其含义和功能

一些JSON,YAML,TOML等格式数据的序列化和反序列化

命令行的参数处理

External Package

Exercise Goal

通过实现http.Handler接口完成将请求重定向到键值对应的URL,比如JSON数据:
[
    {
        "path": "http",
        "url": "https://marcoepsilon.site/golib/net/http/",
    },
    {
        "path": "os",
        "url": "https://marcoepsilon.site/golib/sort/"
    }
]

通过读取JSON数据增加http.Handler,在用户输入”localhost:port/path”时,能够重定向到JSON数据path对应的url

Exercise Details

在实现时我们要解决可能来自用户输入,指定文件,JSON,YAML,TOML等格式数据来源能够被统一处理,比如所有的输入数据可以被统一为Go中的map[string]string,然后将其重定向到请求中URL的Path映射的URL,如果未发现映射,默认用http.NotFound处理,我们可以很快速的写出处理map[string]string的原型
type Source map[string]string
func MapHandler(source Source) http.HandlerFunc {
	return http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			if url, ok := source[strings.TrimPrefix(r.URL.Path, "/")]; ok {
				http.Redirect(w, r, url, http.StatusFound)
			} else {
				http.NotFound(w, r)
			}
		},
	)
}

这样对于YAML,JSON等数据类型我们只需要写出其解析的函数和将其转化为MapHandler处理即可

/*
    import (
        yaml "gopkg.in/yaml.v2"
    )
*/
func parseYAMLToSource(data []byte) (Source, error) {
	type pathUrl struct {
		Path string `yaml:"path"`
		URL string	`yaml:"url"`
	}
	var pathUrls []pathUrl
	err := yaml.Unmarshal(data, &pathUrls)
	if err != nil {
		return nil, err
	}
	source := make(map[string]string)
	for _, value := range pathUrls {
		source[value.Path] = value.URL
	}
	return source, nil
}
func YAMLHandler(data []byte) http.HandlerFunc {
	source, err := parseYAMLToSource(data)
	if err != nil {
		log.Fatalf("Reason: %s", err.Error())
	}
	return MapHandler(source)
}
完整代码