使用Retrofit进行POST请求出现500错误

5

我用Postman发送以下Body数据返回的结果正常(以原始JSON格式):

{"payload":{"email":"","username":"","password":""}}

postman call

但是当我尝试通过Retrofit发送时,它不起作用(返回500错误):

public Observable<JsonObject> signup(String email, String userName, String password) {
    JsonObject data = new JsonObject();
    JsonObject payload = new JsonObject();

    data.addProperty("email", email);
    data.addProperty("username", userName);
    data.addProperty("password", password);
    payload.add("payload", data);

    return mShoutApiService.signup(payload);
}

以下是服务调用和适配器:

服务:

@POST("/signup")
Observable<JsonObject> signup(@Body JsonObject payload);

适配器:

private RestAdapter createRestAdapter(String hostUrl, GsonConverter gsonConverter, OkClient okClient) {
    return new RestAdapter.Builder()
            .setClient(okClient)
            .setConverter(gsonConverter)
            .setEndpoint(hostUrl)
            .setLogLevel(LogLevel.FULL)
            .setLog(new AndroidLog("SHOUT_LOG"))
            .build();
}

private GsonConverter getGsonConverter(Gson gson) {
    return new GsonConverter(gson);
}

private OkClient getOkClient() {
    OkHttpClient okHttpClient = new OkHttpClient();
    okHttpClient.setReadTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
    okHttpClient.setConnectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);

    return new OkClient(okHttpClient);
}

日志如下所示

03-23 05:04:00.380 2442-3468/shout.surge.com.shout D/SHOUT_LOG: --->       HTTP POST http://shout-api.herokuapp.com/signup
03-23 05:04:00.380 2442-3468/shout.surge.com.shout D/SHOUT_LOG: Content-Type: application/json; charset=UTF-8
03-23 05:04:00.380 2442-3468/shout.surge.com.shout D/SHOUT_LOG: Content-Length: 52
03-23 05:04:00.384 2442-3468/shout.surge.com.shout D/SHOUT_LOG: {"payload":{"email":"","username":"","password":""}}
03-23 05:04:00.384 2442-3468/shout.surge.com.shout D/SHOUT_LOG: ---> END HTTP (52-byte body)
03-23 05:04:09.180 2442-3468/shout.surge.com.shout D/SHOUT_LOG: <--- HTTP  500 http://shout-api.herokuapp.com/signup (8796ms)

看起来它们是完全相同的调用,但出现在我的移动应用程序中失败了。请问我错过了什么东西?任何见解都将是极好的!


500 是服务器端的错误。它很可能是由于客户端发送了错误请求或者服务器端实现有误所导致的。由于 Postman 可以正常工作,我认为您的 Retrofit 客户端可能会发送意外的请求。请使用 Postman 仔细检查请求。检查 URL - 结尾是否有 '/'?是 '/signup' 吗?检查您的实现中的基本 URL - 它们是否相同?头部是否相同?您可以在此处发布所有内容以获取进一步帮助。这些只是提示。 - Fred
因此,在返回日志中,看起来我得到了以下内容:03-22 02:16:20.326 2427-2661/shout.surge.com.shout D/SHOUT_LOG: Content-Type: text/html; charset=utf-8如果我使用@Header或使用TypedInput作为正文,这不会改变。 - 1tSurge
我猜那只是500响应的标头,通常是一个带有500错误消息的html页面。你能否在问题中更新restadapter定义,包括调用的完整日志(请求+响应),以及你在postman中拥有的任何内容(url + headers + body)。谢谢! - Fred
完成了!真希望能弄清楚这个。 - 1tSurge
1个回答

2
我查看了你的问题,正如我所猜测的那样,它确实与应用中调用和从Postman调用之间的差异有关。不幸的是,我无法向您解释为什么会发生这种情况,因为作为一个500错误,很可能是服务器端实现有误。
当我添加头部Accept: application/json时,我的问题得到了解决。
@Headers("Accept: application/json")
@POST("/signup")
Observable<JsonObject> signup(@Body JsonObject payload);

我注意到我正在使用的工具(Advanced REST Client for chrome)会在每个调用中添加该标头。当我删除此标头时,我得到了您遇到的500错误。您还可以使用Accept: */*,但我不确定这是否是一个好的做法。对于为什么会出现这种情况,我很抱歉我没有足够的信息告诉你,但是这对我解决了问题。我在Android应用程序中也尝试过它。

哇,这真的很奇怪!下班回家后我会试一试。不过你真是发现得太棒了! - 1tSurge

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接