programing

URL로부터의 InputStream

projobs 2022. 10. 21. 22:01
반응형

URL로부터의 InputStream

URL에서 InputStream을 가져오려면 어떻게 해야 하나요?

예를 들어, 저는 url에 있는 파일을 가져가고 싶습니다.wwww.somewebsite.com/a.txt서블릿을 통해 Java의 InputStream으로 읽습니다.

해봤어요

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

하지만 내가 받은 건 오류였어

java.io.FileNotFoundException

올바른 URL(프로토콜 포함)과 함께 사용합니다.예.

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

다음 항목도 참조하십시오.

시험:

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

(a)wwww.somewebsite.com/a.txt는 '파일 URL'이 아닙니다.전혀 URL이 아닙니다.를 붙이면http://그 앞면에는 HTTP URL이 표시됩니다.이것은, 여기서 의도하고 있는 것이 분명합니다.

(b)FileInputStream파일용이지 URL이 아닙니다.

(c) 임의의 URL에서 입력 스트림을 얻는 방법은URL.openStream(),또는URL.getConnection().getInputStream(),그건 동일하지만 다른 이유가 있을 수 있습니다.URLConnection먼저 가지고 놀아요.

원래 코드는 파일 시스템 호스트 파일에 액세스하기 위한 FileInputStream을 사용합니다.

사용한 컨스트럭터는 현재 작업 디렉토리의 www.somewebsite.com 서브폴더(시스템 속성 user.txt 값)에서 a.txt라는 이름의 파일을 찾으려고 합니다.지정한 이름이 파일 클래스를 사용하여 파일로 확인됩니다.

URL 오브젝트는 이 문제를 해결하는 일반적인 방법입니다.URL을 사용하여 로컬 파일에 액세스할 수 있을 뿐만 아니라 네트워크 호스팅된 리소스에도 액세스할 수 있습니다.URL 클래스는 http:// 또는 https:/ 외에 파일:// 프로토콜을 지원하므로 사용할 수 있습니다.

순수 자바:

 urlToInputStream(url,httpHeaders);

어느 정도 성공해서 나는 이 방법을 사용한다.리다이렉트를 처리하여 다양한 수의 HTTP 헤더를 전달할 수 있습니다.Map<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);
    }

다음은 지정된 웹 페이지의 내용을 읽는 전체 예입니다.웹 페이지는 HTML 양식에서 읽습니다.스탠다드 사용InputStreamJSoup 라이브러리를 사용하면 더 쉽게 할 수 있습니다.

<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>  

이것들은 메이븐 의존관계입니다.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));
    }
}

ReadWebPageservlet은 지정된 웹 페이지의 내용을 읽고 일반 텍스트 형식으로 클라이언트에 반환합니다.페이지를 읽는 작업은 다음에게 위임됩니다.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 양식을 포함하는 홈페이지입니다.이것은 이 토픽에 관한 튜토리얼에서 인용한 것입니다.

언급URL : https://stackoverflow.com/questions/6932369/inputstream-from-a-url

반응형