改造 POST 包含空主体

Retrofit POST contains null body

我正在设置一个带有改造的 api 客户端,到目前为止 GET 工作正常,但我正在尝试创建一个带有 POST 的新对象,而不是对象作为 json 发送,请求正文仅包含字符串 "null":

---> HTTP POST http://myapiurl
Content-Type: application/json; charset=UTF-8
Content-Length: 4
null
---> END HTTP (4-byte body)

这是我要调用的方法:

@POST("/Monsters/")
Response new_monster(@Body Monster mon);

我是这样称呼它的:

@Test
public void testNew_monster() throws Exception {
    //create a new monster object, and pass it to the function,
    //then query and verify it's in the results?
    Monster newmon = new Monster() {
        {
            name = "deleteme";
            description = "created by junit test testNew_monster";
            image_url = "http://i.imgur.com/";
            created_by = "";
            encoded_key = "";
        }
    };

    Response r = client.new_monster(newmon);
    assertEquals(201, r.getStatus());
    //sleep a couple seconds here?

    List<Monster> monsterList = client.monsters();
    assertTrue(monsterList.contains(newmon));
}

我猜当使用 GSON 将对象序列化为 json 时出现问题,但在序列化过程中我看不到任何对调试器有帮助的信息...

我使用的是 GSON 2.3.1 版

编辑:这是我构建 RestAdapter 和客户端的方式:

static MonSpottingApi GetClient(boolean dbg)
{
    RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint(API_URL)
            .build();

    if (dbg) restAdapter.setLogLevel(RestAdapter.LogLevel.FULL);

    MonSpottingApi client = restAdapter.create(MonSpottingApi.class);

    return client;
}

在测试用例中class:

MonSightingClient.MonSpottingApi client;

@Before
public void setUp() throws Exception {
    client = MonSightingClient.GetClient(true);
}

您必须将接口 class 传递给 Restadaptercreate() 方法。假设您的接口 class 是 INewService(您声明 new_monster 的地方),那么 GetClient 应该如下所示:

public static INewService GetClient(boolean dbg){

    RestAdapter restAdapter = new RestAdapter.Builder().
    .setEndpoint(API_URL).
    .setClient(new OkClient(new OkHttpClient()))
    .build();

    if (dbg) restAdapter.setLogLevel(RestAdapter.LogLevel.FULL);

    return restAdapter.create(INewService.class);
}

我怀疑根本原因是 Gson,所以我开始进行非常简单的测试并尝试使用 toJson() 使对象正确序列化。我想我在 Gson 中发现了一个错误,如果使用双括号语法初始化对象,它将失败:

使用示例 class 找到 here

public class GitHubTest {

    //fails
    @Test
    public void testGson1() throws Exception {
        GitHubClient.Contributor contrib = new GitHubClient.Contributor() {
            {
                login = "someguy";
                contributions = 99;
            }
        };
        Gson gson = new Gson();
        String json = gson.toJson(contrib);
        System.out.println("contents of json string: " + json);
        assertNotEquals(json, "null");
    }

    //passes
    @Test
    public void testGson2() throws Exception {
        GitHubClient.Contributor contrib = new GitHubClient.Contributor();
        contrib.contributions = 99;
        contrib.login = "someguy";
        Gson gson = new Gson();
        String json = gson.toJson(contrib);
        System.out.println("contents of json string: " + json);
        assertNotEquals(json, "null");
    }
}

这是 Gson 中的错误吗?还是有一些奇怪的微妙 Java 原因导致了这种情况的发生? (Java不是我最擅长的语言)。

我遇到了同样的问题,看起来 Gson 对要转换的对象的双括号初始化不满意。

正在替换双括号初始化...

 AuthenticationRequest req = new AuthenticationRequest() {{
     setName("myName"); 
     setPassword("myPass");
 }}

与...

AuthenticationRequest req = new AuthenticationRequest();
req.setUserId("myName");
req.setPassword("myPass");

...成功了。