Потоковая передача PDF через сервлет в браузер - PullRequest
3 голосов
/ 06 октября 2010

У меня есть типичный сервлет, который транслирует PDF в браузер.PDF-файлы хранятся на внутреннем сервере, с которого получает мой сервлет.Если я нажму на сервлет прямо из браузера, отобразится PDF.Если я попытаюсь использовать тот же URL-адрес в теге <IMG> на веб-странице, ... сломанная труба.

Любое понимание того, почему это должно быть?

В качестве эксперимента я могу без проблем транслировать GIF-файлы.

Вот код, который я в значительной степени извлек из внутренних сетей:

public class PdfServlet extends HttpServlet {

    private static final Logger log = Logger.getLogger(PdfServlet.class.getName());

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse res) {

        String url = (String) req.getParameter("url");

        log.info("The URL is " + url);
        String format = "application/pdf";
//           String format = "image/gif";

        streamBinaryData(url, format, res);

    }

    /*
     * This Method Handles streaming Binary data
     * <p>
     * @param String urlstr ex: http;//localhost/test.pdf etc.
     * @param String format ex: pdf or audio_wav or msdocuments etc.
     * @param ServletOutputStream outstr
     * @param HttpServletResponse resp
     */
    private void streamBinaryData(
            String urlstr,
            String format,
            HttpServletResponse resp) {

        ServletOutputStream outstr = null;
        String ErrorStr = null;

        try {
            outstr = resp.getOutputStream();

            //find the right MIME type and set it as contenttype
            resp.setContentType(format);
            BufferedInputStream bis = null;
            BufferedOutputStream bos = null;
            try {
                URL url = new URL(urlstr);
                URLConnection urlc = url.openConnection();
                int length = urlc.getContentLength();

                resp.setContentLength(length);
//                resp.setHeader("Content-Length", String.valueOf(+length));
//                resp.setHeader("Content-Disposition", "inline");

                // Use Buffered Stream for reading/writing.
                InputStream in = urlc.getInputStream();
                bis = new BufferedInputStream(in);
                bos = new BufferedOutputStream(outstr);
                byte[] buff = new byte[length];
                int bytesRead;
                // Simple read/write loop.
                while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                    log.info("Got a chunk of " + bytesRead);
                    bos.write(buff, 0, bytesRead);
                }
            } catch (Exception e) {
                e.printStackTrace();
                ErrorStr = "Error Streaming the Data";
                outstr.print(ErrorStr);
            } finally {
                log.info("finally!!!");
                if (bis != null) {
                    bis.close();
                }
                if (bos != null) {
                    bos.close();
                }
                if (outstr != null) {
                    outstr.flush();
                    outstr.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

... и HTMLфайл.Сбой pdf с разорванным каналом, и изображение gif отображается, даже если тип содержимого возвращается как «application / pdf».

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Cheesy Servlet Experiment</title>
    </head>
    <body>
        <h1>Cheesy Servlet Experiment</h1>

        <P>
            <img src="http://10.0.0.9/ServletExperiment/pdf?url=http%3a%2f%2fwww.samplepdf.com%2fsample.pdf" alt="yah mon">
        <P>
            <img src="http://10.0.0.9/ServletExperiment/pdf?url=http%3a%2f%2fbbs.homeshopmachinist.net%2fimages%2fstatusicon%2fforum_new.gif" alt="yah mon">
    </body>
</html>

Правка - следующие операции в FF.Я не знаю, насколько это стандартно.

<object data="http://www.samplepdf.com/sample.pdf" type="application/pdf" width="600" height="600">
    alt : <a href="http://www.samplepdf.com/sample.pdf">test.pdf</a>
</object>

Интересная информация здесь .Выглядит достаточно хорошо поддерживается.

Ответы [ 4 ]

4 голосов
/ 06 октября 2010

Может ли ваш браузер отображать PDF-файлы в img элементах? Это действительно маловероятно. Я думаю, что браузер завершает соединение, когда обнаруживает, что это на самом деле не изображение.

Некоторые браузеры не жалуются на типы контента. Они проверяют файл изображения и выясняют, в каком формате изображение само по себе. Это может объяснить, почему отображается ваше GIF-изображение.

3 голосов
/ 06 октября 2010

Проблема в том, что вы пытаетесь отобразить документ PDF с тегом img. img может обрабатывать только простые форматы изображений, такие как JPEG, GIF или PNG.

Обычно простой браузер не может отображать содержимое PDF самостоятельно. Если не установлен подключаемый модуль для просмотра PDF, браузер отобразит только диалоговое окно сохранения для загрузки файла PDF.

Поэтому самым безопасным способом было бы, чтобы ваша HTML-страница содержала только ссылку на ваш файл PDF. Возможно с target="_blank", чтобы открыть новое окно браузера.

1 голос
/ 06 октября 2010

вы должны использовать якорный тег (если вам нужно использовать img, сделайте обертку IMG с src IMG, указывающим на реальное изображение). Суть якоря будет вашим сервелтом, который отображает PDF-файлы. make suer вы устанавливаете правильный тип контента в сервлете.

0 голосов
/ 27 октября 2013

Первое: вы пытаетесь прочитать length сразу.это не очень хорошая практика, так как уверяет вас в задаче

попробуйте прочитать более мелкие фрагменты на byte [] read_buffer = new byte[1024 * 10] Таким образом, вы читаете 10 КБ за раз.

И пишитеэти 10 КБ на bos.

Держите этот цикл, пока не получите -1 с помощью функции read.

И да.Вы не должны использовать тег img для pdf

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...