Android - 无法使用 Retrofit 在变量名称中获取带破折号的整数

Android - Can't get integer with dash in variable name using Retrofit

我在我的 Android 应用程序中使用 Retrofit 来查询我的 aREST server,其中 returns:

{"return_value": 1, "id": "1", "name": "esp8266", "connected": true}

这是我的 Api 回复 POJO

ApiResponse.java

public class ApiResponse {

  private String id;
  private String name;
  private boolean connected;

  @SerializedName("return_value")
  private int returnValue;

  private boolean isReturnValueSet = false;

  public String getId() {
    return id;
  }

  ...

  public int getReturnValue() {
    return returnValue;
  }

  public void setReturnValue(int returnValue) {
    Log.v("ZetaRemote", "ApiResponse.setReturnValue");
    this.returnValue = returnValue;
    this.isReturnValueSet = true;
  }

  public String toString() {
    // {"id": "1", "name": "esp8266", "connected": true}
    String result;
    String base = "\"id\": \"" + id + "\", \"name\": \"" + name + "\", \"connected\": " + connected;

    String extra = null;
    if (message != null) result = "\"message\": " + message + " " + base;
    else if (isReturnValueSet) result = "\"return_value\": " + returnValue + " " + base;
    else result = base;

    return "{" + result + "}";
  }
}

我尝试使用 SerializedName 和 Log 查看是否触发了 setReturnValue 但没有。

这是启用了改造调试消息的 pidcat 日志:

D  Command image clicked
D  ApiClient.setServer(192.168.1.20)
D  ApiClient.getMyApiClient
D  ---> HTTP GET http://192.168.1.20/led?params=750
D  ---> END HTTP (no body)
D  <--- HTTP 200 http://192.168.1.20/led?params=750 (215ms)
D  Access-Control-Allow-Origin: *
D  Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS
D  Content-Type: application/json
D  Connection: close
D  OkHttp-Selected-Protocol: http/1.1
D  OkHttp-Sent-Millis: 1443122723645
D  OkHttp-Received-Millis: 1443122723754
D  {"return_value": 1, "id": "1", "name": "esp8266", "connected": true}
D  <--- END HTTP (70-byte body)
D  Success, response: {"id": "1", "name": "esp8266", "connected": true}

我应该改变什么才能成功获得return_value

感谢iagreen的解答

ApiResponse.java

public class ApiResponse {

  private String id;
  private String name;
  private boolean connected;

  private String message;

  @SerializedName("return_value")
  private Integer returnValue;

  public String getId() {
    return id;
  }

  ...

  public Integer getReturnValue() {
    return returnValue;
  }

  public void setReturnValue(Integer returnValue) {
    this.returnValue = returnValue;
  }

  public String toString() {
    // {"id": "1", "name": "esp8266", "connected": true}
    String result;
    String base = "\"id\": \"" + id + "\", \"name\": \"" + name + "\", \"connected\": " + connected;

    String extra = null;
    if (message != null) result = "\"message\": " + message + ", " + base;
    else if (returnValue != null) result = "\"return_value\": " + returnValue + ", " + base;
    else result = base;

    return "{" + result + "}";
  }
}

正如 iagreen 指出的那样,我只是将 return_value 隐藏在我写得不好的 toString() 方法中。使用 Integer 而不是 int 允许我检查它是否存在并因此正确构建我的 toString() 方法。

谢谢StringBuilder的建议,我去看看

Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
    .create();

这可能会有所帮助。创建客户端时使用它。

Gson 使用反射来设置 POJO 的值,而不是 setter。无论成员 returnValue 是否从数据中反序列化,您的 setReturnValue 都不会被调用。看起来您的代码正在运行,您只是将 return 值隐藏在 toString 方法中。尝试通过始终显示 returnValue --

来简化它
String base = "\"id\": \"" + id + "\", \"name\": \"" + name + "\", \"connected\": " + connected;

if (message != null) result = "\"message\": " + message + " " + base;
String result = "\"return_value\": " + returnValue + " " + base;

return "{" + result + "}";

然后看看它是否没有出现在日志中。如果您需要知道它是否存在于响应中,您可以将其类型更改为 Integer,如果它不存在于 JSON.

中,则允许 null

顺便说一句,应该考虑使用 StringBuilder 来构建这样的 String,但不想通过上述方式混淆问题。