通过java代理下载文件

通过java代理下载文件,java,http,proxy,stream,connection,Java,Http,Proxy,Stream,Connection,我通过代理从url(如www.example.com/example.pdf)下载文件并将其保存在java文件系统中时遇到问题。有人知道这是怎么回事吗?如果我得到InputStream,我可以简单地使用以下命令将其保存到文件系统: final ReadableByteChannel rbc = Channels.newChannel(httpUrlConnetion.getInputStream()); final FileOutputStream fos = new FileOutpu

我通过代理从url(如
www.example.com/example.pdf
)下载文件并将其保存在java文件系统中时遇到问题。有人知道这是怎么回事吗?如果我得到InputStream,我可以简单地使用以下命令将其保存到文件系统:

final ReadableByteChannel rbc = Channels.newChannel(httpUrlConnetion.getInputStream());    
final FileOutputStream fos = new FileOutputStream(file);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
但如何通过prox获取url的输入流呢? 如果我是这样做的:

SocketAddress addr = new InetSocketAddress("my.proxy.com", 8080);
Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
URL url = new URL("http://my.real.url.com/");
URLConnection conn = url.openConnection(proxy);
我得到一个例外:

java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.io.BufferedInputStream.fill(Unknown Source)
    at java.io.BufferedInputStream.read1(Unknown Source)
    at java.io.BufferedInputStream.read(Unknown Source)
    at sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source)
    at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
    at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at app.model.mail.crawler.newimpl.FileLoader.getSourceOfSiteViaProxy(FileLoader.java:167)
    at app.model.mail.crawler.newimpl.FileLoader.process(FileLoader.java:220)
    at app.model.mail.crawler.newimpl.FileLoader.run(FileLoader.java:57)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
使用此选项:

final HttpURLConnection httpUrlConnetion = (HttpURLConnection) website.openConnection(proxy);
httpUrlConnetion.setDoOutput(true);
httpUrlConnetion.setDoInput(true);
httpUrlConnetion.setRequestProperty("Content-type", "text/xml");
httpUrlConnetion.setRequestProperty("Accept", "text/xml, application/xml");
httpUrlConnetion.setRequestMethod("POST");
httpUrlConnetion.connect();

我可以下载html网站的源代码,但不能下载文件。也许有人可以帮助我设置下载文件所需的属性。

要以编程方式设置代理,请执行以下操作:

SocketAddress addr = new InetSocketAddress("my.proxy.com", 8080);
Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
URL url = new URL("http://my.real.url.com/");
URLConnection conn = url.openConnection(proxy);
然后,您可以将上面的代码与最后一行返回的
URLConnection
一起使用。如果您愿意,还可以使用SOCKS代理或强制不使用代理


这是从中获取的(并稍加编辑)。

可以使用ApacheHttpClient库来解决代理的大部分问题。要编译下面的代码,可以使用以下maven:

马文:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>stackoverflow.test</groupId>
  <artifactId>proxyhttp</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>proxy</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>4.5.1</version>
    </dependency>
  </dependencies>
</project>

以下内容与其他答案不同,并且对我有效:在连接之前设置这些属性:

            System.getProperties().put("http.proxySet", "true");
            System.getProperties().put("http.proxyHost", "my.proxy.com");
            System.getProperties().put("http.proxyPort", "8080"); //port is String, not int

然后,打开URLConnection并尝试下载文件。

另一种方法是在httpUrlConnection的每个实例内部实现代理。即:

  • 不要连接到您想要的真实URL。首先,连接到代理IP和端口,但使用http GET方法引用所需的URL
  • 使用setRequestProperty主机设置为URL和可能需要的任何其他标头
  • 如果成功,连接将透明地将文件发送给您

    我有一些使用套接字的代码

    try {
        Socket sock = new Socket("10.0.241.1", 3128); //proxy IP and port
        InputStream is = sock.getInputStream();
        OutputStream os = sock.getOutputStream();
        String str = "GET http://www.uol.com.br HTTP/1.1\r\n"; //GET your site
        str += "Host: www.uol.com.br\r\n"; //again, Host of your site
        str += "Proxy-Authorization: Basic ZWR1YXJkby5wb2NvOmM1NmQyMw==\r\n"; //if password is needed
        str += "\r\n";
        os.write(str.getBytes());
        byte[] bb = new byte[1024];
        int L = 0;
        while ((L = is.read(bb)) != -1) {
            //write bytes to file stream...
        }
    } catch (Exception ex) {
        //exception handling...
    }
    


    你会说:“当一个人可以使用httpUrlConnection时,为什么有人会使用纯套接字呢?”。嗯,到那时,我还不知道httpUrlConnection。

    如果您只需要设置代理设置,请参阅Oracle,或者如果您想切入主题,.系统属性将无法工作,因为我想在执行下载的每个线程中使用不同的代理。因此,我必须为每个连接设置代理。上面的Oracle文档指定了如何执行此操作。我已经添加了一个带有一些示例代码的答案。它对我不起作用,它给了我一个例外,可能这不是代理的问题。有关此错误的原因列表,请参阅。我猜是一个超时,为了检查,请尝试下载一个非常小的文件。如果我这样做,我会遇到一个异常,请再次查看我的问题,我将编辑iTunes。很难说在您的情况下为什么会重置连接。您是否尝试过使用相同的代理设置在浏览器中访问URL,并确保它在浏览器中工作?您是否使用了正确类型的代理(SOCKS vs.HTTP)?我使用的是SOCKS是的,我使用了,它工作正常。。。我现在尝试了很多其他网站,但都没有成功。您是否将代码中的
    Proxy.Type.HTTP
    更改为
    Proxy.Type.SOCKS
    ?为了以防万一,你可以两个都试一下。嗯,我不确定。我假设您已经在代码中验证了代理主机和端口。除此之外,我不知道该提出什么建议(我在不同的线程中使用不同的代理,所以这不起作用。我得到一个HTTP响应代码:411、读取超时或连接超时……有什么想法吗?@Exagon我已经更新了代码,因为上次我使用了我为旧版本编写的代码,使用的类都不推荐使用。我使用fiddler2作为代理重新测试了代码。这是正确的。)工作正常。如果超时,则可能是“网络错误”问题。顺便说一句,该示例只是“复制并粘贴”的:抱歉,但我在请求时遇到错误。setConfig(config);“类型HttpGet的方法setConfig(RequestConfig)未定义”@如果你不想使用maven,你可以从以下网站下载我使用的版本:你能用一些代码演示如何处理所有属性吗?答案中编辑了。这个实现是从我不知道httpUrlConnection的时候开始的,所以使用了sockets。编辑很匆忙吗您可以计算httpUrlConnection上的等效操作。如果需要,我将再次编辑它以适合httpUrlConnection。
    try {
        Socket sock = new Socket("10.0.241.1", 3128); //proxy IP and port
        InputStream is = sock.getInputStream();
        OutputStream os = sock.getOutputStream();
        String str = "GET http://www.uol.com.br HTTP/1.1\r\n"; //GET your site
        str += "Host: www.uol.com.br\r\n"; //again, Host of your site
        str += "Proxy-Authorization: Basic ZWR1YXJkby5wb2NvOmM1NmQyMw==\r\n"; //if password is needed
        str += "\r\n";
        os.write(str.getBytes());
        byte[] bb = new byte[1024];
        int L = 0;
        while ((L = is.read(bb)) != -1) {
            //write bytes to file stream...
        }
    } catch (Exception ex) {
        //exception handling...
    }