【问题标题】:POST request to REST API with JSON object as payload使用 JSON 对象作为有效负载向 REST API 发送 POST 请求
【发布时间】:2015-05-07 11:32:54
【问题描述】:

我正在尝试使用具有 JSON 有效负载的 POST 请求从 REST API 获取 JSON 响应(在发送之前应转换为 URL 编码文本)。我已经按照一些教程来实现该过程,但我收到状态码 400 的错误。我可能没有对给定的 JSON 字符串进行编码或遗漏了某些内容。请帮我解决这个问题。谢谢。

这是我的代码

    try {
        URL url = new URL("https://appem.totango.com/api/v1/search/accounts/health_dist");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestProperty("app-token", "1a1c626e8cdca0a80ae61b73ee0a1909941ab3d7mobile+testme@totango.com");
        conn.setRequestProperty("Accept", "application/json, text/javascript, */*; q=0.01");
        conn.setRequestProperty("X-Requested-With","XMLHttpRequest");

        String payload = "{\"terms\":[{\"type\":\"totango_user_scope\",\"is_one_of\":[\"mobile+testme@totango.com\"]}],\"group_fields\":[{\"type\":\"health\"}]}";

        OutputStream os = conn.getOutputStream();
        os.write(payload.getBytes());
        os.flush();

        if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
            throw new RuntimeException("Failed : HTTP error code : "
                    + conn.getResponseCode());
        }

        BufferedReader br = new BufferedReader(new InputStreamReader(
                (conn.getInputStream())));

        String output;
        System.out.println("Output from Server .... \n");
        while ((output = br.readLine()) != null) {
            System.out.println(output);
        }
        conn.disconnect();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

【问题讨论】:

  • 您是否收到了响应正文以及 400 状态码?
  • @Dan675 不,只是状态码。
  • 你没有在你的 os.flush() 之后调用 conn.connect(),我认为这可能是问题
  • @faljbour 添加了 conn.connect() 但仍然是相同的异常。
  • 我刚试过你的代码,如果我删除 conn.RequestProperty("app-token",我得到一个错误 401 Unauthorized,但是当我把它放回去时,我得到了 400 错误的错误request.所以它与app-token有关

标签: java json rest http-post


【解决方案1】:

在关注许多帖子和教程超过 24 小时后,我知道我没有正确发送我的 URL 参数。而且我还了解到使用 ApacheHttpClient 的 REST API 调用相对容易。我解决了我的 HTTP 错误代码 400 并从服务器获得了响应。这是我的问题的工作代码。

        try {
            httpClient = HttpClients.createDefault();
            httpPost = new HttpPost("https://appem.totango.com/api/v1/search/accounts/health_dist");

            List<NameValuePair> headers = new ArrayList<NameValuePair>(); //ArrayList to store header parameters
            List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); //ArrayList to store URL parameters

            urlParameters.add(new BasicNameValuePair("query","{\"terms\":[{\"type\":\"totango_user_scope\",\"is_one_of\":[\"mobile+testme@totango.com\"]}],\"group_fields\":[{\"type\":\"health\"}]}"));
            headers.add(new BasicNameValuePair("app-token", "1a1c626e8cdca0a80ae61b73ee0a1909941ab3d7mobile+testme@totango.com"));
            headers.add(new BasicNameValuePair("Accept", "application/json, text/javascript, */*; q=0.01"));
            headers.add(new BasicNameValuePair("X-Requested-With", "XMLHttpRequest"));
            httpPost.setEntity(new UrlEncodedFormEntity(urlParameters));

            for (NameValuePair h : headers)
            {
                httpPost.addHeader(h.getName(), h.getValue());
            }

            response = httpClient.execute(httpPost);

            if (response.getStatusLine().getStatusCode() != 200) {
                throw new RuntimeException("Failed : HTTP error code : "
                        + response.getStatusLine().getStatusCode());
            }

            BufferedReader br = new BufferedReader(new InputStreamReader(
                    (response.getEntity().getContent())));

            String output;
            System.out.println("Output from Server .... \n");
            while ((output = br.readLine()) != null) {
                System.out.println(output);
            }
        } catch (MalformedURLException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        } finally {
            try{
                response.close();
                httpClient.close();
            }catch(Exception ex) {
                ex.printStackTrace();
            }
        }

【讨论】:

    【解决方案2】:

    您正在调用的 API 需要一个名为“query=true|false”的查询参数。

    URL url = new URL("https://appem.totango.com/api/v1/search/accounts/health_dist?query=true");
    

    添加此参数后,HTTP 请求本身成功,状态码为 200,但 REST 调用失败,并出现一些服务器端错误。也许您需要不同的有效载荷。

    如果您是 REST 新手,我建议您尝试使用像 POSTMan 这样的 REST 客户端

    【讨论】:

    • 我可以使用 Postman 得到响应。我没有收到任何服务器端错误。
    • 我收到了这个:"status": "Server error", "detailed_error": "com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class com.saaspulse.web.api.search.EntityGroupForm] from Boolean value; no single-boolean/Boolean-arg constructor/factory method"
    • 即使我通过在我的代码中添加你的答案得到了这个错误,但如果我使用 Postman,我会得到响应(JSON 对象)。
    • 您正在为除已创建之外的所有 HTTP 代码引发异常。您需要将条件更改为conn.getResponseCode() != HttpURLConnection.HTTP_OK。此外,如果您认为您的原始问题已得到解答,请随时接受答案。
    猜你喜欢
    • 2015-07-05
    • 2019-03-29
    • 2020-03-30
    • 1970-01-01
    • 2019-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多