HttpURLConnection HTTP客户端

HTTP是应用最广泛的应用层协议,JavaSE内置了HttpURLConnection对象,它可以作为一个简单的HTTP客户端,在编写服务调用客户端、爬虫程序、GUI程序和Android应用时都比较常用。HttpURLConnection这个类的方法很多,这里不会逐一介绍,只是记录几个使用HttpURLConnection的最佳实践,以备日后查阅。有关更详细的方法使用,可以参考JDK文档。

发起GET请求并读取响应体

public class Main {
    public static void main(String[] args) throws Exception {
        File file = new File("/home/gacfox/test.html");
        FileOutputStream fileOutputStream = new FileOutputStream(file);

        //初始化请求URL
        URL url = new URL("http://www.baidu.com");
        //获取HttpURLConnection对象
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        //发起HTTP请求
        connection.connect();

        //读取响应状态码,200表示OK
        if (connection.getResponseCode() == 200) {
            //获取响应体输入流
            InputStream inputStream = connection.getInputStream();

            //读取输入流写入文件
            byte[] buffer = new byte[1024];
            int n;
            while ((n = inputStream.read(buffer)) != -1) {
                fileOutputStream.write(buffer, 0, n);
            }
            inputStream.close();
            fileOutputStream.close();
        }
    }
}

这里我们向一个网页发起GET请求,显然响应体是一个HTML页面,我们获得了这个页面内容的输入流,并将其存入一个文件中。

注:为了代码美观,上面我们对HttpURLConnection并没有配置很多属性,因为它的很多属性默认值就是我们需要的。具体请参考文档。

使用POST方式提交表单

public class Main {
    public static void main(String[] args) throws Exception {
        URL url = new URL("http://localhost:8080/TestPost/TestServlet");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        //获取请求体输出流
        connection.setDoOutput(true);
        DataOutput dataOutput = new DataOutputStream(connection.getOutputStream());
        //向请求体写入数据
        dataOutput.write("param1=a&param2=b".getBytes(StandardCharsets.UTF_8));
        connection.connect();

        if (connection.getResponseCode() == 200) {
            System.out.println("POST请求成功");
        }
    }
}

上面代码演示了使用POST方式,向一个URL提交表单数据。实际上HttpURLConnection提供的接口比较底层,并没有区分POST的是表单还是二进制数据,统统使用OutputStream。这里POST的地址是一个Servlet编写的后台,后台可以正常收到POST的参数即:param1 = aparam2 = b

设置请求头

下面例子代码设置了User-Agent请求头。

connection.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0");

读取响应头

Map<String, List<String>> headerFields = connection.getHeaderFields();
for (String headerKey : headerFields.keySet()) {
    System.out.println(headerKey);
    for (String headerValue : headerFields.get(headerKey)) {
        System.out.println(headerValue);
    }
}

我们可以通过connection.getHeaderFields()拿到所有响应头信息的Map对象,然后读取即可。下面是Tomcat服务器默认的返回结果:

null
HTTP/1.1 200 OK
Server
Apache-Coyote/1.1
Content-Length
0
Date
Tue, 18 Jul 2017 14:11:06 GMT

使用Cookie

HttpURLConnection并没有提供和Cookie相关的API,但是这并不影响我们使用Cookie。当请求网页时,我们可以从响应头的Set-Cookie属性中,读取服务器向我们设置的所有Cookie。我们向服务器发起请求时,则可以在请求头中的Cookie属性中,带上需要发给服务器的Cookie。

我们可以自己使用Map存储Cookie,也可以使用JavaSE内置的java.net.CookieManager存储。

忽略HTTPS证书

在内网中如果用到HTTPS协议通常都会使用自签名证书,而非真实有效的证书,此时如果使用HttpURLConnection客户端访问证书存在错误的HTTPS服务时会报错,不过我们可以通过代码配置忽略HTTPS证书相关的问题。

TrustManager[] trustAllCertificates = new TrustManager[]{
        new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        }
};
try {
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustAllCertificates, new SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
    HttpsURLConnection.setDefaultHostnameVerifier((hostname, sslSession) -> true);
} catch (NoSuchAlgorithmException | KeyManagementException e) {
    e.printStackTrace();
}

当然,这种方式存在一定的安全风险,实际开发中我们应该结合具体需求合理进行设置。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap