如何在 Retrofit 请求的正文中发布原始的整个 JSON? [英] How to POST raw whole JSON in the body of a Retrofit request?

查看:38
本文介绍了如何在 Retrofit 请求的正文中发布原始的整个 JSON?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题以前可能有人问过,但没有得到明确的回答.如何在 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:

  1. 使用 TypedByteArray 发送原始字节和JSON MIME 类型:

  1. 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.

    这篇关于如何在 Retrofit 请求的正文中发布原始的整个 JSON?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆