Отправка HTTP запроса и сохранение файла из ответа (Java )

221
11 января 2018, 21:48

Есть URL.

Нужно чтобы был отправлен запрос : т.е. Java перешла по ссылке.

И получила ответ : в виде Wav файла,который необходимо воспроизвести.

Как это реализовать?Какие дополнительные библиотеки нужно подключить?

Посмотрел похожие темы,есть реализованная на PHP. Но нужна Java.

Отправить запрос насколько мне известно можно так :

   URL url = new URL("https://");
   url.openConnection();

А вот как полученный ответ в виде Waw файла сохранить и воспроизвести.Хотя сохранять необязательно.

ещё увидел вот такую конструкцию

 import java.applet.Applet;
 import java.applet.AudioClip;
 import java.net.URL;
  public class MainClass {
    public static void main(String[] args) {
      try {
        URL url = new URL("file:youraudiofile.wav" );
        AudioClip ac = Applet.newAudioClip(url);
        ac.play();
        System.out.println("Press any key to exit.");
        System.in.read();
        ac.stop();
      } catch (Exception e) {
        System.out.println(e);
      }
    }

Вся проблема в том,что когда переходишь по ссылке итоговая страница уже воспроизводит звук в браузере. А нужно чтобы Java сохранила файл,дала ему расширение.

Пример простой попытки включить аудио-файл:

package sayme;
import java.io.IOException;
import java.net.*;
import java.applet.*;
public class URLReader {
    public static void main(String a[]) {
        try {
           String str1 = "http://dll.zf.fm/music/f/7e/clean_bandit_feat_sean_paul__anne-marie_-_rockabye_(zf.fm).mp3";
  URL url = new URL(str1); // 1
            AudioClip clip = Applet.newAudioClip(url);
            clip.play();
        } catch (java.net.MalformedURLException e) {
            e.printStackTrace();
        }
    }
}

я не слышу звук,когда выполняется код. даже если после поставить вот так :

clip.play();
Thread.sleep(10000);

программа отработает 15 секунд и выключится.

программа отлично работает с файлами которые имеются в системе,а не в интернете. естественно,если перейти по этой ссылке в браузере - он включит это трек в браузере. А вот воспроизвести так сказать из кода он не даёт. В чем проблема?

Answer 1

Отправить запрос насколько мне известно можно так :

URL url = new URL("https://"); url.openConnection(); Цитата

Это не совсем так...

URL url = new URL("https://");

- просто создается инстанс URL.

url.openConnection();

- создается инстанс коннекта (URLCOnnection). Но никаких данных еще никуда не отправлено. Это только заготовка.

Помимо этого недурно еще установить параметры коннекта: будет ли он принимать/отправлять данные (setDoInput(), setDoInput()), метод запроса (GET, POST, PUT и т.д.), таймаут коннекта, указать заголовки запроса.

В качестве примера:

proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("<host>", <port>));
conn = (HttpURLConnection) url.openConnection(proxy);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setConnectTimeout(60000);
conn.setRequestMethod("GET");
// подготовили коннект
// Т.к. запрос у нас GET, то сразу принимаем входящие данные.
// Вот тут как раз (при открытии InputStream ) и происходит отправка GET запроса на сервер.
InputStream inStream = conn.getInputStream();
// Т.к. файл у нас бинарный, открываем ReadableByteChannel и создаем файл
ReadableByteChannel rbc = Channels.newChannel(conn.getInputStream());
FileOutputStream fos = new FileOutputStream("<имя_файла_для_сохранения>");
// Перенаправляем данные из ReadableByteChannel прямо канал файла.
// Говорят, так быстрее, чем по одному байту вычитывать из потока и писать в файл.
long filePosition = 0;
long transferedBytes = fos.getChannel().transferFrom(rbc, filePosition, Long.MAX_VALUE);
while(transferedBytes == Long.MAX_VALUE){
    filePosition += transferedBytes;
    transferedBytes = fos.getChannel().transferFrom(rbc, filePosition, Long.MAX_VALUE);
}
rbc.close();
fos.close();

Если прокси нет, то

 conn = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);

А вообще это хардкорный способ. Гораздо удобнее использовать библиотеку Apache HttpClient

Код грубоват, но должен с работать. Но сначала советую попробовать скачать файл на более простом ресурсе, где нет "охранных систем":

public class NewClass {
    public static void main(String[] args) throws IOException{
    HttpURLConnection conn = null;
    try{
        URL url = new URL("http://dll.zf.fm/music/f/7e/clean_bandit_feat_sean_paul__anne-marie_-_rockabye_(zf.fm).mp3");
        conn = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
        conn.setDoInput(true);
        //conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setConnectTimeout(60000);
        conn.setRequestMethod("GET");
        // подготовили коннект
        // Т.к. запрос у нас GET, то сразу принимаем входящие данные.
        // Вот тут как раз (при открытии InputStream ) и происходит отправка GET запроса на сервер.
        InputStream inStream = conn.getInputStream();
        // Т.к. файл у нас бинарный, открываем ReadableByteChannel и создаем файл
        ReadableByteChannel rbc = Channels.newChannel(conn.getInputStream());
        FileOutputStream fos = new FileOutputStream("qwe.mp3");
        // Перенаправляем данные из ReadableByteChannel прямо канал файла.
        // Говорят, так быстрее, чем по одному байту вычитывать из потока и писать в файл.
        long filePosition = 0;
        long transferedBytes = fos.getChannel().transferFrom(rbc, filePosition, Long.MAX_VALUE);
        while(transferedBytes == Long.MAX_VALUE){
            filePosition += transferedBytes;
            transferedBytes = fos.getChannel().transferFrom(rbc, filePosition, Long.MAX_VALUE);
        }
        rbc.close();
        fos.close();
    }catch(Exception e){
        InputStreamReader inStream = new InputStreamReader(conn.getErrorStream());
        char[] cbuf = new char[1];
        String result= "";
        BufferedReader in = new BufferedReader(inStream);
        while (in.read(cbuf) != -1) {
            result += String.valueOf(cbuf);
        }
        System.out.println("result:" + result);
    }
}

}

READ ALSO
запрос на чат покерклиента [требует правки]

запрос на чат покерклиента [требует правки]

Нужна информация из окна чата покерклиента, ее можно копировать, значит она где-то отображается в дереве процессовОдии из этих процессов...

140
Замена PageRequest в Spring 5 (Deprecated)

Замена PageRequest в Spring 5 (Deprecated)

При использовании PageRequest в Spring 5 его перечёркивает и пишет, что он DeprecatedПодскажите, чем теперь пользоваться в Spring вместо этого класса?

133
Потеря переноса строки при чтении файла в Android

Потеря переноса строки при чтении файла в Android

Я создаю поток записи в файл:

169