如何在java中发送HTTP请求?

Yat*_*oel 392 html java http httpwebrequest

在Java中,如何编写HTTP请求消息并将其发送到HTTP WebServer?

duf*_*ymo 294

您可以使用java.net.HttpUrlConnection.

示例(从这里开始),有所改进.包含在链接腐烂的情况下:

public static String executePost(String targetURL, String urlParameters) {
  HttpURLConnection connection = null;

  try {
    //Create connection
    URL url = new URL(targetURL);
    connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("POST");
    connection.setRequestProperty("Content-Type", 
        "application/x-www-form-urlencoded");

    connection.setRequestProperty("Content-Length", 
        Integer.toString(urlParameters.getBytes().length));
    connection.setRequestProperty("Content-Language", "en-US");  

    connection.setUseCaches(false);
    connection.setDoOutput(true);

    //Send request
    DataOutputStream wr = new DataOutputStream (
        connection.getOutputStream());
    wr.writeBytes(urlParameters);
    wr.close();

    //Get Response  
    InputStream is = connection.getInputStream();
    BufferedReader rd = new BufferedReader(new InputStreamReader(is));
    StringBuilder response = new StringBuilder(); // or StringBuffer if Java version 5+
    String line;
    while ((line = rd.readLine()) != null) {
      response.append(line);
      response.append('\r');
    }
    rd.close();
    return response.toString();
  } catch (Exception e) {
    e.printStackTrace();
    return null;
  } finally {
    if (connection != null) {
      connection.disconnect();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 将一些实际代码放入此答案将有助于避免链接腐烂... (13认同)
  • 从 Java 9 开始,创建 HTTP 请求[变得更加容易](https://www.baeldung.com/java-http-request)。 (3认同)
  • 这是替代Java Almanac的另一个很好的代码片段:[HttpUrlConnection-Example](http://www.xyzws.com/Javafaq/how-to-use-httpurlconnection-post-data-to-web-server/139) (2认同)

Chi*_*Chi 223

来自Oracle的java教程

import java.net.*;
import java.io.*;

public class URLConnectionReader {
    public static void main(String[] args) throws Exception {
        URL yahoo = new URL("http://www.yahoo.com/");
        URLConnection yc = yahoo.openConnection();
        BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                yc.getInputStream()));
        String inputLine;

        while ((inputLine = in.readLine()) != null) 
            System.out.println(inputLine);
        in.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是发送HTTP请求imo的太多线路噪声.与Python的请求库形成对比:`response = requests.get('http://www.yahoo.com/')`; 在Java中应该可以实现类似简洁的东西. (76认同)
  • @ leo-the-manic那是因为Java应该是一种低级语言(比python)并且允许(强制)程序员处理下面的细节而不是假设"理智"默认值(即缓冲,字符编码等) .有可能得到简洁的东西,但是你会失去更多准系统方法的灵活性. (20认同)
  • @fortran Python具有同样的低级选项来完成与上面相同的操作. (7认同)
  • "那是因为Java应该是一种较低级别的语言"X'D (7认同)

eri*_*son 69

我知道其他人会推荐Apache的http客户端,但它增加了复杂性(即更多可能出错的东西),这很少得到保证.对于一个简单的任务,java.net.URL将会这样做.

URL url = new URL("http://www.y.com/url");
InputStream is = url.openStream();
try {
  /* Now read the retrieved document from the stream. */
  ...
} finally {
  is.close();
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用URLConnection来处理请求标头,但海报不要求这样做; 从这个问题来看,一个简单的答案很重要. (36认同)
  • 如果你想要使用请求标题,那就没有用了,这在处理只会以某种方式响应流行浏览器的网站时特别有用. (6认同)

Vin*_*lds 55

Apache HttpComponents.这两个模块的示例 - HttpCoreHttpClient将立即开始.

并不是HttpUrlConnection是一个糟糕的选择,HttpComponents将抽象出很多繁琐的编码.如果你真的想用最少的代码支持很多HTTP服务器/客户端,我会推荐这个.顺便说一句,HttpCore可以用于具有最小功能的应用程序(客户端或服务器),而HttpClient将用于需要支持多种身份验证方案,cookie支持等的客户端.

  • FWIW,我们的代码以java.net.HttpURLConnection开头,但是当我们必须添加SSL并在我们棘手的内部网络中解决一些奇怪的用例时,它变得非常令人头痛.Apache HttpComponents节省了一天.我们的项目目前仍然使用一个丑陋的混合,有一些狡猾的适配器将java.net.URLs转换为HttpComponents使用的URI.我经常重构那些.唯一一次HttpComponents代码变得非常复杂的是从头部解析日期.但[解决方案](http://stackoverflow.com/a/1930240/1450294)仍然很简单. (2认同)

Jan*_*sen 25

这是一个完整的Java 7程序:

class GETHTTPResource {
  public static void main(String[] args) throws Exception {
    try (java.util.Scanner s = new java.util.Scanner(new java.net.URL("http://tools.ietf.org/rfc/rfc768.txt").openStream())) {
      System.out.println(s.useDelimiter("\\A").next());
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

新的try-with-resources将自动关闭Scanner,它将自动关闭InputStream.


Sat*_*rma 14

这会对你有所帮助.不要忘记将JAR添加HttpClient.jar到类路径中.

import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;

public class MainSendRequest {

     static String url =
         "http://localhost:8080/HttpRequestSample/RequestSend.jsp";

    public static void main(String[] args) {

        //Instantiate an HttpClient
        HttpClient client = new HttpClient();

        //Instantiate a GET HTTP method
        PostMethod method = new PostMethod(url);
        method.setRequestHeader("Content-type",
                "text/xml; charset=ISO-8859-1");

        //Define name-value pairs to set into the QueryString
        NameValuePair nvp1= new NameValuePair("firstName","fname");
        NameValuePair nvp2= new NameValuePair("lastName","lname");
        NameValuePair nvp3= new NameValuePair("email","email@email.com");

        method.setQueryString(new NameValuePair[]{nvp1,nvp2,nvp3});

        try{
            int statusCode = client.executeMethod(method);

            System.out.println("Status Code = "+statusCode);
            System.out.println("QueryString>>> "+method.getQueryString());
            System.out.println("Status Text>>>"
                  +HttpStatus.getStatusText(statusCode));

            //Get data as a String
            System.out.println(method.getResponseBodyAsString());

            //OR as a byte array
            byte [] res  = method.getResponseBody();

            //write to file
            FileOutputStream fos= new FileOutputStream("donepage.html");
            fos.write(res);

            //release connection
            method.releaseConnection();
        }
        catch(IOException e) {
            e.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 根据定义,@ Joffrey Maps每个值有1个键,表示:`一个地图不能包含重复的键'!但HTTP参数可以有重复的键. (4认同)

Tom*_*art 13

Google java http客户端具有很好的http请求API.您可以轻松添加JSON支持等.虽然对于简单的请求,它可能是过度的.

import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import java.io.IOException;
import java.io.InputStream;

public class Network {

    static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();

    public void getRequest(String reqUrl) throws IOException {
        GenericUrl url = new GenericUrl(reqUrl);
        HttpRequest request = HTTP_TRANSPORT.createRequestFactory().buildGetRequest(url);
        HttpResponse response = request.execute();
        System.out.println(response.getStatusCode());

        InputStream is = response.getContent();
        int ch;
        while ((ch = is.read()) != -1) {
            System.out.print((char) ch);
        }
        response.disconnect();
    }
}
Run Code Online (Sandbox Code Playgroud)


lak*_*sys 10

您可以像这样使用Socket

String host = "www.yourhost.com";
Socket socket = new Socket(host, 80);
String request = "GET / HTTP/1.0\r\n\r\n";
OutputStream os = socket.getOutputStream();
os.write(request.getBytes());
os.flush();

InputStream is = socket.getInputStream();
int ch;
while( (ch=is.read())!= -1)
    System.out.print((char)ch);
socket.close();    
Run Code Online (Sandbox Code Playgroud)

  • 与其他解决方案相比,它似乎更容易,更直接。Java使事情比应有的复杂。 (2认同)

Mah*_*zad 9

如果您使用的是 Java 11或更高版本(Android 除外),则可以使用 Java 11 新的HTTP Client API ,而不是旧版HttpUrlConnection类类。

GET请求示例:

var uri = URI.create("https://httpbin.org/get?age=26&isHappy=true");
var client = HttpClient.newHttpClient();
var request = HttpRequest
        .newBuilder()
        .uri(uri)
        .header("accept", "application/json")
        .GET()
        .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
Run Code Online (Sandbox Code Playgroud)

异步执行相同的请求:

var responseAsync = client
        .sendAsync(request, HttpResponse.BodyHandlers.ofString())
        .thenApply(HttpResponse::body)
        .thenAccept(System.out::println);
// responseAsync.join(); // Wait for completion
Run Code Online (Sandbox Code Playgroud)

POST请求示例:

var request = HttpRequest
        .newBuilder()
        .uri(uri)
        .version(HttpClient.Version.HTTP_2)
        .timeout(Duration.ofMinutes(1))
        .header("Content-Type", "application/json")
        .header("Authorization", "Bearer fake")
        .POST(BodyPublishers.ofString("{ title: 'This is cool' }"))
        .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
Run Code Online (Sandbox Code Playgroud)

要以 multipart ( multipart/form-data) 或 url-encoded ( application/x-www-form-urlencoded) 格式发送表单数据,请参阅此解决方案

有关 HTTP 客户端 API 的示例和更多信息,请参阅本文。

对于 Java 标准库 HTTP服务器,请参阅这篇文章


tzi*_*zik 7

有一个关于发送POST请求有很大的联系在这里通过实例车厂::

try {
    // Construct data
    String data = URLEncoder.encode("key1", "UTF-8") + "=" + URLEncoder.encode("value1", "UTF-8");
    data += "&" + URLEncoder.encode("key2", "UTF-8") + "=" + URLEncoder.encode("value2", "UTF-8");

    // Send data
    URL url = new URL("http://hostname:80/cgi");
    URLConnection conn = url.openConnection();
    conn.setDoOutput(true);
    OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
    wr.write(data);
    wr.flush();

    // Get the response
    BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String line;
    while ((line = rd.readLine()) != null) {
        // Process line...
    }
    wr.close();
    rd.close();
} catch (Exception e) {
}
Run Code Online (Sandbox Code Playgroud)

如果您想发送GET请求,可以稍微修改代码以满足您的需求.具体而言,您必须在URL的构造函数中添加参数.然后,也注释掉这个wr.write(data);

有一件事是没有写的,你应该提防,是超时.特别是如果你想在WebServices中使用它,你必须设置超时,否则上面的代码将无限期地等待或者至少持续很长时间,这可能是你不想要的.

超时设置如下conn.setReadTimeout(2000);,输入参数以毫秒为单位


归档时间:

查看次数:

920501 次

最近记录:

6 年 前