2017-01-28 19 views
2

Проблема заключается в том, что я знаю, как загрузить File из URL, например:Загрузить файл на Java с URL-адреса 1), где вы не знаете расширение [например .jpg] или 2) перенаправляется на файл

http://i12.photobucket.com/albums/a206/zxc6/1_zps3e6rjofn.jpg


Когда речь идет о файлах, как ниже:

https://images.duckduckgo.com/iu/?u=http%3......

I га Не знаю, как его загрузить.


код, я использую для загрузки файлов с IOUtils он прекрасно работает, если расширение видно, но в случае приведенного выше примера возвращает:

java.io.IOException: Server returned HTTP response code: 500 for URL: https://images.duckduckgo.com/iu/?u=http%3A%2F%2Fimages2.fanpop.com%2Fimage%2Fphotos%2F8900000%2FFirefox-firefox-8967915-1600-1200.jpg&f=1 

Даже если вы удалите &f=1.


Код для Downloader (Это для тестирования .... прототип):

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.URL; 
import java.net.URLConnection; 

import org.apache.commons.io.IOUtils; 

public class Downloader { 

    private static class ProgressListener implements ActionListener { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     // e.getSource() gives you the object of 
     // DownloadCountingOutputStream 
     // because you set it in the overriden method, afterWrite(). 
     System.out.println("Downloaded bytes : " + ((DownloadProgressListener) e.getSource()).getByteCount()); 
    } 
    } 

    /** 
    * Main Method 
    * 
    * @param args 
    */ 
    public static void main(String[] args) { 
    URL dl = null; 
    File fl = null; 
    String x = null; 
    OutputStream os = null; 
    InputStream is = null; 
    ProgressListener progressListener = new ProgressListener(); 
    try { 
     fl = new File(System.getProperty("user.home").replace("\\", "/") + "/Desktop/image.jpg"); 
     dl = new URL(
      "https://images.duckduckgo.com/iu/?u=http%3A%2F%2Fimages2.fanpop.com%2Fimage%2Fphotos%2F8900000%2FFirefox-firefox-8967915-1600-1200.jpg&f=1"); 
     os = new FileOutputStream(fl); 
     is = dl.openStream(); 

     // http://i12.photobucket.com/albums/a206/zxc6/1_zps3e6rjofn.jpg 

     DownloadProgressListener dcount = new DownloadProgressListener(os); 
     dcount.setListener(progressListener); 

     URLConnection connection = dl.openConnection(); 

     // this line give you the total length of source stream as a String. 
     // you may want to convert to integer and store this value to 
     // calculate percentage of the progression. 
     System.out.println("Content Length:" + connection.getHeaderField("Content-Length")); 
     System.out.println("Content Length with different way:" + connection.getContentType()); 

     System.out.println("\n"); 

     // begin transfer by writing to dcount, not os. 
     IOUtils.copy(is, dcount); 

    } catch (Exception e) { 
     System.out.println(e); 
    } finally { 
     IOUtils.closeQuietly(os); 
     IOUtils.closeQuietly(is); 
    } 
    } 
} 

Код для DownloadProgressListener:

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.IOException; 
import java.io.OutputStream; 

import org.apache.commons.io.output.CountingOutputStream; 

public class DownloadProgressListener extends CountingOutputStream { 

    private ActionListener listener = null; 

    public DownloadProgressListener(OutputStream out) { 
    super(out); 
    } 

    public void setListener(ActionListener listener) { 
    this.listener = listener; 
    } 

    @Override 
    protected void afterWrite(int n) throws IOException { 
    super.afterWrite(n); 
    if (listener != null) { 
     listener.actionPerformed(new ActionEvent(this, 0, null)); 
    } 
    } 

} 

Вопрос Я прочитал, прежде чем отправлять :

1) Download file from url that doesn't end with .extension

2) http://www.mkyong.com/java/how-to-get-url-content-in-java/

3) Download file using java apache commons?

4) How to download and save a file from Internet using Java?

5) How to create file object from URL object

+0

Это не имеет никакого отношения к расширению. – shmosel

+0

@shmosel Вы можете исправить заголовок, если я ошибаюсь. Вот как я, хотя это. Это связано с перенаправлением? – GOXR3PLUS

+0

Как указал шмосель, расширение не имеет значения.Проблема заключается в попытке загрузить что-то, что, вероятно, является перенаправлением или другим запросом. Я не уверен в каком-либо простом решении, но если вы посмотрите на: https://images.duckduckgo.com/iu/?u=http%3A%2F%2Fimages2.fanpop.com%2Fimage%2Fphotos%2F8900000% 2FFirefox-firefox-8967915-1600-1200.jpg & f = 1', на самом деле есть URL-адрес изображения, которое вы можете проанализировать. –

ответ

3

Как было отмечено в комментарии, расширение не имеет значения.

Проблема здесь заключается в попытке загрузить что-то, что, вероятно, является перенаправлением или, возможно, просто параметрами асинхронного вызова.

Ваш Очень большой URL-адрес без расширения не работает, но я могу ответить на потенциальное решение для другого типа.

Если вы наблюдаете URL:

https://images.duckduckgo.com/iu/?u=http%3A%2F%2Fimages2.fan‌​pop.com%2Fimage%2Fph‌​otos%2F8900000%2FFir‌​efox-firefox-8967915‌​-1600-1200.jpg&f=1

URL, к изображению на самом деле есть. Он просто закодирован и должен быть довольно легко декодироваться. В Java есть библиотеки расшифровки (java.net.Раскодирования URL-адресов), но если вы хотите сделать это самостоятельно, вы можете посмотреть на это так:

http%3A%2F%2Fimages2.fan‌​pop.com%2Fimage%2Fph‌​otos%2F8900000%2FFir‌​efox-firefox-8967915‌​-1600-1200.jpg&f=1

кодированные порции %XX где XX любые два символа. Глядя на таблицу кодирования HTML, вы увидите, что %3A - это, очевидно, двоеточие. %2F - это косая черта.

Если заменить все закодированные объекты, вы в конечном итоге с: http://images2.fan‌​pop.com/image/ph‌​otos/8900000/Fir‌​efox-firefox-8967915‌​-1600-1200.jpg&f=1

В этом случае, вы не хотите, дополнительные параметры, так что вы можете отказаться от &f=1 и загрузить изображение из исходный URL. В большинстве случаев, я думаю, вы можете сохранить дополнительный параметр, и его просто проигнорируют.

-

В двух словах:

  1. Извлечь оригинальный URL
  2. Расшифруйте это
  3. Скачать

Я хотел бы отметить, что это хрупкое и будет разорваться, если шаблон URL изменится, или потребуется много обслуживания. Если вы ориентируетесь на более чем небольшую группу пользователей, вы должны пересмотреть свой подход.

HTML URL encoding table

+0

Спасибо, Кристофер, теперь я понимаю это, прочитав приведенные ссылки и успешно загрузил изображение. Я выполняю шаги, которые вы указали в конце 1,2,3. Трудная часть 1, как извлечь исходный URL ....? Например, здесь вы получили «http: //images2.fan pop.com/image/ph otos/8900000/Fir efox-firefox-8967915 -1600-1200.jpg & f = 1' после разреза части декодированной url ... ('https: //images.duckduckgo.com/iu/? u =')] 2 и 3 сделаны легко. – GOXR3PLUS

+0

Я не уверен, что смогу ответить на этот вопрос. Вы хотите загрузить из нескольких мест? Это просто duckduckgo? Вам нужно выяснить, как извлечь URL-адрес в зависимости от источника. Если посмотреть на URL-адрес, если он всегда префикс каждого URL-адреса изображения с помощью 'https: //images.duckduckgo.com/iu/? U =', вы можете просто отрезать это с начала строки, и все готово. Вы также можете искать 'http% 3A% 2F% 2F' и использовать это как начало URL-адреса. Регулярно было бы хорошо. Посмотрите на 'java.util.regex.Matcher'. В частности 'find()' и 'start()' –

+0

Повторное чтение вашего комментария, я не думаю, что я обратился к нему. Как я уже сказал в своем первоначальном комментарии к вашему вопросу, нет простого решения, и я не уверен, как вы на самом деле это реализуете. Если все, что у вас есть, это URL-адреса, вам нужно создать какой-то алгоритм, который сможет анализировать URL-адреса и попытаться найти URL-адреса, встроенные в эти URL-адреса. –

3

Если вы хотите «быстрый и грязный» способ решения проблемы, посмотрите на ответ @Christopher Шнайдера. (Но это может сломаться, если изменяется синтаксис URL-адреса DuckDuckGo ...)

Я немного поработал (используя curl --trace-ascii и т. Д.). Это не проблема с перенаправлением. Согласно curl, 500 - это немедленный ответ на запрос.

Так что я лучше всего предполагаю, что это поведение «по дизайну». Сервер просматривает заголовки запросов (например, заголовок «User-Agent») и решает, что ваш запрос не выглядит так, как будто он поступает из поддерживаемого браузера. Ответ 500 - преднамеренное или случайное обфускация.

Почему?

Скорее всего, люди, которые запускают DuckDuckGo, не хотят, чтобы вы использовали эту конечную точку сервера для автоматической загрузки, очистки, что угодно. Они не совсем ясно об этом, но эта связь идет некоторый путь к объяснению:

решение?

Не делайте этого! Посмотрите, можете ли вы делать то, что вы пытаетесь сделать, используя свои официальные API (см. Выше). Если это не сработает, свяжитесь с ними.

+0

Я хочу, чтобы пользователь мог загружать обычно файлы с помощью моего приложения. Таким образом, проблема кажется сложной, но благодаря Кристоперу ответ мне удалось найти обходной путь :). Также используя найденный код (http://www.mkyong.com/java/java-httpurlconnection-follow-redirect-example/), я вижу, что 'html.toString()' возвращает код изображения '.jpg' поэтому я попытался использовать FileWriter и экспортировал его в «Файл», который сохранил его как. .jpg. Когда попытался открыть его с помощью Painter, это не сработает ... Странно .. – GOXR3PLUS

+0

+1. Я согласен с этим ответом. Мой ответ был определенно «быстрым и грязным», но я отвечал на основе предоставленной информации, которая была URL-строкой. Я написал много сценариев, чтобы делать такие вещи, но я пишу только для них и, возможно, для нескольких других разработчиков со звездочкой, что они хрупкие и в какой-то момент сломаются. Если @ GOXR3PLUS хочет написать законное программное обеспечение, ориентированное на потребителя, они должны отказаться от своей идеи и следовать этому ответу. –