OkHttp:一个简单的GET请求:response.body()。string()返回json内部无法读取的转义unicode符号,无法转换为gson

问题描述 投票:1回答:1

在邮递员中发送请求时,得到以下输出:

{
    "valid": false,
    "reason": "taken",
    "msg": "Username has already been taken",
    "desc": "That username has been taken. Please choose another."
}

但是,当使用okhttp进行编码时,出现编码问题,无法使用gson将生成的json字符串转换为Java对象。

我有此代码:

public static void main(String[] args) throws Exception {
        TwitterChecker checker = new TwitterChecker();
        TwitterJson twitterJson = checker.checkUsername("dogster");
        System.out.println(twitterJson.getValid());  //NPE
        System.out.println(twitterJson.getReason());
        System.out.println("Done");
    }

    public TwitterJson checkUsername(String username) throws Exception  {
        HttpUrl.Builder urlBuilder = HttpUrl.parse("https://twitter.com/users/username_available").newBuilder();
        urlBuilder.addQueryParameter("username", username);
        String url = urlBuilder.build().toString();

        Request request = new Request.Builder()
                .url(url)
                .addHeader("Content-Type", "application/json; charset=utf-8")

                .build();


        OkHttpClient client = new OkHttpClient();
        Call call = client.newCall(request);
        Response response = call.execute();
        System.out.println(response.body().string());

        Gson gson = new Gson();
        return gson.fromJson(
                response.body().string(), new TypeToken<TwitterJson>() {
                }.getType());

    }

哪个打印此:

{"valid":false,"reason":"taken","msg":"\u0414\u0430\u043d\u043d\u043e\u0435 \u0438\u043c\u044f \u0443\u0436\u0435 \u0437\u0430\u043d\u044f\u0442\u043e","desc":"\u0414\u0430\u043d\u043d\u043e\u0435 \u0438\u043c\u044f \u0443\u0436\u0435 \u0437\u0430\u043d\u044f\u0442\u043e. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0435."}

,然后在尝试访问NullPointerException时抛出twitterJson。调试器将该对象显示为null

TwitterJson

@Generated("net.hexar.json2pojo")
@SuppressWarnings("unused")
public class TwitterJson {
    @Expose
    private String desc;
    @Expose
    private String msg;
    @Expose
    private String reason;
    @Expose
    private Boolean valid;

    public String getDesc() {
        return desc;
    }

    public String getMsg() {
        return msg;
    }

    public String getReason() {
        return reason;
    }

    public Boolean getValid() {
        return valid;
    }

    ...

如何解决okhttp的编码问题?

java unicode character-encoding gson okhttp
1个回答
1
投票

这是因为响应对象只能使用一次。 OKHTTP在他们的documentation中说。调用execute之后,您将两次调用响应对象。将response.body()。string()的结果存储到变量中,然后将其转换为GSON。

如果我要使用一个hello world示例...

private void testOkHttpClient() {
    OkHttpClient httpClient = new OkHttpClient();
    try {
      Request request = new Request.Builder()
          .url("https://www.google.com")
          .build();
      Call call = httpClient.newCall(request);
      Response response = call.execute();
      System.out.println("First time " + response.body().string()); // I get the response
      System.out.println("Second time " + response.body().string()); // This will be empty
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

之所以第二次为空,是因为响应对象只能使用一次。所以你要么

按原样返回响应。不要做sysOut

System.out.println(response.body().string()); // Instead of doing a sysOut return the value.

将响应的值存储到JSON,然后将其转换为GSON,然后返回值。

EDIT:关于Unicode字符。事实证明,由于我所在的地区不是一个讲英语的国家,所以我接受的json也不是英语。我添加了此标题:

.addHeader("Accept-Language", Locale.US.getLanguage())

关于解决该问题的请求。

© www.soinside.com 2019 - 2024. All rights reserved.