问题描述
这个问题之前可能已经被问过,但没有得到明确的回答.究竟如何在 Retrofit 请求的正文中发布原始的整个 JSON?
This question may have been asked before but no it was not definitively answered. How exactly does one post raw whole JSON inside the body of a Retrofit request?
查看类似问题此处.或者这个答案是否正确,它 必须是形式url 编码并作为字段传递?我真的不希望这样,因为我连接的服务只是在帖子正文中期待原始 JSON.它们未设置为查找 JSON 数据的特定字段.
See similar question here. Or is this answer correct that it must be form url encoded and passed as a field? I really hope not, as the services I am connecting to are just expecting raw JSON in the body of the post. They are not set up to look for a particular field for the JSON data.
我只想用 restperts 一劳永逸地澄清这一点.一个人回答不要使用 Retrofit.另一个不确定语法.另一个人认为可以,但前提是它的形式是 url 编码并放在一个字段中(这在我的情况下是不可接受的).不,我无法为我的 Android 客户端重新编码所有服务.是的,在主要项目中发布原始 JSON 而不是将 JSON 内容作为字段属性值传递是很常见的.让我们做对并继续前进.有人可以指出显示这是如何完成的文档或示例吗?或者提供一个可以/不应该做的正当理由.
I just want to clarify this with the restperts once and for all. One person answered not to use Retrofit. The other was not certain of the syntax. Another thinks yes it can be done but only if its form url-encoded and placed in a field (that's not acceptable in my case). No, I can't re-code all the services for my Android client. And yes, it's very common in major projects to post raw JSON instead of passing over JSON content as field property values. Let's get it right and move on. Can someone point to the documentation or example that shows how this is done? Or provide a valid reason why it can/should not be done.
更新:我可以 100% 确定地说一件事.您可以在 Google 的 Volley 中执行此操作.它是内置的.我们可以在 Retrofit 中做到这一点吗?
UPDATE: One thing I can say with 100% certainty. You CAN do this in Google's Volley. It's built right in. Can we do this in Retrofit?
推荐答案
@Body
注解定义了一个请求体.
The @Body
annotation defines a single request body.
interface Foo {
@POST("/jayson")
FooResponse postJson(@Body FooRequest body);
}
由于 Retrofit 默认使用 Gson,FooRequest
实例将被序列化为 JSON 作为请求的唯一主体.
Since Retrofit uses Gson by default, the FooRequest
instances will be serialized as JSON as the sole body of the request.
public class FooRequest {
final String foo;
final String bar;
FooRequest(String foo, String bar) {
this.foo = foo;
this.bar = bar;
}
}
调用方式:
FooResponse = foo.postJson(new FooRequest("kit", "kat"));
将产生以下正文:
{"foo":"kit","bar":"kat"}
Gson 文档有更多关于对象序列化如何工作的内容.
The Gson docs have much more on how object serialization works.
现在,如果您真的想自己发送原始"JSON 作为正文(但请使用 Gson!),您仍然可以使用 TypedInput
:
Now, if you really really want to send "raw" JSON as the body yourself (but please use Gson for this!) you still can using TypedInput
:
interface Foo {
@POST("/jayson")
FooResponse postRawJson(@Body TypedInput body);
}
TypedInput 被定义为具有相关的 MIME 类型.".有两种方法可以通过上述声明轻松发送原始数据:
TypedInput is a defined as "Binary data with an associated mime type.". There's two ways to easily send raw data with the above declaration:
使用 TypedByteArray 发送原始字节和JSON mime 类型:
Use TypedByteArray to send raw bytes and the JSON mime type:
String json = "{"foo":"kit","bar":"kat"}";
TypedInput in = new TypedByteArray("application/json", json.getBytes("UTF-8"));
FooResponse response = foo.postRawJson(in);
子类 TypedString 创建一个 TypedJsonString
类:
public class TypedJsonString extends TypedString {
public TypedJsonString(String body) {
super(body);
}
@Override public String mimeType() {
return "application/json";
}
}
然后使用类似于 #1 的该类的实例.
And then use an instance of that class similar to #1.
这篇关于如何在改造请求的正文中发布原始的整个 JSON?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!