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

时间:2015-09-24 19:35:10

标签: android json retrofit

我在我的Android应用中使用Retrofit来查询我的aREST server,它返回:

{"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的建议,我会看看它。

2 个答案:

答案 0 :(得分:1)

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

这可能会有所帮助。在创建客户端时使用此选项。

答案 1 :(得分:1)

Gson使用反射来设置POJO的值,而不是setter。无论成员setReturnValue是否从数据中反序列化,都不会调用returnValue。看起来您的代码正常工作,而您只是隐藏了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来构建{{1}}这样的内容,但不想通过上述方式混淆问题。