🍬 Hello World
# 模板表达式
在@Request
的各大属性中大多数都是用String
字符串填值的,如果要在这些字符串属性中动态地关联参数数据,用Java原生字符串连接(如+
)是不行的,而且也不够直观。
所以Forest为了帮助您参数数据动态绑定到这些属性上,提供了模板表达式。
# 表达式Hello World
Forest的模板表达式是在普通的Java字符串中嵌入{表达式}
来实现字符串和数据的动态绑定。
嵌入的表达式由左花括号{
开始,到右花括号}
结束,在两边花括号中间填写的内容是表达式的本体。
最简单的表达式可以是一个@Var
标注的变量名,或是一个全局配置中定义的全局变量名。
让我们来看一个最简单的模板表达式Hello World的例子吧
@Request(url = "http://localhost:8080/hello/{name}")
String send(@Var("name") String name);
2
若在调用send
方法时传入参数为"world"
,那么这时被表达式绑定url
属性则会变成:
http://localhost:8080/hello/world
也可以嵌入${表达式}
这种以美元符号($
)开始,再由左花括号{
开始,到右花括号}
结束的字符串模板形式
@Request(url = "http://localhost:8080/hello/${name}")
String send(@Var("name") String name);
2
调用后效果和上面例子一样
# {表达式} 与 ${表达式}
# {表达式}
代表一个Query参数
{表达式}
模板参数,在?a={a}
的情况下,会被认为是一个Query参数,即便变量可能包含"1&x=10&y=20"这样多个参数的字符串,也会被转义成一个Query参数
@Get("http://localhost/data?a={a}&b={b}")
String getData(@Var("a") String a, @Var("b") String b)
2
// 最终产生的URL是
// http://localhost/data?a=1%26x%3D10%26y%3D20&b=hello
// 也就是只会有 a 和 b 两个Query参数
myClient.getData("1&x=10&y=20", "hello");
2
3
4
# ${表达式}
可以包含多个Query参数
而 ${表达式}
模板参数,可以认为是一种字符串替换,替换完再对URL参数进行解析,所以一个模板参数引用的变量中可能包含多个参数,也会被解析成多个参数
@Get("http://localhost/data?a=${a}&b=${b}")
String getData(@Var("a") String a, @Var("b") String b)
2
// 最终产生的URL是
// http://localhost/data?a=1&x=10&y=20&b=hello
// 也就是只会有 a、x、y、b 四个Query参数
myClient.getData("1&x=10&y=20", "hello");
2
3
4
# 推荐使用{表达式}
作为模板参数
基于这两种模板参数各自的特性,都各有各的用处,但一般情况下,推荐使用{表达式}
因为它更结构化、更语义化,也更容易让人理解,不容易出错,尤其是在URL参数中传递另一个URL地址时的作用更为突出
比如,要传一个带参数的子URL:https://search.gitee.com/?type=repository&q=forest
接到父URL后为 http://localhost/data?call={url}
如果是用${url}
就会出问题
@Get("/data?call=${url}")
String getData(@Var("url") String url);
// 最后产生的URL是
// http://localhost/data?call=https://search.gitee.com/?type=repository&q=forest
2
3
4
5
咋看起来没错,但最后那部分&q=forest
会被认为是父URL的Query参数,但其实应该是子URL的
如果用 {url}
就没这个问题,即使后来再有其它参数也毫无问题
@Get("/data?call={url}&x={x}")
String getData(@Var("url") String url, @Var("x") String x);
// 最后产生的URL是
// http://localhost/data?call=https://search.gitee.com/?type=repository%26q=forest&x=xxx
2
3
4
5
可以看到,子URL中Query参数的连接符&
被转义了,这样就解决了子URL参数和父URL参数(如后面的x
)之间产生的歧义