杰瑞科技汇

Java如何实现HTTP代理?

Of course! Here is a comprehensive guide on how to use HTTP proxies in Java, covering the most common scenarios.

An HTTP proxy acts as an intermediary between your Java application and the internet. When you configure a proxy, all your HTTP/HTTPS requests are sent to the proxy server first, which then forwards them to the destination.

Why Use a Proxy?

  • Bypass Geo-restrictions: Access content that is region-locked.
  • Anonymity: Hide your real IP address.
  • Security: Filter traffic, scan for malware, or log requests.
  • Caching: Speed up access to frequently visited websites.
  • Content Filtering: Block access to certain websites or types of content.

Method 1: Using java.net.HttpURLConnection (Java Standard Library)

This is the most fundamental way to make HTTP requests in Java. Setting a proxy here affects only the connection you create.

Step-by-Step Example

  1. Create a Proxy object: You need to specify the proxy type (usually Proxy.Type.HTTP), its hostname (or IP address), and its port number.
  2. Set the proxy on the connection: Before opening the connection, call connection.setProxy(proxy).
  3. Handle Authentication (if needed): If the proxy requires a username and password, you must set the Proxy-Authorization header.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.URL;
import java.net.HttpURLConnection;
public class HttpURLConnectionProxyExample {
    public static void main(String[] args) {
        // --- Proxy Configuration ---
        String proxyHost = "proxy.example.com";
        int proxyPort = 8080;
        String proxyUser = "myusername";
        String proxyPassword = "mypassword";
        // --- Target URL ---
        String targetUrl = "https://httpbin.org/ip"; // A service that returns your IP
        try {
            // 1. Create a Proxy object
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
            // 2. Create a URL object
            URL url = new URL(targetUrl);
            // 3. Open the connection and set the proxy
            HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);
            // 4. Handle Proxy Authentication
            Authenticator.setDefault(new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    if (getRequestingHost().equals(proxyHost) && getRequestingPort() == proxyPort) {
                        return new PasswordAuthentication(proxyUser, proxyPassword.toCharArray());
                    }
                    return null;
                }
            });
            // 5. Set request method and headers
            connection.setRequestMethod("GET");
            connection.setRequestProperty("User-Agent", "Java-HttpURLConnection-Proxy-Example");
            // 6. Get the response code
            int responseCode = connection.getResponseCode();
            System.out.println("Response Code: " + responseCode);
            // 7. Read the response
            if (responseCode == HttpURLConnection.HTTP_OK) { // success
                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String inputLine;
                StringBuilder response = new StringBuilder();
                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();
                // Print the response (should show the proxy's IP, not yours)
                System.out.println("Response from server:");
                System.out.println(response.toString());
            } else {
                System.out.println("GET request failed. Response Code: " + responseCode);
            }
        } catch (IOException e) {
            System.err.println("Error during HTTP request: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Method 2: Using Apache HttpClient (Recommended for Modern Applications)

Apache HttpClient is a powerful, flexible, and widely-used library for HTTP communication. It provides a cleaner API and better features than HttpURLConnection.

Step-by-Step Example

  1. Add Dependency: If you're using a build tool like Maven or Gradle, add the HttpClient dependency.

    Maven (pom.xml):

    <dependency>
        <groupId>org.apache.httpcomponents.client5</groupId>
        <artifactId>httpclient5</artifactId>
        <version>5.3.1</version> <!-- Use the latest version -->
    </dependency>
  2. Create a HttpHost for the Proxy: This represents the proxy server.

  3. Create a RequestConfig and set the proxy: This configures how the request should be made, including the proxy.

  4. Build and execute the request: Apply the config to your request.

import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.net.URIBuilder;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class HttpClientProxyExample {
    public static void main(String[] args) {
        // --- Proxy Configuration ---
        String proxyHost = "proxy.example.com";
        int proxyPort = 8080;
        String proxyUser = "myusername";
        String proxyPassword = "mypassword";
        // --- Target URL ---
        String targetUrl = "https://httpbin.org/ip";
        // 1. Create a proxy HttpHost
        org.apache.hc.client5.http.protocol.HttpHost proxy = new org.apache.hc.client5.http.protocol.HttpHost(proxyHost, proxyPort);
        // 2. Build RequestConfig with proxy and authentication
        RequestConfig config = RequestConfig.custom()
                .setProxy(proxy)
                .setProxyPreferredAuthScheme("Basic") // or "Digest"
                .build();
        // 3. Create a HttpClient with the custom config
        try (CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(config)
                // For preemptive proxy authentication (often needed)
                .setProxyAuthenticationStrategy(new org.apache.hc.client5.http.auth.ProxyAuthenticationStrategy())
                .build()) {
            // 4. Create the HTTP GET request
            HttpGet request = new HttpGet(targetUrl);
            // 5. Execute the request and get the response
            try (CloseableHttpResponse response = httpClient.execute(request)) {
                System.out.println("Response Code: " + response.getCode());
                // 6. Read the response body
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String result = EntityUtils.toString(entity);
                    System.out.println("Response from server:");
                    System.out.println(result);
                }
                EntityUtils.consume(entity); // Ensure the entity is fully consumed and connection is released
            }
        } catch (IOException e) {
            System.err.println("Error during HTTP request: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Note: For proxy authentication, HttpClient can use an AuthScope and CredentialsProvider for more granular control, which is the recommended approach for complex scenarios.


Method 3: System-wide Proxy Settings (JVM Properties)

Sometimes, you want to set a proxy for all HTTP connections made by your entire Java Virtual Machine (JVM), not just a specific connection. This is useful for libraries or frameworks that use the standard java.net package.

You can set these properties via command-line arguments or programmatically.

Command-Line Arguments

java -Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=8080 -Dhttps.proxyHost=proxy.example.com -Dhttps.proxyPort=8080 -Dhttp.proxyUser=myusername -Dhttp.proxyPassword=mypassword YourClassName

Programmatically (Java Code)

public class SystemProxyExample {
    public static void main(String[] args) {
        // --- Proxy Configuration ---
        String proxyHost = "proxy.example.com";
        int proxyPort = 8080;
        String proxyUser = "myusername";
        String proxyPassword = "mypassword";
        // --- Set System Properties ---
        System.setProperty("http.proxyHost", proxyHost);
        System.setProperty("http.proxyPort", String.valueOf(proxyPort));
        System.setProperty("https.proxyHost", proxyHost);
        System.setProperty("https.proxyPort", String.valueOf(proxyPort));
        System.setProperty("http.proxyUser", proxyUser);
        System.setProperty("http.proxyPassword", proxyPassword);
        // Now, any HttpURLConnection created will automatically use this proxy
        try {
            URL url = new URL("https://httpbin.org/ip");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            int responseCode = connection.getResponseCode();
            System.out.println("Response Code: " + responseCode);
            if (responseCode == HttpURLConnection.HTTP_OK) {
                try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                    String inputLine;
                    StringBuilder response = new StringBuilder();
                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    System.out.println("Response from server:");
                    System.out.println(response.toString());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Summary: Which Method to Choose?

Method Best For Pros Cons
HttpURLConnection Simple scripts, quick tests, avoiding external libraries. Part of Java standard library, no setup needed. Verbose API, less flexible, manual authentication.
Apache HttpClient Production applications, complex HTTP needs (retries, redirects, async). Powerful, flexible, modern API, excellent authentication handling. Requires adding an external dependency.
System Properties Setting a global proxy for the entire JVM or when you can't modify library code. Affects all connections automatically, simple to set. Less control, can interfere with other parts of the application.
分享:
扫描分享到社交APP
上一篇
下一篇