首页 文章

在Java中发送HTTP POST请求

提问于
浏览
238

我们假设这个URL ...

http://www.example.com/page.php?id=10

(这里需要在POST请求中发送id)

我想将 id = 10 发送到服务器的 page.php ,它在POST方法中接受它 .

我怎样才能从Java中做到这一点?

我试过这个:

URL aaa = new URL("http://www.example.com/page.php");
URLConnection ccc = aaa.openConnection();

但我仍然无法弄清楚如何通过POST发送它

8 回答

  • 20

    我建议使用基于apache http api构建的http-request .

    HttpRequest<String> httpRequest = HttpRequestBuilder.createPost("http://www.example.com/page.php", String.class)
    .responseDeserializer(ResponseDeserializer.ignorableDeserializer()).build();
    
    public void send(){
       String response = httpRequest.execute("id", "10").get();
    }
    
  • 144

    使用Apache HTTP组件的一种简单方法是

    Request.Post("http://www.example.com/page.php")
                .bodyForm(Form.form().add("id", "10").build())
                .execute()
                .returnContent();
    

    看看Fluent API

  • 0
    String rawData = "id=10";
    String type = "application/x-www-form-urlencoded";
    String encodedData = URLEncoder.encode( rawData, "UTF-8" ); 
    URL u = new URL("http://www.example.com/page.php");
    HttpURLConnection conn = (HttpURLConnection) u.openConnection();
    conn.setDoOutput(true);
    conn.setRequestMethod("POST");
    conn.setRequestProperty( "Content-Type", type );
    conn.setRequestProperty( "Content-Length", String.valueOf(encodedData.length()));
    OutputStream os = conn.getOutputStream();
    os.write(encodedData.getBytes());
    
  • 95

    调用 HttpURLConnection.setRequestMethod("POST")HttpURLConnection.setDoOutput(true); 实际上只需要后者作为POST然后成为默认方法 .

  • 14

    在vanilla Java中发送POST请求很容易 . 从 URL 开始,我们需要使用 url.openConnection(); 将其转换为 URLConnection . 之后,我们需要将其转换为 HttpURLConnection ,因此我们可以访问其 setRequestMethod() 方法来设置我们的方法 . 我们最后说我们将通过连接发送数据 .

    URL url = new URL("https://www.example.com/login");
    URLConnection con = url.openConnection();
    HttpURLConnection http = (HttpURLConnection)con;
    http.setRequestMethod("POST"); // PUT is another valid option
    http.setDoOutput(true);
    

    然后我们需要说明我们要发送的内容:

    发送简单表格

    来自http表单的普通POST具有well defined格式 . 我们需要将输入转换为以下格式:

    Map<String,String> arguments = new HashMap<>();
    arguments.put("username", "root");
    arguments.put("password", "sjh76HSn!"); // This is a fake password obviously
    StringJoiner sj = new StringJoiner("&");
    for(Map.Entry<String,String> entry : arguments.entrySet())
        sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" 
             + URLEncoder.encode(entry.getValue(), "UTF-8"));
    byte[] out = sj.toString().getBytes(StandardCharsets.UTF_8);
    int length = out.length;
    

    然后,我们可以使用正确的标头将表单内容附加到http请求并发送它 .

    http.setFixedLengthStreamingMode(length);
    http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
    http.connect();
    try(OutputStream os = http.getOutputStream()) {
        os.write(out);
    }
    // Do something with http.getInputStream()
    

    发送JSON

    我们也可以使用java发送json,这也很简单:

    byte[] out = "{\"username\":\"root\",\"password\":\"password\"}" .getBytes(StandardCharsets.UTF_8);
    int length = out.length;
    
    http.setFixedLengthStreamingMode(length);
    http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
    http.connect();
    try(OutputStream os = http.getOutputStream()) {
        os.write(out);
    }
    // Do something with http.getInputStream()
    

    请记住,不同的服务器接受json的不同内容类型,请参阅this问题 .


    使用java post发送文件

    由于格式更复杂,因此可以认为发送文件更具挑战性 . 我们还将添加支持将文件作为字符串发送,因为我们不希望将文件完全缓冲到内存中 .

    为此,我们定义了一些辅助方法:

    private void sendFile(OutputStream out, String name, InputStream in, String fileName) {
        String o = "Content-Disposition: form-data; name=\"" + URLEncoder.encode(name,"UTF-8") 
                 + "\"; filename=\"" + URLEncoder.encode(filename,"UTF-8") + "\"\r\n\r\n";
        out.write(o.getBytes(StandardCharsets.UTF_8));
        byte[] buffer = new byte[2048];
        for (int n = 0; n >= 0; n = in.read(buffer))
            out.write(buffer, 0, n);
        out.write("\r\n".getBytes(StandardCharsets.UTF_8));
    }
    
    private void sendField(OutputStream out, String name, String field) {
        String o = "Content-Disposition: form-data; name=\"" 
                 + URLEncoder.encode(name,"UTF-8") + "\"\r\n\r\n";
        out.write(o.getBytes(StandardCharsets.UTF_8));
        out.write(URLEncoder.encode(field,"UTF-8").getBytes(StandardCharsets.UTF_8));
        out.write("\r\n".getBytes(StandardCharsets.UTF_8));
    }
    

    然后,我们可以使用这些方法创建一个多部分发布请求,如下所示:

    String boundary = UUID.randomUUID().toString();
    byte[] boundaryBytes = 
               ("--" + boundary + "\r\n").getBytes(StandardCharsets.UTF_8);
    byte[] finishBoundaryBytes = 
               ("--" + boundary + "--").getBytes(StandardCharsets.UTF_8);
    http.setRequestProperty("Content-Type", 
               "multipart/form-data; charset=UTF-8; boundary=" + boundary);
    
    // Enable streaming mode with default settings
    http.setChunkedStreamingMode(0); 
    
    // Send our fields:
    try(OutputStream out = http.getOutputStream()) {
        // Send our header (thx Algoman)
        out.write(boundaryBytes);
    
        // Send our first field
        sendField(out, "username", "root");
    
        // Send a seperator
        out.write(boundaryBytes);
    
        // Send our second field
        sendField(out, "password", "toor");
    
        // Send another seperator
        out.write(boundaryBytes);
    
        // Send our file
        try(InputStream file = new FileInputStream("test.txt")) {
            sendFile(out, "identification", file, "text.txt");
        }
    
        // Finish the request
        out.write(finishBoundaryBytes);
    }
    
    
    // Do something with http.getInputStream()
    
  • 5

    第一个答案很棒,但我必须添加try / catch以避免Java编译器错误 .
    另外,我在如何阅读使用Java库的 HttpResponse 时遇到了麻烦 .

    这是更完整的代码:

    /*
     * Create the POST request
     */
    HttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost("http://example.com/");
    // Request parameters and other properties.
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("user", "Bob"));
    try {
        httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
    } catch (UnsupportedEncodingException e) {
        // writing error to Log
        e.printStackTrace();
    }
    /*
     * Execute the HTTP Request
     */
    try {
        HttpResponse response = httpClient.execute(httpPost);
        HttpEntity respEntity = response.getEntity();
    
        if (respEntity != null) {
            // EntityUtils to get the response content
            String content =  EntityUtils.toString(respEntity);
        }
    } catch (ClientProtocolException e) {
        // writing exception to log
        e.printStackTrace();
    } catch (IOException e) {
        // writing exception to log
        e.printStackTrace();
    }
    
  • 276

    更新答案:

    由于原始答案中的某些类在较新版本的Apache HTTP Components中已弃用,因此我发布此更新 .

    顺便说一句,您可以访问完整文档以获取更多示例here .

    HttpClient httpclient = HttpClients.createDefault();
    HttpPost httppost = new HttpPost("http://www.a-domain.com/foo/");
    
    // Request parameters and other properties.
    List<NameValuePair> params = new ArrayList<NameValuePair>(2);
    params.add(new BasicNameValuePair("param-1", "12345"));
    params.add(new BasicNameValuePair("param-2", "Hello!"));
    httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
    
    //Execute and get the response.
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity entity = response.getEntity();
    
    if (entity != null) {
        try (InputStream instream = entity.getContent()) {
            // do something useful
        }
    }
    

    原文答案:

    我建议使用Apache HttpClient . 它更快,更容易实现 .

    HttpPost post = new HttpPost("http://jakarata.apache.org/");
    NameValuePair[] data = {
        new NameValuePair("user", "joe"),
        new NameValuePair("password", "bloggs")
    };
    post.setRequestBody(data);
    // execute method and handle any error responses.
    ...
    InputStream in = post.getResponseBodyAsStream();
    // handle response.
    

    有关更多信息,请查看此网址:http://hc.apache.org/

  • 1

    使用post请求发送参数的最简单方法:

    String postURL = "http://www.example.com/page.php";
    
    HttpPost post = new HttpPost(postURL);
    
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("id", "10"));
    
    UrlEncodedFormEntity ent = new UrlEncodedFormEntity(params, "UTF-8");
    post.setEntity(ent);
    
    HttpClient client = new DefaultHttpClient();
    HttpResponse responsePOST = client.execute(post);
    

    你做完了 . 现在你可以使用 responsePOST . 获取响应内容为字符串:

    BufferedReader reader = new BufferedReader(new  InputStreamReader(responsePOST.getEntity().getContent()), 2048);
    
    if (responsePOST != null) {
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(" line : " + line);
            sb.append(line);
        }
        String getResponseString = "";
        getResponseString = sb.toString();
    //use server output getResponseString as string value.
    }
    

相关问题