Java:如何使用数据进行 API 调用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46233770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 09:08:01  来源:igfitidea点击:

Java: How to make API call with data?

javarestapihttprequest

提问by RajSharma

I want to make API call similar to below curl command:

我想进行类似于以下 curl 命令的 API 调用:

curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer 
1djCb/mXV+KtryMxr6i1bXw" 
-d '{"operands":[]}' 
https://ads.line.me/api/v1.0/authority_delegations/get

What I am trying

我在尝试什么

public void send_deligation_request(String details[]) throws Exception{
    System.out.println(Arrays.toString(details));

    URL line_api_url = new URL("https://ads.line.me/api/v1.0/authority_delegations/get");
    String payload = "{operands:[]}";



    HttpURLConnection linec = (HttpURLConnection)line_api_url.openConnection();
    linec.setDoInput(true);
    linec.setDoOutput(true);
    linec.setRequestMethod("POST");
    linec.setRequestProperty("Content-Type", "application/json");
    linec.setRequestProperty("Authorization", "Bearer "+access_token);

    OutputStreamWriter writer = new OutputStreamWriter(linec.getOutputStream(), "UTF-8");
    writer.write(payload);


    BufferedReader in = new BufferedReader(
                            new InputStreamReader(
                                    linec.getInputStream()));
    String inputLine;

    while ((inputLine = in.readLine()) != null) 
        System.out.println(inputLine);
    in.close();
}

But I am getting below error:

但我收到以下错误:

[[email protected], 5514]
java.io.IOException: Server returned HTTP response code: 400 for URL: https://ads.line.me/api/v1.0/authority_delegations/get
  at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1840)
  at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
  at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
  at AuthorityDelegation.send_deligation_request(AuthorityDelegation.java:66)
  at AuthorityDelegation.read_csv(AuthorityDelegation.java:36)
  at AuthorityDelegation.main(AuthorityDelegation.java:20)
java.io.IOException: Server returned HTTP response code: 400 for URL: https://ads.line.me/api/v1.0/authority_delegations/get
  at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1840)
  at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
  at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
  at AuthorityDelegation.send_deligation_request(AuthorityDelegation.java:66)
  at AuthorityDelegation.read_csv(AuthorityDelegation.java:36)
  at AuthorityDelegation.main(AuthorityDelegation.java:20)

Could somebody please help me?

有人可以帮我吗?

回答by JRG

HTTP code 400 means a BAD REQUEST.

HTTP 代码 400 表示错误请求。

I can't access the endpoint you have shared but here is free online REST API which I am using for demonstrating ..

我无法访问您共享的端点,但这里有免费的在线 REST API,我正在使用它来演示 ..

curl -X POST \
  https://jsonplaceholder.typicode.com/posts \
  -H 'cache-control: no-cache' \
  -H 'postman-token: 907bbf75-73f5-703f-c8b6-3e1cd674ebf7' \
  -d '{
        "userId": 100,
        "id": 100,
        "title": "main title",
        "body": "main body"
    }'
  • -H= headers
  • -d= data
  • -H= 标题
  • -d= 数据

Sample Run:

样品运行:

[/c]$ curl -X POST \
>   https://jsonplaceholder.typicode.com/posts \
>   -H 'cache-control: no-cache' \
>   -H 'postman-token: 907bbf75-73f5-703f-c8b6-3e1cd674ebf7' \
>   -d '{
>         "userId": 100,
>         "id": 100,
>         "title": "main title",
>         "body": "main body"
>     }'

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   258  100   150  100   108    147    106  0:00:01  0:00:01 --:--:--   192{
  "{\n        \"userId\": 100,\n        \"id\": 100,\n        \"title\": \"main title\",\n        \"body\": \"main body\"\n    }": "",
  "id": 101
}

Java Code for the same is as follows:

相同的Java代码如下:

OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/octet-stream");
RequestBody body = RequestBody.create(mediaType, "{\n        \"userId\": 100,\n        \"id\": 100,\n        \"title\": \"main title\",\n        \"body\": \"main body\"\n    }");
Request request = new Request.Builder()
  .url("https://jsonplaceholder.typicode.com/posts")
  .post(body)
  .addHeader("cache-control", "no-cache")
  .addHeader("postman-token", "e11ce033-931a-0419-4903-ab860261a91a")
  .build();

Response response = client.newCall(request).execute();

Another example of calling REST POST call with data ..

使用数据调用 REST POST 调用的另一个示例..

User user = new User();
user.setFirstName("john");
user.setLastName("Maclane");

ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target("URL");
Response response = target.request().post(Entity.entity(user, <MEDIATYPE>));
//Read output in string format
System.out.println(response.getStatus());
response.close(); 

Here is the what your code looks like when I update it with my endpoints and payload.

这是我使用端点和有效负载更新代码时的样子。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;

public class TestClass {

    public static final String POST_URL = "https://jsonplaceholder.typicode.com/posts";

    public static final String POST_DATA = "{\"userId\": 100,\"id\": 100,\"title\": \"main title\",\"body\": \"main body\"}";

    public static void main(String[] args) throws Exception {
        String[] details = {};
        System.out.println(Arrays.toString(details));

        URL line_api_url = new URL(POST_URL);
        String payload = POST_DATA;

        HttpURLConnection linec = (HttpURLConnection) line_api_url
                .openConnection();
        linec.setDoInput(true);
        linec.setDoOutput(true);
        linec.setRequestMethod("POST");
        linec.setRequestProperty("Content-Type", "application/json");
        linec.setRequestProperty("Authorization", "Bearer "
                + "1djCb/mXV+KtryMxr6i1bXw");

        OutputStreamWriter writer = new OutputStreamWriter(
                linec.getOutputStream(), "UTF-8");
        writer.write(payload);

        BufferedReader in = new BufferedReader(new InputStreamReader(
                linec.getInputStream()));
        String inputLine;

        while ((inputLine = in.readLine()) != null)
            System.out.println(inputLine);
        in.close();
    }
}

In nutshell, check the API documentation and ensure the request payload is of correct format as 400 means BAD REQUEST.

简而言之,检查 API 文档并确保请求有效负载的格式正确,因为 400 表示 BAD REQUEST。

回答by SaAn

It's a 400 error, which means Bad Request. Please check this link below.

这是一个 400 错误,这意味着错误的请求。请检查下面的链接。

How to find out specifics of 400 Http error in Java?

如何找出 Java 中 400 Http 错误的细节?

回答by RajSharma

Thanks everyone for your help. I used below code to make it work.

感谢大家的帮助。我使用下面的代码来使它工作。

public JSONObject send_post() {
    HttpClient httpClient = HttpClientBuilder.create().build();
    JSONObject jsonObject = null;

    try {

        HttpPost request = new HttpPost(this.URL + this.object_type + this.request_type);
        StringEntity params = null;
        if (this.request_type.equals("/get")) {
            params = new StringEntity("{\"accountId\":\"5514\"}");
        } else if (this.request_type.equals("/set")) {
            // params = new
            // StringEntity("{\"accountId\":\"5514\",\"operands\":[{\"id\":40151,\"name\":\"ddddd\"}]}");
            String output = String.format("{\"accountId\":\"5514\",\"operands\":[{\"id\":%s,\"name\":\"%s\"}]}",
                    this.params[0], this.params[1]);
            if (this.params[1].equals("OptimizationOff")) {
                output = String.format(
                        "{\"accountId\":\"5514\",\"operands\":[{\"id\":%s,\"bidOptimizationType\":\"%s\"}]}",
                        this.params[0], "NONE");
            } else if (this.params[1].equals("OptimizationOn")) {
                output = String.format(
                        "{\"accountId\":\"5514\",\"operands\":[{\"id\":%s,\"bidOptimizationType\":\"%s\",\"bidOptimizationGoal\":\"%s\"}]}",
                        this.params[0], this.params[2], this.params[3]);
            }
            if (object_type.equals("/ads")) {
                output = String.format("{\"accountId\":\"5514\",\"operands\":[{\"id\":%s,\"bidAmount\":\"%s\"}]}",
                        this.params[0], this.params[1]);
            }
            params = new StringEntity(output);
        }
        request.addHeader("content-type", "application/json");
        request.addHeader("Authorization", "Bearer " + this.Access_Token);
        request.setEntity(params);

        HttpResponse response = httpClient.execute(request);

        BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuffer result = new StringBuffer();
        String line = "";
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }

        System.out.println("API Resonse :"+result.toString());
        jsonObject = new JSONObject(result.toString());

    } catch (Exception ex) {

        ex.printStackTrace();

    } finally {

    }
    return jsonObject;

}

回答by Rajiv Singh

Scala Code to get data from Splunk API and compress the certification/SSL error:

从 Splunk API 获取数据并压缩认证/SSL 错误的 Scala 代码:

import java.nio.charset.StandardCharsets
import java.security.cert.X509Certificate
import java.util.{ArrayList, List}

import javax.net.ssl.SSLContext
import org.apache.commons.codec.binary.Base64
import org.apache.http.NameValuePair
import org.apache.http.client.HttpClient
import org.apache.http.client.methods.HttpPost
import org.apache.http.conn.ssl.{NoopHostnameVerifier, TrustSelfSignedStrategy}
import org.apache.http.impl.client.HttpClients
import org.apache.http.message.BasicNameValuePair
import org.apache.http.ssl.SSLContextBuilder

class test {


  val sslContext: SSLContext = new SSLContextBuilder()
    .loadTrustMaterial(null, new TrustSelfSignedStrategy() {
      override def isTrusted(chain: Array[X509Certificate],
                             authType: String): Boolean = true
    })
    .build()

  val httpclient: HttpClient = HttpClients
    .custom()
    .setSSLContext(sslContext)
    .setSSLHostnameVerifier(new NoopHostnameVerifier())
    .build()
  val httpPost: HttpPost = new HttpPost(
    "https://splunk-api:8089/servicesNS/nobody/search/search/jobs/export")

  val params: List[NameValuePair] = new ArrayList[NameValuePair]()
  val searchString: String =
    "search index=prod_applogs OR index=prod_applogs source=\"*subscriber-daemon-*\" Data  Mutation | lookup data_clients.csv client OUTPUTNEW pow AS pow | stats count as numEvents, min(_time) as minTime by pow, Name | eval cost=round(exact(numEvents*0.000003),2)|eval date=strftime(minTime, \"%Y-%m-%d\")|fields *"
  params.add(new BasicNameValuePair("search", searchString))
  params.add(new BasicNameValuePair("output_mode", "csv"))
  params.add(new BasicNameValuePair("earliest_time", "1h"))
  params.add(new BasicNameValuePair("latest_time", "now"))


  val username: String = "userName"
  val password: String = "pwd"
  val auth: String = username + ":" + password

  val encodedAuth: Array[Byte] =
    Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1))
  val authHeaderVal: String = "Basic " + new String(encodedAuth)

}

回答by Mike

OutputStreamWriter will buffer the output. After this line in your code:

OutputStreamWriter 将缓冲输出。在您的代码中的这一行之后:

writer.write(payload);

add this line

添加这一行

writer.flush();

I would expect that to fix your problem.

我希望这能解决您的问题。

回答by Naman

Though this may not help you with precisely an existing HTTP call using the traditional HttpURLConnection. Yet an interesting way to achieve this in recent times is to use HTTP/2 Clientand try out the latest introduced incubator module jdk.incubator.httpform Java 9.

尽管这可能无法帮助您准确地使用传统的HttpURLConnection. 然而,最近实现这一目标的一个有趣方法是使用HTTP/2 客户端并尝试从jdk.incubator.httpJava 9 中最新引入的孵化器模块。

An easy way(quick-start) of mocking a POSTcall using the same is as follows :

使用相同的模拟调用的简单方法(快速启动)POST如下:

  1. Create a java-modulewithin your project and define module-info.javaas:

    module http.trial { 
        requires jdk.incubator.httpclient;
    }
    
  2. Within the module create a package and a class named HttpPostwith following content:

    import jdk.incubator.http.HttpRequest;
    import jdk.incubator.http.HttpClient;
    import jdk.incubator.http.HttpResponse;
    import java.io.IOException;
    import java.net.URI;
    import java.net.URISyntaxException;
    
    public class HttpPost {
    
      public static void main(String[] args) {
    
        // Request builder
        URI uri = null;
        try {
            uri = new URI("https://ads.line.me/api/v1.0/authority_delegations/get");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        HttpRequest.BodyProcessor bodyProcessor = HttpRequest.BodyProcessor.fromString("{\"operands\":[]}");
        HttpRequest request = HttpRequest.newBuilder().uri(uri)
                        .header("Content-Type", "application/json")
                        .header("Authorization", "Bearer 1djCb/mXV+KtryMxr6i1bXw")
                        .POST(bodyProcessor)
                        .build();
    
        // Client
        HttpClient httpClient = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.ALWAYS).build();
        System.out.println(httpClient.version());
    
        // Response builder
        HttpResponse response = null;
        try {
            response = httpClient.send(request, HttpResponse.BodyHandler.asString());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    
        System.out.println("StatusCode = " + response.statusCode());
        System.out.println("Response = " + response.body().toString());
      }
    }
    
  1. 在您的项目中创建一个java 模块并定义module-info.java为:

    module http.trial { 
        requires jdk.incubator.httpclient;
    }
    
  2. 在模块中创建一个包和一个命名HttpPost为以下内容的类:

    import jdk.incubator.http.HttpRequest;
    import jdk.incubator.http.HttpClient;
    import jdk.incubator.http.HttpResponse;
    import java.io.IOException;
    import java.net.URI;
    import java.net.URISyntaxException;
    
    public class HttpPost {
    
      public static void main(String[] args) {
    
        // Request builder
        URI uri = null;
        try {
            uri = new URI("https://ads.line.me/api/v1.0/authority_delegations/get");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        HttpRequest.BodyProcessor bodyProcessor = HttpRequest.BodyProcessor.fromString("{\"operands\":[]}");
        HttpRequest request = HttpRequest.newBuilder().uri(uri)
                        .header("Content-Type", "application/json")
                        .header("Authorization", "Bearer 1djCb/mXV+KtryMxr6i1bXw")
                        .POST(bodyProcessor)
                        .build();
    
        // Client
        HttpClient httpClient = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.ALWAYS).build();
        System.out.println(httpClient.version());
    
        // Response builder
        HttpResponse response = null;
        try {
            response = httpClient.send(request, HttpResponse.BodyHandler.asString());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    
        System.out.println("StatusCode = " + response.statusCode());
        System.out.println("Response = " + response.body().toString());
      }
    }