Как я могу обслуживать двоичный контент из приложения JSF / Webflow? - PullRequest
2 голосов
/ 09 ноября 2010

У меня есть приложение JSF 1.2 / Spring Web flow 2.0.7, которое должно обслуживать двоичный контент (изображение). Этот контент извлекается из веб-службы (вместе с некоторыми другими данными) в виде строки в кодировке Base64 и заканчивается в компоненте вместе с остальными данными. Как я могу получить изображение для отображения на моей веб-странице?

Примечание. Нет, невозможно заставить потоковую передачу данных веб-службы напрямую или даже извлечь двоичные данные из веб-службы без всего прочего.

Ответы [ 2 ]

6 голосов
/ 10 ноября 2010

Вы хотите получить это изображение в компоненте <h:graphicImage>, верно? Теоретически, вы можете использовать для этого data URI формат .

<h:graphicImage value="data:image/png;base64,#{bean.base64Image}" />

Однако у вас проблема в том, что он не работает во всех текущих браузерах. Например, MSIE ограничивает длину data URI 32 КБ.

Если эти изображения в целом больше или вы хотели бы также поддерживать устаревшие браузеры, то в настоящее время лучшая ставка на самом деле - дать ей указать полноценный URL после всех .

<h:graphicImage value="images/filename.png" />

Есть два способа заставить это работать:

  1. Временно напишите изображение в общедоступный веб-контент и сделайте ссылку на него обычным способом.

    this.uniqueImageFileName = getOrGenerateItSomehow();
    byte[] imageContent = convertBase64ToByteArraySomehow();
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ServletContext sc = (ServletContext) ec.getContext();
    File image = new File(sc.getRealPath("/images"), uniqueImageFileName);
    // Write byte[] to FileOutputStream on that file the usual way (and close!)
    

    И используйте его следующим образом:

    <h:graphicImage value="images/#{bean.uniqueImageFileName}" />
    

    Однако это работает, только если расширена WAR и у вас есть права на запись в файловую систему диска. Вы также должны принять во внимание очистку. A HttpSessionListener может быть полезным в этом.

  2. Сохраните двоичные данные в сеансе и предоставьте HttpServlet для их обслуживания. Предполагая, что ваш бин имеет объем запроса:

    this.uniqueImageFileName = getOrGenerateItSomehow();
    byte[] imageContent = convertBase64ToByteArraySomehow();
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ec.getSessionMap().put(uniqueImageFileName, imageContent);
    

    и вид выглядит так:

    <h:graphicImage value="images/#{bean.uniqueImageFileName}" />
    

    Создайте HttpServlet, который отображается на url-pattern из /images/* и выполняет следующие действия в методе doGet():

    String uniqueImageFileName = request.getPathInfo().substring(1);
    byte[] imageContent = (byte[]) request.getSession().getAttribute(uniqueImageFileName);
    response.setContentType("image/png"); // Assuming it's always PNG.
    response.setContentLength(imageContent.length);
    // Write byte[] to response.getOutputStream() the usual way. 
    
2 голосов
/ 09 ноября 2010
  1. Получить объект ответа (в jsf - FacesContext.getCurrentInstance().getExternalContext().getResponse() и привести к HttpServletResponse) или the OutputStream (JSF 2.0, последний вызов метода выше getResponseOutputStream())

  2. использовать методы write для ответа OutputStream

  3. установить правильный Content-Type заголовок

...