【问题标题】:Retrofit POST contains null body改造 POST 包含空正文
【发布时间】:2015-03-06 10:20:09
【问题描述】:

我正在设置一个带有改造的 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;
}

在测试用例类中:

MonSightingClient.MonSpottingApi client;

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

【问题讨论】:

  • 如何为客户端界面构建RestAdapter
  • @EfeKahraman 我在问题中添加了更多代码以显示这一点。
  • 我认为您可能在 Builder 中遗漏了一些方法调用。检查the RestAdapter.Builder documentation,它说你应该添加setEndpoint(Endpoint)setClient(Client.Provider)setConverter(Converter)

标签: java rest retrofit


【解决方案1】:

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

使用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 不知道如何序列化这个子类,因为它的类型不同(GitHubClient.Contributor$1 而不是 GitHubClient.Contributor)。
  • @TomG 好的,这是有道理的。谢谢你的解释!
【解决方案2】:

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

替换双括号初始化...

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

与...

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

...成功了。

【讨论】:

    【解决方案3】:

    您必须将您的接口类传递给Restadaptercreate() 方法。假设你的接口类是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);
    }
    

    【讨论】:

    • 除了名称等细微差别(我的界面称为 MonSpottingApi),我看不出这与我已经在做的有什么不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-16
    • 2017-08-07
    • 2019-03-24
    • 1970-01-01
    相关资源
    最近更新 更多