来自URL的InputStream

问题描述 投票:101回答:6

如何从URL获取InputStream?

例如,我想将文件放在url wwww.somewebsite.com/a.txt上,并通过servlet将其作为Java中的InputStream读取。

我试过了

InputStream is = new FileInputStream("wwww.somewebsite.com/a.txt");

但我得到的是一个错误:

java.io.FileNotFoundException
java url inputstream
6个回答
199
投票

使用java.net.URL#openStream()和正确的URL(包括协议!)。例如。

InputStream input = new URL("http://www.somewebsite.com/a.txt").openStream();
// ...

See also:


16
投票

尝试:

final InputStream is = new URL("http://wwww.somewebsite.com/a.txt").openStream();

10
投票

(a)wwww.somewebsite.com/a.txt不是'文件网址'。它根本不是URL。如果你把http://放在它的前面,它将是一个HTTP URL,这显然是你想要的。

(b)FileInputStream用于文件,而不是URL。

(c)从任何URL获取输入流的方法是通过URL.openStream(),URL.getConnection().getInputStream(),这是等效的,但你可能有其他理由得到URLConnection并首先使用它。


4
投票

您的原始代码使用FileInputStream,用于访问文件系统托管文件。

您使用的构造函数将尝试在当前工作目录的www.somewebsite.com子文件夹中找到名为a.txt的文件(系统属性user.dir的值)。您提供的名称使用File类解析为文件。

URL对象是解决此问题的通用方法。您可以使用URL访问本地文件,也可以使用网络托管资源。除了http://或https://之外,URL类还支持file://协议,因此您可以继续使用。


2
投票

纯Java:

 urlToInputStream(url,httpHeaders);

有了一些成功,我使用这种方法。它处理重定向,并且可以传递可变数量的HTTP头asMap<String,String>。它还允许从HTTP重定向到HTTPS。

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);
    }
}

完整的示例电话

private InputStream getInputStreamFromUrl(URL url, String user, String passwd) throws IOException {
        String encoded = Base64.getEncoder().encodeToString((user + ":" + passwd).getBytes(StandardCharsets.UTF_8));
        Map<String,String> httpHeaders=new Map<>();
        httpHeaders.put("Accept", "application/json");
        httpHeaders.put("User-Agent", "myApplication");
        httpHeaders.put("Authorization", "Basic " + encoded);
        return urlToInputStream(url,httpHeaders);
    }

-1
投票

这是一个完整的示例,它读取给定网页的内容。从HTML表单中读取网页。我们使用标准的InputStream类,但使用JSoup库可以更轻松地完成。

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>

</dependency>

<dependency>
    <groupId>commons-validator</groupId>
    <artifactId>commons-validator</artifactId>
    <version>1.6</version>
</dependency>  

这些是Maven依赖项。我们使用Apache Commons库来验证URL字符串。

package com.zetcode.web;

import com.zetcode.service.WebPageReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "ReadWebPage", urlPatterns = {"/ReadWebPage"})
public class ReadWebpage extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/plain;charset=UTF-8");

        String page = request.getParameter("webpage");

        String content = new WebPageReader().setWebPageName(page).getWebPageContent();

        ServletOutputStream os = response.getOutputStream();
        os.write(content.getBytes(StandardCharsets.UTF_8));
    }
}

ReadWebPage servlet读取给定网页的内容,并以纯文本格式将其发送回客户端。阅读页面的任务委托给WebPageReader

package com.zetcode.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.apache.commons.validator.routines.UrlValidator;

public class WebPageReader {

    private String webpage;
    private String content;

    public WebPageReader setWebPageName(String name) {

        webpage = name;
        return this;
    }

    public String getWebPageContent() {

        try {

            boolean valid = validateUrl(webpage);

            if (!valid) {

                content = "Invalid URL; use http(s)://www.example.com format";
                return content;
            }

            URL url = new URL(webpage);

            try (InputStream is = url.openStream();
                    BufferedReader br = new BufferedReader(
                            new InputStreamReader(is, StandardCharsets.UTF_8))) {

                content = br.lines().collect(
                      Collectors.joining(System.lineSeparator()));
            }

        } catch (IOException ex) {

            content = String.format("Cannot read webpage %s", ex);
            Logger.getLogger(WebPageReader.class.getName()).log(Level.SEVERE, null, ex);
        }

        return content;
    }

    private boolean validateUrl(String webpage) {

        UrlValidator urlValidator = new UrlValidator();

        return urlValidator.isValid(webpage);
    }
}

WebPageReader验证URL并读取网页的内容。它返回一个包含页面HTML代码的字符串。

<!DOCTYPE html>
<html>
    <head>
        <title>Home page</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <form action="ReadWebPage">

            <label for="page">Enter a web page name:</label>
            <input  type="text" id="page" name="webpage">

            <button type="submit">Submit</button>

        </form>
    </body>
</html>

最后,这是包含HTML表单的主页。这是从我的tutorial关于这个主题。

© www.soinside.com 2019 - 2024. All rights reserved.