Заставить HttpURLConnection загружать веб-страницы с изображениями

В настоящее время я использую HttpURLConnection для загрузки удаленной веб-страницы и представления своим клиентам (используя передачу InputStream в HttpResponse outputStream), он правильно загружает html, но пропускает изображения, как это исправить?

Спасибо


person Fagoter    schedule 08.06.2011    source источник


Ответы (2)


Вам нужно манипулировать HTML таким образом, чтобы все URL-адреса ресурсов в домене интрасети также были проксированы. Например. все следующие ссылки на ресурсы в HTML

<base href="http://intranet.com/" />
<script src="http://intranet.com/script.js"></script>
<link href="http://intranet.com/style.css" />
<img src="http://intranet.com/image.png" />
<a href="http://intranet.com/page.html">link</a>

должны быть изменены в HTML таким образом, чтобы вместо этого они проходили через ваш прокси-сервлет, например.

<base href="http://example.com/proxy/" />
<script src="http://example.com/proxy/script.js"></script>
<link href="http://example.com/proxy/style.css" />
<img src="http://example.com/proxy/image.png" />
<a href="http://example.com/proxy/page.html">link</a>

Парсер HTML, такой как Jsoup, чрезвычайно полезен в этом. Вы можете сделать следующее в своем прокси-сервлете, который, я полагаю, сопоставлен с шаблоном URL /proxy/*.

String intranetURL = "http://intranet.com";
String internetURL = "http://example.com/proxy";

if (request.getRequestURI().endsWith(".html")) { // A HTML page is requested.
    Document document = Jsoup.connect(intranetURL + request.getPathInfo()).get();

    for (Element element : document.select("[href]")) {
        element.attr("href", element.absUrl("href").replaceFirst(intranetURL, internetURL));
    }

    for (Element element : document.select("[src]")) {
        element.attr("src", element.absUrl("src").replaceFirst(intranetURL, internetURL));
    }

    response.setContentType("text/html;charset=UTF-8");
    response.setCharacterEncoding("UTF-8");
    resposne.getWriter().write(document.html());
}
else { // Other resources like images, etc.
    URLConnection connection = new URL(intranetURL + request.getPathInfo()).openConnection();

    for (Map.Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
        for (String value : header.getValue()) {
            response.addHeader(header.getKey(), value);
        }
    }

    InputStream input = connection.getInputStream();
    OutputStream output = response.getOutputStream();
    // Now just copy input to output.
}
person BalusC    schedule 08.06.2011
comment
Да, это действительно имеет смысл... странно, что нет инструментов, чтобы сделать это из коробки - person Fagoter; 09.06.2011

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

person Bozho    schedule 08.06.2011
comment
Божо, это ему не поможет (я имею в виду изображения)... так как источник изображений также должен быть перенаправлен. - person bestsss; 08.06.2011
comment
Я думаю, что HtmlUnit может извлечь URL-адреса изображений с веб-страницы и позволить вам делать новые запросы для каждого из них. - person Bozho; 08.06.2011
comment
Это ясно, но, насколько я понимаю, ОП хочет, чтобы клиенты могли их запрашивать. Для этого им необходимо проанализировать HTML-код и сделать специальные запросы для указанных изображений. Это непростая задача. - person bestsss; 08.06.2011
comment
Я не уверен, чем полезен HtmlUnit, если эти запросы должны исходить от клиента. - person BalusC; 08.06.2011
comment
извините, я не понял, что он загружает страницу от имени клиентов. - person Bozho; 09.06.2011