Проблема с отображением PDF-файла из моего JSF-портлета Liferay

Я использую liferay 5.2 с jsf-портлетом.

На странице я хочу нажать кнопку, чтобы создать один PDF-файл. В managebean я создаю pdf и хочу показать его в ответ.

В ByteArrayOutputStream с именем outputStream у меня есть PDF-файл, созданный с помощью JasperReport.

Я пишу:

   PortletResponse portletResponse = (PortletResponse)externalCtx.getResponse(); 
   HttpServletResponse httpResponse = PortalUtil.getHttpServletResponse(portletResponse);

   ServletOutputStream out = httpResponse.getOutputStream();
   String filename="Pdf" + System.currentTimeMillis()+".pdf";
   httpResponse.reset();

   httpResponse.setContentType("application/pdf");
   httpResponse.setHeader("Content-Disposition", "attachment; filename=\""+ filename + "\"");
   httpResponse.setContentLength(outputStream.size());

   outputStream.writeTo(out);

   out.flush();
   out.close();

Я не вижу ничего на выходе! В журнале jboss я прочитал: IllegaStateException....

Что не так?

БРЕВНО

        11:03:19,716 INFO  [STDOUT] 11:03:19,716 ERROR [IncludeTag] Current URL /web/organo-di-governo/datawarehouse?p_p_id=1_WAR_Portlet_Datawarehouse_INSTANCE_D7s7&p_p_lifecycle=1&p_p_state=normal&p_p_mode=view&p_p_col_id=column-2&p_p_col_count=1&_1_WAR_Portlet_Datawarehouse_INSTANCE_D7s7_com.sun.faces.portlet.VIEW_ID=%2Fview.xhtml&_1_WAR_Portlet_Datawarehouse_INSTANCE_D7s7_com.sun.faces.portlet.NAME_SPACE=_1_WAR_Portlet_Datawarehouse_INSTANCE_D7s7_ generates exception: null
                11:03:19,717 INFO  [STDOUT] 11:03:19,717 ERROR [IncludeTag] java.lang.IllegalStateException
                    at com.liferay.portal.servlet.filters.strip.StripResponse.getWriter(StripResponse.java:85)
                    at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
                    at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
                    at org.apache.jasper.runtime.JspWriterImpl.write(JspWriterImpl.java:326)
                    at org.apache.jasper.runtime.JspWriterImpl.write(JspWriterImpl.java:342)
                    at org.apache.jasper.runtime.JspWriterImpl.print(JspWriterImpl.java:468)
                    at com.liferay.taglib.util.ThemeUtil.includeVM(ThemeUtil.java:208)
                    at com.liferay.taglib.util.ThemeUtil.include(ThemeUtil.java:68)
                    at com.liferay.taglib.util.IncludeTag.doEndTag(IncludeTag.java:59)
                    at org.apache.jsp.html.common.themes.portal_jsp._jspx_meth_liferay_002dtheme_005finclude_005f1(portal_jsp.java:816)
                    at org.apache.jsp.html.common.themes.portal_jsp._jspx_meth_c_005fotherwise_005f0(portal_jsp.java:788)
                    at org.apache.jsp.html.common.themes.portal_jsp._jspService(portal_jsp.java:724)
                    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
                    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
                    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:373)
                    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:336)
                    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
                    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
                    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
                    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                11:03:19,718 ERROR [[jsp]] Servlet.service() for servlet jsp threw exception
                java.lang.IllegalStateException



        11:03:19,719 ERROR [[Main Servlet]] Servlet.service() for servlet Main Servlet threw exception
        java.lang.IllegalStateException
            at com.liferay.portal.servlet.filters.strip.StripResponse.getWriter(StripResponse.java:85)
            at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
            at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)



        11:03:19,722 INFO  [STDOUT] 11:03:19,720 ERROR [OpenSSOFilter] org.apache.jasper.JasperException: java.lang.IllegalStateException
        org.apache.jasper.JasperException: java.lang.IllegalStateException
            at org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:521)
            at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:409)
            at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:336)
            at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)




        11:03:19,722 INFO  [STDOUT] n.internalDoFilter(ApplicationFilterChain.java:235)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
            at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)


        Caused by: java.lang.IllegalStateException
            at com.liferay.portal.servlet.filters.strip.StripResponse.getWriter(StripResponse.java:85)
            at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
            at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)

person Stefano    schedule 02.03.2010    source источник
comment
Нам нужна трассировка стека исключения, а не только имя класса.   -  person skaffman    schedule 02.03.2010
comment
мое альтернативное решение - один внешний сервлет... я пробовал с сервлетом... работает нормально... я вставил в сеанс свой ByteArrayOutputStream и после externalCtx.redirect(externalCtx.getRequestContextPath() +/Download); но это не лучшее решение...   -  person Stefano    schedule 02.03.2010
comment
Возможный дубликат Загрузить файл, имя файла не работает в портлете   -  person stiemannkj1    schedule 17.01.2019


Ответы (1)


Единственный подходящий способ сделать это — использовать фазу «RESOURCE» спецификации JSR-286. В настоящее время в вашем коде вы находитесь в фазе «RENDER», которая принудительно разрешает только кодировку «text/html».

В простом JSP тег будет выглядеть примерно так:

<portlet:resourceURL id="/super-cool.pdf" />

Затем в своем классе портлета вы реализуете метод serveResource(ResourceRequest req, ResourceResponse res) и читаете, вызываете метод req.getResourceId() ResourceRequest и ведете себя, вызывая свою бизнес-логику (создаете свой PDF-файл), а затем записываете его в выходной поток.

В JSF я не совсем уверен, поддерживается ли это вообще, а это значит, что единственный способ — делегировать задачу вызову сервлета. Посмотрите в JSF, реализована ли обработка ресурсов JSR-286.

person Ray    schedule 02.03.2010
comment
спасибо, Рэй, но я не могу поверить, что ... из JSF-портлета в Liferay нет возможности взять pdf. текст... должно быть решение! - person Stefano; 02.03.2010
comment
Рэй дал абсолютно правильный ответ на ваш вопрос - независимо от того, верите вы в это или нет. Невозможно просто получить поток вывода сервлета из контекста портлета. Это приведет к (угадайте...) исключению IllegalStateException. Представьте: во время рендеринга вашего портлета половина HTML-страницы уже может быть передана клиенту, поэтому вы не можете внезапно изменить тип содержимого на pdf. Используйте фазу RESOURCE — именно для этого она и создана. Честный. - person Olaf Kock; 29.04.2011
comment
как я могу использовать этот тег ‹portlet:resourceURL на моей странице xhtml? - person muneebShabbir; 13.07.2012