web-dev-qa-db-ja.com

Javaコードの数行で文字列へのURLを読み取ります

GroovyのJavaに相当するものを見つけようとしています。

String content = "http://www.google.com".toURL().getText();

URLのコンテンツを文字列に読み取りたい。このような単純なタスクのために、バッファされたストリームとループでコードを汚染したくありません。 ApacheのHttpClientを調べましたが、1行または2行の実装も見当たりません。

136
Pomponius

元の答えが受け入れられてから時間が経った今、より良いアプローチがあります:

String out = new Scanner(new URL("http://www.google.com").openStream(), "UTF-8").useDelimiter("\\A").next();

1行ではない、少し充実した実装が必要な場合は、次のようにします。

public static String readStringFromURL(String requestURL) throws IOException
{
    try (Scanner scanner = new Scanner(new URL(requestURL).openStream(),
            StandardCharsets.UTF_8.toString()))
    {
        scanner.useDelimiter("\\A");
        return scanner.hasNext() ? scanner.next() : "";
    }
}
116
ccleve

この回答は、Javaの古いバージョンに関するものです。 ccleveの回答をご覧ください。


これを行う従来の方法は次のとおりです。

import Java.net.*;
import Java.io.*;

public class URLConnectionReader {
    public static String getText(String url) throws Exception {
        URL website = new URL(url);
        URLConnection connection = website.openConnection();
        BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                    connection.getInputStream()));

        StringBuilder response = new StringBuilder();
        String inputLine;

        while ((inputLine = in.readLine()) != null) 
            response.append(inputLine);

        in.close();

        return response.toString();
    }

    public static void main(String[] args) throws Exception {
        String content = URLConnectionReader.getText(args[0]);
        System.out.println(content);
    }
}

@extraneonが示唆しているように、 ioutils を使用すると、Java精神にある非常に雄弁な方法でこれを行うことができます。

 InputStream in = new URL( "http://jakarta.Apache.org" ).openStream();

 try {
   System.out.println( IOUtils.toString( in ) );
 } finally {
   IOUtils.closeQuietly(in);
 }
93
Joseph Weissman

または、Apache Commons IOUtils.toString(URL url) 、またはエンコードパラメーターを受け入れるバリアントを使用します。

69
steve

時間が経過したので、Java 8でそれを行う方法を次に示します。

URLConnection conn = url.openConnection();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
    pageText = reader.lines().collect(Collectors.joining("\n"));
}
19
Jeanne Boyarsky

グアバを使用した追加の例:

URL xmlData = ...
String data = Resources.toString(xmlData, Charsets.UTF_8);
8
takacsot

Java 9以降、さらに良い方法があります。

URL u = new URL("http://www.example.com/");
try (InputStream in = u.openStream()) {
    return new String(in.readAllBytes(), StandardCharsets.UTF_8);
}

元のgroovyの例と同様に、これはコンテンツがUTF-8でエンコードされていることを前提としています。 (それよりも賢い何かが必要な場合は、URLConnectionを作成し、それを使用してエンコードを計算する必要があります。)

7
Sean Reilly

入力ストリームがある場合(Joeの答えを参照)、ioutils.toString(inputstream)も検討してください。

http://commons.Apache.org/io/api-1.4/org/Apache/commons/io/IOUtils.html#toString(Java.io.InputStream

4
extraneon

以下はJava 7/8のセキュアURLで動作し、リクエストにCookieを追加する方法も示しています。これは主に このページの他のすばらしい回答 の直接コピーですが、Cookieの例を追加し、安全なURLでも動作するという点で明確になっていることに注意してください;-)

無効な証明書または自己署名証明書を使用してサーバーに接続する必要がある場合、証明書をインポートしない限り、セキュリティエラーがスローされます。この機能が必要な場合は、 この回答で詳しく説明されているアプローチを検討してください これに StackOverflowの関連質問

String result = getUrlAsString("https://www.google.com");
System.out.println(result);

出力

<!doctype html><html itemscope="" .... etc

コード

import Java.net.URL;
import Java.net.URLConnection;
import Java.io.BufferedReader;
import Java.io.InputStreamReader;

public static String getUrlAsString(String url)
{
    try
    {
        URL urlObj = new URL(url);
        URLConnection con = urlObj.openConnection();

        con.setDoOutput(true); // we want the response 
        con.setRequestProperty("Cookie", "myCookie=test123");
        con.connect();

        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));

        StringBuilder response = new StringBuilder();
        String inputLine;

        String newLine = System.getProperty("line.separator");
        while ((inputLine = in.readLine()) != null)
        {
            response.append(inputLine + newLine);
        }

        in.close();

        return response.toString();
    }
    catch (Exception e)
    {
        throw new RuntimeException(e);
    }
}
3
Brad Parks

ジャンヌの素敵な答えはここにありますが、私のようなマペットのためのきちんとした機能に包まれています。

private static String getUrl(String aUrl) throws MalformedURLException, IOException
{
    String urlData = "";
    URL urlObj = new URL(aUrl);
    URLConnection conn = urlObj.openConnection();
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) 
    {
        urlData = reader.lines().collect(Collectors.joining("\n"));
    }
    return urlData;
}
2
Dave

Pure Javaの文字列へのURL

コール例

 String str = getStringFromUrl("YourUrl");

実装

InputStreamのURLを読み取る方法 でこの回答に記載されているメソッドを使用し、 InputStreamをStringに読み取る方法 でこの回答と組み合わせることができます。

結果は次のようになります

public String getStringFromUrl(URL url) throws IOException {
        return inputStreamToString(urlToInputStream(url,null));
}

public String inputStreamToString(InputStream inputStream) throws IOException {
    try(ByteArrayOutputStream result = new ByteArrayOutputStream()) {
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            result.write(buffer, 0, length);
        }

        return result.toString(UTF_8);
    }
}

private InputStream urlToInputStream(URL url, Map<String, String> args) {
    HttpURLConnection con = null;
    InputStream inputStream = null;
    try {
        con = (HttpURLConnection) url.openConnection();
        con.setConnectTimeout(15000);
        con.setReadTimeout(15000);
        if (args != null) {
            for (Entry<String, String> e : args.entrySet()) {
                con.setRequestProperty(e.getKey(), e.getValue());
            }
        }
        con.connect();
        int responseCode = con.getResponseCode();
        /* By default the connection will follow redirects. The following
         * block is only entered if the implementation of HttpURLConnection
         * does not perform the redirect. The exact behavior depends to 
         * the actual implementation (e.g. Sun.net).
         * !!! Attention: This block allows the connection to 
         * switch protocols (e.g. HTTP to HTTPS), which is <b>not</b> 
         * default behavior. See: https://stackoverflow.com/questions/1884230 
         * for more info!!!
         */
        if (responseCode < 400 && responseCode > 299) {
            String redirectUrl = con.getHeaderField("Location");
            try {
                URL newUrl = new URL(redirectUrl);
                return urlToInputStream(newUrl, args);
            } catch (MalformedURLException e) {
                URL newUrl = new URL(url.getProtocol() + "://" + url.getHost() + redirectUrl);
                return urlToInputStream(newUrl, args);
            }
        }
        /*!!!!!*/

        inputStream = con.getInputStream();
        return inputStream;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

長所

  • 純粋なJavaです

  • (上記の例のようにnullオブジェクトを渡す代わりに)さまざまなヘッダー、認証などを追加することにより、簡単に拡張できます。

  • プロトコルスイッチの処理がサポートされています

0
jschnasse