HTTP POST โดยใช้ JSON ใน Java


188

ฉันต้องการสร้าง HTTP POST อย่างง่ายโดยใช้ JSON ใน Java

สมมติว่าเป็น URL www.site.com

และใช้ในค่าที่{"name":"myname","age":"20"}ระบุว่าเป็น'details'ตัวอย่าง

ฉันจะสร้างไวยากรณ์สำหรับ POST ได้อย่างไร

ฉันดูเหมือนจะไม่พบวิธีการโพสต์ใน JSON Javadocs

คำตอบ:


167

นี่คือสิ่งที่คุณต้องทำ:

  1. รับ Apache HttpClient สิ่งนี้จะช่วยให้คุณสามารถร้องขอได้
  2. สร้างคำขอ HttpPost ด้วยและเพิ่มส่วนหัว "application / x-www-form-urlencoded"
  3. สร้าง StringEntity ที่คุณจะส่ง JSON ไปให้
  4. ดำเนินการโทร

ดูเหมือนว่ารหัสคร่าว ๆ (คุณจะยังคงต้องแก้ปัญหาและทำให้มันทำงาน)

//Deprecated
//HttpClient httpClient = new DefaultHttpClient(); 

HttpClient httpClient = HttpClientBuilder.create().build(); //Use this instead 

try {

    HttpPost request = new HttpPost("http://yoururl");
    StringEntity params =new StringEntity("details={\"name\":\"myname\",\"age\":\"20\"} ");
    request.addHeader("content-type", "application/x-www-form-urlencoded");
    request.setEntity(params);
    HttpResponse response = httpClient.execute(request);

    //handle response here...

}catch (Exception ex) {

    //handle exception here

} finally {
    //Deprecated
    //httpClient.getConnectionManager().shutdown(); 
}

9
คุณสามารถทำได้ แต่มันก็เป็นแนวปฏิบัติที่ดีที่จะทำให้นามธรรมเป็น JSONObject ราวกับว่าคุณกำลังทำในสตริงโดยตรงคุณอาจตั้งโปรแกรมสตริงผิดและทำให้เกิดข้อผิดพลาดทางไวยากรณ์ โดยใช้ JSONObject คุณตรวจสอบให้แน่ใจว่าการทำให้เป็นอนุกรมของคุณนั้นเป็นไปตามโครงสร้าง JSON ที่ถูกต้องเสมอ
momo

3
ในหลักการพวกเขาทั้งสองเพิ่งส่งข้อมูล ข้อแตกต่างเพียงอย่างเดียวคือวิธีที่คุณดำเนินการกับเซิร์ฟเวอร์ หากคุณมีคู่คีย์ - ค่าเพียงไม่กี่คู่ดังนั้นพารามิเตอร์ POST ปกติที่มี key1 = value1, key2 = value2 ฯลฯ อาจเพียงพอ แต่เมื่อข้อมูลของคุณซับซ้อนมากขึ้นและมีโครงสร้างที่ซับซ้อนโดยเฉพาะอย่างยิ่ง (วัตถุซ้อนกันอาร์เรย์) คุณต้องการ เริ่มพิจารณาใช้ JSON การส่งโครงสร้างที่ซับซ้อนโดยใช้คู่คีย์ - ค่านั้นน่ารังเกียจและยากที่จะแยกวิเคราะห์บนเซิร์ฟเวอร์ (คุณสามารถลองแล้วคุณจะเห็นมันทันที) ยังจำวันที่เราต้องทำอย่างนั้น .. มันไม่สวย ..
momo

1
ดีใจที่ได้ช่วยเหลือ! หากนี่คือสิ่งที่คุณกำลังมองหาคุณควรยอมรับคำตอบเพื่อให้คนอื่นที่มีคำถามคล้าย ๆ กันนั้นเป็นผู้นำที่ดีสำหรับคำถามของพวกเขา คุณสามารถใช้เครื่องหมายถูกที่คำตอบ แจ้งให้เราทราบหากคุณมีคำถามเพิ่มเติม
momo

12
ไม่ควรใช้ประเภทเนื้อหาเป็น 'application / json' 'application / x-www-form-urlencoded' หมายถึงสตริงที่จะถูกจัดรูปแบบคล้ายกับสตริงแบบสอบถาม นิวเม็กซิโกฉันเห็นสิ่งที่คุณทำคุณใส่ json blob เป็นมูลค่าของทรัพย์สิน
Matthew Ward

1
ส่วนที่เลิกใช้แล้วควรถูกแทนที่โดยใช้ CloseableHttpClient ซึ่งให้วิธีการ. close () - ดูstackoverflow.com/a/20713689/1484047
Frame91

92

คุณสามารถใช้ไลบรารี Gson เพื่อแปลงคลาส Java ของคุณเป็นวัตถุ JSON

สร้างคลาส pojo สำหรับตัวแปรที่คุณต้องการส่งตามตัวอย่างด้านบน

{"name":"myname","age":"20"}

กลายเป็น

class pojo1
{
   String name;
   String age;
   //generate setter and getters
}

เมื่อคุณตั้งค่าตัวแปรในคลาส pojo1 คุณสามารถส่งโดยใช้รหัสต่อไปนี้

String       postUrl       = "www.site.com";// put in your url
Gson         gson          = new Gson();
HttpClient   httpClient    = HttpClientBuilder.create().build();
HttpPost     post          = new HttpPost(postUrl);
StringEntity postingString = new StringEntity(gson.toJson(pojo1));//gson.tojson() converts your pojo to json
post.setEntity(postingString);
post.setHeader("Content-type", "application/json");
HttpResponse  response = httpClient.execute(post);

และนี่คือการนำเข้า

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;

และสำหรับ GSON

import com.google.gson.Gson;

1
สวัสดีคุณสร้างวัตถุ httpClient อย่างไร มันเป็นอินเทอร์เฟซ
user3290180

1
ใช่นั่นคือส่วนต่อประสาน คุณสามารถสร้างอินสแตนซ์โดยใช้ 'HttpClient httpClient = new DefaultHttpClient ();'
Prakash

2
ตอนนี้เลิกใช้แล้วเราต้องใช้ HttpClient httpClient = HttpClientBuilder.create (). build ();
user3290180

5
วิธีการนำเข้า HttpClientBuilder
Esterlinkof

3
ฉันพบว่ามันสะอาดกว่าการใช้พารามิเตอร์ ContentType บนตัวสร้าง StringUtils และส่งผ่าน ContentType.APPLICATION_JSON แทนที่จะตั้งค่าส่วนหัวด้วยตนเอง
TownCube

47

คำตอบของ @ momo สำหรับ Apache HttpClient รุ่น 4.3.1 หรือใหม่กว่า ฉันใช้JSON-Javaเพื่อสร้างวัตถุ JSON ของฉัน:

JSONObject json = new JSONObject();
json.put("someKey", "someValue");    

CloseableHttpClient httpClient = HttpClientBuilder.create().build();

try {
    HttpPost request = new HttpPost("http://yoururl");
    StringEntity params = new StringEntity(json.toString());
    request.addHeader("content-type", "application/json");
    request.setEntity(params);
    httpClient.execute(request);
// handle response here...
} catch (Exception ex) {
    // handle exception here
} finally {
    httpClient.close();
}

20

มันอาจจะง่ายที่สุดในการใช้HttpURLConnection

http://www.xyzws.com/Javafaq/how-to-use-httpurlconnection-post-data-to-web-server/139

คุณจะใช้ JSONObject หรืออะไรก็ตามที่สร้าง JSON ของคุณ แต่จะไม่จัดการกับเครือข่าย คุณต้องทำให้เป็นอนุกรมแล้วส่งผ่านไปยัง HttpURLConnection เพื่อ POST


JSONObject j = new JSONObject (); j.put ("name", "myname"); j.put ("อายุ", "20"); เช่นนั้น? ฉันจะทำให้เป็นอันดับได้อย่างไร
asdf007

@ asdf007 j.toString()ใช้เพียง
Alex Churchill

นั่นเป็นความจริงการเชื่อมต่อนี้กำลังปิดกั้น นี่อาจไม่ใช่เรื่องใหญ่หากคุณกำลังส่ง POST มันสำคัญมากถ้าคุณเรียกใช้เว็บเซิร์ฟเวอร์
Alex Churchill

ลิงก์ HttpURLConnection นั้นตาย
โทเบียสโรลันด์

คุณสามารถโพสต์ตัวอย่างวิธีการโพสต์ json ต่อร่างกายได้หรือไม่

15
protected void sendJson(final String play, final String prop) {
     Thread t = new Thread() {
     public void run() {
        Looper.prepare(); //For Preparing Message Pool for the childThread
        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(client.getParams(), 1000); //Timeout Limit
        HttpResponse response;
        JSONObject json = new JSONObject();

            try {
                HttpPost post = new HttpPost("http://192.168.0.44:80");
                json.put("play", play);
                json.put("Properties", prop);
                StringEntity se = new StringEntity(json.toString());
                se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
                post.setEntity(se);
                response = client.execute(post);

                /*Checking response */
                if (response != null) {
                    InputStream in = response.getEntity().getContent(); //Get the data in the entity
                }

            } catch (Exception e) {
                e.printStackTrace();
                showMessage("Error", "Cannot Estabilish Connection");
            }

            Looper.loop(); //Loop in the message queue
        }
    };
    t.start();
}

7
โปรดพิจารณาการแก้ไขโพสต์ของคุณเพื่อเพิ่มคำอธิบายเพิ่มเติมเกี่ยวกับสิ่งที่รหัสของคุณทำและเหตุผลที่จะแก้ไขปัญหา คำตอบที่ส่วนใหญ่มีเพียงรหัส (แม้ว่าจะใช้งานได้) โดยปกติแล้วจะไม่ช่วยให้ OP เข้าใจถึงปัญหาของพวกเขา
Reeno

14

ลองรหัสนี้:

HttpClient httpClient = new DefaultHttpClient();

try {
    HttpPost request = new HttpPost("http://yoururl");
    StringEntity params =new StringEntity("details={\"name\":\"myname\",\"age\":\"20\"} ");
    request.addHeader("content-type", "application/json");
    request.addHeader("Accept","application/json");
    request.setEntity(params);
    HttpResponse response = httpClient.execute(request);

    // handle response here...
}catch (Exception ex) {
    // handle exception here
} finally {
    httpClient.getConnectionManager().shutdown();
}

ขอบคุณ! เพียง แต่คำตอบของคุณแก้ไขปัญหาการเข้ารหัส :)
Shrikant

@SonuDhakar ทำไมคุณส่งapplication/jsonทั้งเป็นส่วนหัวที่ยอมรับและเป็นประเภทเนื้อหา
Kasun Siyambalapitiya

ดูเหมือนว่าDefaultHttpClientจะเลิกใช้แล้ว
sdgfsdh

11

ฉันพบคำถามนี้เพื่อหาวิธีแก้ปัญหาเกี่ยวกับวิธีส่งคำขอโพสต์จากลูกค้า java ไปยัง Google Endpoints คำตอบข้างต้นน่าจะถูกต้อง แต่ไม่สามารถใช้งานได้ในกรณีของ Google Endpoint

ทางออกสำหรับ Google Endpoints

  1. เนื้อความการร้องขอต้องมีสตริง JSON เท่านั้นไม่ใช่คู่ name = value
  2. ต้องตั้งค่าส่วนหัวของชนิดเนื้อหาเป็น "application / json"

    post("http://localhost:8888/_ah/api/langapi/v1/createLanguage",
                       "{\"language\":\"russian\", \"description\":\"dsfsdfsdfsdfsd\"}");
    
    
    
    public static void post(String url, String json ) throws Exception{
      String charset = "UTF-8"; 
      URLConnection connection = new URL(url).openConnection();
      connection.setDoOutput(true); // Triggers POST.
      connection.setRequestProperty("Accept-Charset", charset);
      connection.setRequestProperty("Content-Type", "application/json;charset=" + charset);
    
      try (OutputStream output = connection.getOutputStream()) {
        output.write(json.getBytes(charset));
      }
    
      InputStream response = connection.getInputStream();
    }

    แน่นอนว่าสามารถทำได้โดยใช้ HttpClient เช่นกัน


8

คุณสามารถใช้รหัสต่อไปนี้กับ Apache HTTP:

String payload = "{\"name\": \"myname\", \"age\": \"20\"}";
post.setEntity(new StringEntity(payload, ContentType.APPLICATION_JSON));

response = client.execute(request);

นอกจากนี้คุณสามารถสร้างวัตถุ json และใส่ในฟิลด์ลงในวัตถุเช่นนี้

HttpPost post = new HttpPost(URL);
JSONObject payload = new JSONObject();
payload.put("name", "myName");
payload.put("age", "20");
post.setEntity(new StringEntity(payload.toString(), ContentType.APPLICATION_JSON));

สิ่งสำคัญคือการเพิ่ม ContentType.APPLICATION_JSON ไม่อย่างนั้นมันก็ไม่ได้ผลสำหรับ StringEntity ใหม่ของฉัน (payload, ContentType.APPLICATION_JSON)
Johnny Cage

2

สำหรับ Java 11 คุณสามารถใช้ไคลเอ็นต์ HTTPใหม่:

 HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("http://localhost/api"))
        .header("Content-Type", "application/json")
        .POST(ofInputStream(() -> getClass().getResourceAsStream(
            "/some-data.json")))
        .build();

    client.sendAsync(request, BodyHandlers.ofString())
        .thenApply(HttpResponse::body)
        .thenAccept(System.out::println)
        .join();

คุณสามารถใช้ผู้เผยแพร่จาก InputStream, String, File แปลง JSON เป็น String หรือ IS ที่คุณสามารถทำได้ด้วย Jackson


1

Java 8 พร้อม apache httpClient 4

CloseableHttpClient client = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost("www.site.com");


String json = "details={\"name\":\"myname\",\"age\":\"20\"} ";

        try {
            StringEntity entity = new StringEntity(json);
            httpPost.setEntity(entity);

            // set your POST request headers to accept json contents
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Content-type", "application/json");

            try {
                // your closeablehttp response
                CloseableHttpResponse response = client.execute(httpPost);

                // print your status code from the response
                System.out.println(response.getStatusLine().getStatusCode());

                // take the response body as a json formatted string 
                String responseJSON = EntityUtils.toString(response.getEntity());

                // convert/parse the json formatted string to a json object
                JSONObject jobj = new JSONObject(responseJSON);

                //print your response body that formatted into json
                System.out.println(jobj);

            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {

                e.printStackTrace();
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

0

ฉันขอแนะนำhttp-request ที่สร้างจาก apache http api

HttpRequest<String> httpRequest = HttpRequestBuilder.createPost(yourUri, String.class)
    .responseDeserializer(ResponseDeserializer.ignorableDeserializer()).build();

public void send(){
   ResponseHandler<String> responseHandler = httpRequest.execute("details", yourJsonData);

   int statusCode = responseHandler.getStatusCode();
   String responseContent = responseHandler.orElse(null); // returns Content from response. If content isn't present returns null. 
}

หากคุณต้องการส่งJSONตามคำขอเนื้อหาคุณสามารถ:

  ResponseHandler<String> responseHandler = httpRequest.executeWithBody(yourJsonData);

ฉันขอแนะนำให้อ่านเอกสารก่อนการใช้งาน


ทำไมคุณถึงแนะนำสิ่งนี้เหนือคำตอบข้างต้นด้วย upvotes มากที่สุด
Jeryl Cook

เพราะมันง่ายมากที่จะใช้และจัดการกับการตอบสนอง
Beno Arakelyan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.