在POST
和PUT
等请求方法中,通常使用 HTTP 请求体进行传输数据。在 Forest 中有多种方式设置请求体数据。
@Body 注解#
您可以使用@Body
注解修饰参数的方式,将传入参数的数据绑定到 HTTP 请求体中。
@Body
注解修饰的参数一定会绑定到请求体中,不用担心它会出现在其他地方
@Post(
url = "http://localhost:8080/user",
headers = {"Accept:text/plain"}
)
String sendPost(@Body("username") String username, @Body("password") String password);
表单格式#
上面使用 @Body 注解的例子用的是普通的表单格式,也就是contentType
属性为application/x-www-form-urlencoded
的格式,即contentType
不做配置时的默认值。
表单格式的请求体以字符串 key1=value1&key2=value2&...&key{n}=value{n}
的形式进行传输数据,其中value
都是已经过 URL Encode 编码过的字符串。
@Post(
url = "http://localhost:8080/user",
contentType = "application/x-www-form-urlencoded",
headers = {"Accept:text/plain"}
)
String sendPost(@Body("key1") String value1, @Body("key2") Integer value2, @Body("key3") Long value3);
调用后产生的结果可能如下:
POST http://localhost:8080/hello/user
HEADER:
Content-Type: application/json
BODY:
key1=xxx&key2=1000&key3=9999
当@Body
注解修饰的参数为一个对象,并注解的value
属性不设置任何名称的时候,会将注解所修饰参数值对象视为一整个表单,其对象中的所有属性将按 属性名1=属性值1&属性名2=属性值2&...&属性名{n}=属性值{n}
的形式通过请求体进行传输数据。
@Post(
url = "http://localhost:8080/hello/user",
headers = {"Accept:text/plain"}
)
String send(@Body User user);
调用后产生的结果如下:
POST http://localhost:8080/hello/user
HEADER:
Content-Type: application/json
BODY:
username=foo&password=bar
JSON格式: @JSONBody注解修饰对象#
发送JSON非常简单,只要用@JSONBody
注解修饰相关参数就可以了,该注解自1.5.0-RC1
版本起可以使用。
使用@JSONBody注解的同时就可以省略 contentType = "application/json"属性设置。
@Post("http://localhost:8080/hello/user")
String helloUser(@JSONBody User user);
调用后产生的结果如下:
POST http://localhost:8080/hello/user
HEADER:
Content-Type: application/json
BODY:
{"username": "foo", "password": "bar"}
JSON格式: @JSONBody注解修饰键值对#
@JSONBody注解可以按键值对拆分成多个参数进行传入,在发送的时候再合成一个完成的JSON字符串:
@Post("http://localhost:8080/hello/user")
String helloUser(@JSONBody("username") String username, @JSONBody("password") String password);
如调用helloUser("foo", "bar");
会产生如下结果:
POST http://localhost:8080/hello/user
HEADER:
Content-Type: application/json
BODY:
{"username": "foo", "password": "bar"}
JSON格式: @JSONBody注解修饰集合对象#
@JSONBody注解也支持Map、List等集合类型参数
@Post(url = "http://localhost:8080/hello/user")
String helloUser(@JSONBody Map<String, Object> user);
若调用代码如下:
Map<String, Object> map = new HashMap<>();
map.put("name", "foo");
map.put("password", "bar");
client.helloUser(map);
会产生如下结果:
POST http://localhost:8080/hello/user
HEADER:
Content-Type: application/json
BODY:
{"username": "foo", "password": "bar"}
List等聊表对象也同理:
@Post(url = "http://localhost:8080/hello/user-names")
String helloUserNames(@JSONBody List<String> usernames);
若调用代码如下:
List<String> names = Lists.newArrayList("A", "B", "C");
client.helloUserNames(names);
会产生如下结果:
POST http://localhost:8080/hello/user
HEADER:
Content-Type: application/json
BODY:
["A", "B", "C"]
JSON格式: @JSONBody注解修饰字符串#
@JSONBody注解还支持字符串类型参数,可以直接传入一个JSON字符串进行传输
@Post("http://localhost:8080/hello/user")
String helloUser(@JSONBody String userJson);
JSON格式: @Body注解 + contentType#
除了@JSONBody
注解,使用@Body
注解也可以,只要将contentType
属性或Content-Type
请求头指定为application/json
便可。
@Post(
url = "http://localhost:8080/hello/user",
contentType = "application/json"
)
String send(@Body User user);
调用后产生的结果如下:
POST http://localhost:8080/hello/user
HEADER:
Content-Type: application/json
BODY:
{"username": "foo", "password": "bar"}
XML格式: @XMLBody注解修饰对象#
发送XML也非常简单,只要用@XMLBody
注解修饰相关参数就可以了,该注解自1.5.0-RC1
版本起可以使用。
@Post("http://localhost:8080/hello/user")
String sendXmlMessage(@XMLBody User user);
要注意的是,这里的User
对象要绑定JAXB
注解:
@XmlRootElement(name = "misc")
public User {
private String usrname;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
调用传入User
对象后的结果如下:
POST http://localhost:8080/hello/user
HEADER:
Content-Type: application/xml
BODY:
<misc><username>foo</username><password>bar</password></misc>
XML格式: @XMLBody注解修饰字符串#
@XMLBody支持的另一种形式就是直接传入一个XML字符串
@Post("http://localhost:8080/hello/user")
String sendXmlMessage(@XMLBody String userXml);
XML格式: @Body注解 + contentType + filter#
使用@Body
注解发送XML数据较为特殊,除了指定contentType
属性或Content-Type
请求头为application/xml
外,还需要设置@Body
的filter
属性为xml
。
@Post(
url = "http://localhost:8080/hello/user",
contentType = "application/xml"
)
String send(@Body(filter = "xml") User user);
调用传入User
对象后的结果如下:
POST http://localhost:8080/hello/user
HEADER:
Content-Type: application/xml
BODY:
<misc><username>foo</username><password>bar</password></misc>
data 属性#
您也可以通过@Request
、以及@Get
、@Post
等请求注解的data
属性把数据添加到请求体。需要注意的是只有当type
为POST
、PUT
、PATCH
这类 HTTP Method 时,data
属性中的值才会绑定到请求体中,而GET
请求在有些情况会绑定到url
的参数中。
具体type
属性和data
属性数据绑定位置的具体关系如下表:
type | data 属性数据绑定位置 | 支持的contentType 或Content-Type 请求头 |
---|
GET | url 参数部分 | 只有application/x-www-form-urlencoded |
POST | 请求体 | 任何contentType |
PUT | 请求体 | 任何contentType |
PATCH | 请求体 | 任何contentType |
HEAD | url 参数部分 | 只有application/x-www-form-urlencoded |
OPTIONS | url 参数部分 | 只有application/x-www-form-urlencoded |
DELETE | url 参数部分 | 只有application/x-www-form-urlencoded |
TRACE | url 参数部分 | 只有application/x-www-form-urlencoded |
data
属性在POST
请求中绑定请求体
public interface MyClient {
@Request(
url = "http://localhost:8080/hello/user",
type = "post",
data = "username=foo&password=bar",
headers = {"Accept:text/plain"}
)
String dataPost();
}
该接口调用后所实际产生的 HTTP 请求如下:
POST http://localhost:8080/hello/user
HEADER:
Accept:text/plain
BODY:
username=foo&password=bar
在data
属性中进行数据绑定:
public interface MyClient {
@Request(
url = "http://localhost:8080/hello/user",
type = "post",
data = "username=${0}&password=${1}",
headers = {"Accept:text/plain"}
)
String dataPost(String username, String password);
}
如果调用方代码如下所示:
myClient.dataPost("foo", "bar");
实际产生的 HTTP 请求如下:
POST http://localhost:8080/hello/user
HEADER:
Accept: text/plain
BODY:
username=foo&password=bar
您可以直接把 JSON 数据加入到请求体中,其中header
设置为Content-Type: application/json
public interface MyClient {
@Request(
url = "http://localhost:8080/hello/user",
type = "post",
data = "{\"username\": \"${0}\", \"password\": \"${1}\"}",
headers = {"Content-Type: application/json"}
)
String postJson(String username, String password);
}
如果调用方代码如下所示:
myClient.postJson("foo", "bar");
实际产生的 HTTP 请求如下:
POST http://localhost:8080/hello/user
HEADER:
Content-Type: application/json
BODY:
{"username": "foo", "password": "bar"}
把 XML 数据加入到请求体中,其中header
设置为Content-Type: application/json
public interface MyClient {
@Request(
url = "http://localhost:8080/hello/user",
type = "post",
data = "<misc><username>${0}</username><password>${1}</password></misc>",
headers = {"Content-Type: application/xml"}
)
String postXml(String username, String password);
}
如果调用方代码如下所示:
myClient.postXml("foo", "bar");
实际产生的 HTTP 请求如下:
POST http://localhost:8080/hello/user
HEADER:
Content-Type: application/xml
BODY:
<misc><username>foo</username><password>bar</password></misc>