实现思路:我们接收前端的请求数据时,经过分发组件分发到各个服务,所以如果我们在分发组件中实现过滤器,就不需要在各个服务中再进行验证。在分发中进行拦截判断是否为合法请求。
分发的实现详见https://blog.dtse.ha.cn/index.php/2019/11/06/1033.html
而过滤器是在接受前端传递过来的所有请求之后,在获取url来分辨所想请求的具体服务之前,读取Body获得key和value进行过滤判断。如果成功进行服务转发,失败则返回状态码和信息。实现起来不难,主要是对golang的 interface进行使用。但如果不太熟悉还是会走一些弯路,以下是实现功能时遇到的一些问题。
接收前端json数据进行类型断言
rebody, _ := ioutil.ReadAll(r.Body)
//json类型断言获得过滤参数
var filter interface{}
err := json.Unmarshal(rebody, &filter)
if err != nil {
fmt.Println("jsonstr error:", err)
}
得到一个map集合,我们需要从map集合中获得key和value
//打印filter
map[key:1815925214 password:123456 stu_sno:1815925214 value:36cc8d561f2b3b36a4fb08b33a528489167631a5]
key := filter["key"]
value := filter["value"]
报了以下错误:
# yiyu/Share
invalid operation: filter["key"] (type interface {} does not support indexing)
invalid operation: filter["value"] (type interface {} does not support indexing)
这里的数据类型是关键,filter的打印虽然确实是map类型的数据,但它实际上并不是map,而是interface{},它可以是任何东西,一个地图,一个字符串等等,我们要把interface{}转为map
filtermap, _ := filter.(map[string]interface{})
调试继续报错
# yiyu/Share
cannot use key (type interface {}) as type string in argument to FilterJudge: need type assertion
cannot use value (type interface {}) as type string in argument to FilterJudge: need type assertion
和上个报错类似,原来是我们需要的是string类型,interface{}并不是string类型,需要将interface{}类型转化为string类型
// json类型断言获得过滤参数
var filter interface{}
err := json.Unmarshal(rebody, &filter)
if err != nil {
fmt.Println("jsonstr error:", err)
}
// 将interface{}转为map
filtermap, _ := filter.(map[string]interface{})
// 将interface{}转为string
key := filtermap["key"].(string)
value := filtermap["value"].(string)
if FilterJudge(key, value) == 0 {
//failed
ReturnFunction(201, "failure", w)
return
}
注意
看到这里有很多小伙伴要有疑问了,既然要先把interface{}转为map[string]interface{},再把map[string]interface{}中的interface{}转为string,为何不直接把string转为map[string]string呢,实际上这样是不行的,打印出的key,value是空值。