Page 2 of 2 FirstFirst 12
Results 11 to 17 of 17

Thread: Spring Web Flow + PDF Generation

  1. #11
    Join Date
    Mar 2008
    Posts
    21

    Default Webflow 2.0.0.RELEASE

    Hi,

    With 2.0.0.RELEASE, It may not possible to write in the outputstream of response (which is accessible with requestcontext) in "evaluate expression".
    With RC1, it was still possible to write in the outputstream of response and generate pdf.
    Is there an equivalent of null view in viewstate (webflow 1.0.0) with webflow 2.0.0?
    There is an other solution as jamesclinton describes is to use an other controller, but objects of webflow scope (conversation, flow) are not accessible.
    Is there a solution for accessing objects in the flow scope outside flowController?

    Thanks in advance

  2. #12
    Join Date
    Jul 2006
    Location
    London
    Posts
    500

    Default

    Quote Originally Posted by efshaolin View Post
    Hi,
    Is there a solution for accessing objects in the flow scope outside flowController?
    If you in the flow, you can pop what you need in the http session. Then via the MVC controller extract it to build your doc.
    Regards,
    James

  3. #13
    Join Date
    May 2008
    Posts
    4

    Default write byte [] to PDF using spring web flow

    Hi All,

    We are developing an application using spring web flow. My requirement is to first generate PDF and store in the database (BLOB) in byte[]. Now i wanted to display PDF using stored byte[]. To generate PDF and get byte[] i am using Jasper API.

    I searched using google however i did not find any Jasper API which generate PDF file using byte[]. I also took a look at the AbstarctPdfView, however we cannot pass byte[] to Document Object.

    Can anybody help me how do i achieve this?

  4. #14

    Default

    Quote Originally Posted by babybaby409 View Post
    Hi All,

    We are developing an application using spring web flow. My requirement is to first generate PDF and store in the database (BLOB) in byte[]. Now i wanted to display PDF using stored byte[]. To generate PDF and get byte[] i am using Jasper API.

    I searched using google however i did not find any Jasper API which generate PDF file using byte[]. I also took a look at the AbstarctPdfView, however we cannot pass byte[] to Document Object.

    Can anybody help me how do i achieve this?
    See thread view-state on-render for download action for details on rendering a PDF. The solution I'm using is in post #6.

    As for retrieving a PDF from a database Blob, you can try something like this...

    PdfUtil.java
    Code:
        private static final int OUTPUT_BYTE_ARRAY_INITIAL_SIZE = 4096;
    
        public static OutputStream convertInputStreamToOutputStream(InputStream inputStream)
            throws IOException {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream(OUTPUT_BYTE_ARRAY_INITIAL_SIZE);
    
            // convert InputStream to OutputStream
            byte[] byteArray = new byte[OUTPUT_BYTE_ARRAY_INITIAL_SIZE];
            int bytesRead = 0;
            int offset = 0;
    
            bytesRead = inputStream.read(byteArray, offset, OUTPUT_BYTE_ARRAY_INITIAL_SIZE);
    
            while (bytesRead != -1) {
                outputStream.write(byteArray, offset, bytesRead);
                bytesRead = inputStream.read(byteArray, offset, OUTPUT_BYTE_ARRAY_INITIAL_SIZE);
            }
    
            return outputStream;
        }
    ReportPdfServiceImpl.java
    Code:
        @Resource
        private ReportPdfDao reportPdfDao;
    
        public OutputStream fetchReportPdf(Integer reportId)
            throws ApplicationException {
            try {
                return PdfUtil.convertInputStreamToOutputStream(reportPdfDao.fetchReportPdf(reportId));
            } catch (DataAccessException e) {
                throw new ApplicationException("fetch report pdf failed", e).code(ReportPdfServiceService.PDF_NOT_FOUND);
            } catch (SQLException e) {
                throw new ApplicationException("fetch report pdf failed", e).code(ReportPdfServiceService.PDF_NOT_FOUND);
            } catch (IOException e) {
                throw new ApplicationException("InputStream/OutputStream conversion failed in fetch report pdf ", e);
            }
        }

    JdbcReportPdfDao.java
    Code:
        private JdbcTemplate reportPdfJdbcTemplate = new JdbcTemplate(getDataSource());
    
        public InputStream fetchReportPdf(Integer reportId)
            throws DataAccessException, SQLException {
            Blob pdfBlob = null;
            InputStream pdf = null;
    
            Map paramMap = new HashedMap();
            paramMap.put("reportId", reportId);
    
            SqlParameterSource namedParameters = new MapSqlParameterSource(paramMap);
    
            pdfBlob = (Blob) reportPdfJdbcTemplate.queryForObject(JdbcReportPdfDao.REPORT_PDF_BY_ID_SQL,
                    namedParameters, Blob.class);
    
            if (null != pdfBlob) {
                pdf = pdfBlob.getBinaryStream();
            }
    
            return pdf;
        }

  5. #15

    Cool Combining ResourceBundleViewResolver for jasper and otherwise UrlBasedViewResolver

    Hey I'm trying something similar with the swf-booking-faces sample bundled in the swf 2.0.5 dist

    I've added the controller

    Code:
    package org.springframework.webflow.samples.jasper;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
    import org.springframework.webflow.samples.booking.Hotel;
    
    import org.springframework.stereotype.Service;
    import java.io.Serializable;
    
    //I made my controller and modelAndView serializable to use it in the flow...
    
    @Service
    public class ReportController extends MultiActionController implements Serializable   {
    
            private static final long serialVersionUID = 1L;
    
    	public ModelAndView handleSimpleReport(List<Hotel> hotels) throws Exception {
                System.out.println("handleSimpleReport()");
                //Map mpHotels = (Map)hotels;
    		return new SwfModelAndView("simpleReport", getModel(hotels));
    	}
    	
    	private Map getModel(List<Hotel> hotels) {
                System.out.println("getModel");
    		Map model = new HashMap();
    		model.put("ReportTitle", "Dear Lord!");
    		model.put("datasource", hotels);
    
    
    		return model;
    	}
    	
    }
    and extended the ModelAndView (probably didn't need to,however..)

    Code:
    package org.springframework.webflow.samples.jasper;
    
    import java.io.Serializable;
    import java.util.Map;
    import org.springframework.web.servlet.ModelAndView;
    
    
    public class SwfModelAndView extends ModelAndView implements Serializable {
            private static final long serialVersionUID = 1L;
    
        public SwfModelAndView(String viewName,Map model){}
    
    }
    in views.properties..

    Code:
    simpleReport.class=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView
    simpleReport.url=/WEB-INF/reports/report2.jasper
    simpleReport.reportDataKey=datasource
    but I have concluded that my problem resides in reolving my views..

    in webmvc-config.xml I need the views to go to ResourceBundleViewResolver for jasper and otherwise toUrlBasedViewResolver...

    but how to do this?

    it will always resolve to /WEB-INF/simpleReport.xhtml when I want it to go to the views.properties file to lookup the file


    see the configs below..



    Code:
    <!-- Maps request paths to flows in the flowRegistry; e.g. a path of /hotels/booking looks for a flow with id "hotels/booking" -->
    	<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
    		<property name="flowRegistry" ref="flowRegistry" />
    		<property name="defaultHandler">
    			<!-- If no flow match, map path to a view to render; e.g. the "/intro" path would map to the view named "intro" -->	
    			<bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
    		</property>
    	</bean>
    
    	<!-- Maps logical view names to Facelet templates in /WEB-INF (e.g. 'search' to '/WEB-INF/search.xhtml' -->
    	<bean id="faceletsViewResolver" class="org.springframework.web.servlet.view.c">
    		<property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
    		<property name="prefix" value="/WEB-INF/" />
    		<property name="suffix" value=".xhtml" />
                    <property name="order"><value>1</value></property>
    	</bean>
    
        <!-- <bean id="pdfViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    		<property name="viewClass" value="org.springframework.webflow.samples.util.PdfPage"/>
    		<property name="prefix" value="/WEB-INF/" />
    		<property name="suffix" value=".pdf" />
    	</bean> -->
    
        <!-- the ResourceBundleViewResolver -->
        <bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
          <property name="basename" value="views"/>
          <property name="order"><value>0</value></property>
        </bean>
    
    	<!-- Dispatches requests mapped to org.springframework.web.servlet.mvc.Controller implementations -->
    	<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
    
    	<!-- Dispatches requests mapped to flows to FlowHandler implementations -->
    	<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
    		<property name="flowExecutor" ref="flowExecutor" />
    	</bean>
    (see subflow below...)

    Code:
    <var name="reportController" class="org.springframework.webflow.samples.jasper.ReportController" />
    		        <var name="modelAndView" class="org.springframework.web.servlet.ModelAndView" />
    			<input name="hotels" required="true" type="dataModel" />
    		        <input name="searchCriteria" required="true" />
    		
    		        <on-start>
    		            <evaluate expression="bookingService.addMsg('now in subflow...')" />
    		            <evaluate expression="reportController.handleSimpleReport(bookingService.findHotels(searchCriteria,externalContext.locale))"  result="flowScope.modelAndView" />
    		        </on-start>
    		        <view-state id="simpleReport" popup="true">
    		
    		            <on-entry>
    		                <evaluate expression="bookingService.addMsg('entered view-state displayPdfState')" />
    		            </on-entry>
            		</view-state>



    So I do get the following output msgs from my flow that calls the controller..

    handleSimpleReport() and getModel so i know the modelAndView is returned

    yet...

    Code:
    2009-09-20 22:47:21,568 DEBUG [org.springframework.webflow.engine.Flow] - <Restoring [FlowVariable@1ea01711 name = 'reportController', valueFactory = [BeanFactoryVariableValueFactory@204a6ccc type = ReportController]]>
    	2009-09-20 22:47:21,568 DEBUG [org.springframework.webflow.engine.Flow] - <Restoring [FlowVariable@2ff1bf46 name = 'modelAndView', valueFactory = [BeanFactoryVariableValueFactory@2844a541 type = ModelAndView]]>
    	2009-09-20 22:47:21,677 DEBUG [org.springframework.faces.webflow.FlowViewStateManager] - <No matching view in view scope>
    	2009-09-20 22:47:21,677 DEBUG [org.springframework.faces.webflow.JsfViewFactory] - <Creating UIViewRoot from 'simpleReport.xhtml'>
    	2009-09-20 22:47:21,677 DEBUG [org.springframework.webflow.engine.ViewState] - <Rendering + [JSFView = '/WEB-INF/flows/pdfHotels/simpleReport.xhtml']>
    	2009-09-20 22:47:21,677 DEBUG [org.springframework.webflow.engine.ViewState] - <  Flash scope = map['flowRenderResponse' -> true]>
    	2009-09-20 22:47:21,786 DEBUG [org.springframework.webflow.engine.ViewState] - <  Messages = [DefaultMessageContext@708a605c sourceMessages = map[[null] -> list[[empty]]]]>
    	2009-09-20 22:47:21,786 DEBUG [org.springframework.faces.support.RequestLoggingPhaseListener] - <Entering JSF Phase: RENDER_RESPONSE 6>
    	2009-09-20 22:47:21,786 DEBUG [org.springframework.faces.webflow.JsfView] - <Asking view handler to render view>
    	20-Sep-2009 10:47:21 PM com.sun.facelets.FaceletViewHandler handleRenderException
    	SEVERE: Error Rendering View[/WEB-INF/flows/pdfHotels/simpleReport.xhtml]




    In short how do I target the correct viewResolver for the right case, must be a solution out there !


    Any suggestions as to what changes to make?

    Has anyone succeeded in adding jasperreports to the swf-booking-faces example?

    my best regards to all!

    Kevin u out there?

  6. #16

    Cool blank jasper detail section

    I'm stubbornly still at it!

    Trying to create a jasperreport pdf view for the swf-booking-faces sample bundled in the swf 2.0.5 dist..
    I can get it to produce the pdf however the detail section of the report is blank no matter what I try...
    If I run this in the current netBeans with the sql (jdbc datasource) it runs OK and you can see eveything OK...
    if I run this off the page <a href="simpleReport.pdf" >PDF</a> there's no error and the detail section is blank!

    the relevant code is as follows...

    the report2.jrxml (what's wrong with it?)
    Code:
    <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="simpleReport" pageWidth="595" pageHeight="842" columnWidth="535" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" isFloatColumnFooter="true">
    	<property name="ireport.scriptlethandling" value="0"/>
    	<property name="ireport.encoding" value="UTF-8"/>
    	<import value="net.sf.jasperreports.engine.*"/>
    	<import value="java.util.*"/>
    	<import value="net.sf.jasperreports.engine.data.*"/>
    	<field name="id" class="java.lang.Long"/>
    	<field name="address" class="java.lang.String"/>
    	<field name="name" class="java.lang.String"/>
    	<background>
    		<band splitType="Stretch"/>
    	</background>
    	<title>
    		<band height="79" splitType="Stretch">
    			<staticText>
    				<reportElement x="173" y="17" width="224" height="31"/>
    				<textElement>
    					<font size="14" isBold="true"/>
    				</textElement>
    				<text><![CDATA[Why can't this work?]]></text>
    			</staticText>
    		</band>
    	</title>
    	<pageHeader>
    		<band height="35" splitType="Stretch"/>
    	</pageHeader>
    	<columnHeader>
    		<band height="61" splitType="Stretch">
    			<staticText>
    				<reportElement x="0" y="41" width="38" height="20"/>
    				<textElement/>
    				<text><![CDATA[ID]]></text>
    			</staticText>
    			<textField evaluationTime="Auto" pattern="" isBlankWhenNull="false">
    				<reportElement x="48" y="10" width="81" height="31"/>
    				<textElement>
    					<font fontName="Verdana"/>
    				</textElement>
    				<textFieldExpression class="java.lang.String"><![CDATA[$F{name}]]></textFieldExpression>
    			</textField>
    			<textField>
    				<reportElement x="155" y="10" width="107" height="31"/>
    				<textElement/>
    				<textFieldExpression class="java.lang.String"><![CDATA[$F{address}]]></textFieldExpression>
    			</textField>
    		</band>
    	</columnHeader>
    	<detail>
    		<band height="57" splitType="Stretch">
    			<textField pattern="" isBlankWhenNull="false">
    				<reportElement x="0" y="0" width="38" height="31"/>
    				<textElement/>
    				<textFieldExpression class="java.lang.Long"><![CDATA[$F{id}]]></textFieldExpression>
    			</textField>
    			<textField pattern="" isBlankWhenNull="false">
    				<reportElement key="textField" positionType="Float" mode="Transparent" x="38" y="0" width="81" height="31" forecolor="#000000"/>
    				<textElement>
    					<font fontName="Verdana"/>
    				</textElement>
    				<textFieldExpression class="java.lang.String"><![CDATA[$F{name}]]></textFieldExpression>
    			</textField>
    			<textField>
    				<reportElement x="119" y="0" width="75" height="20"/>
    				<textElement/>
    				<textFieldExpression class="java.lang.String"><![CDATA[$F{address}]]></textFieldExpression>
    			</textField>
    		</band>
    	</detail>
    	<columnFooter>
    		<band height="45" splitType="Stretch"/>
    	</columnFooter>
    	<pageFooter>
    		<band height="54" splitType="Stretch">
    			<textField pattern="EEEEE dd MMMMM yyyy">
    				<reportElement x="0" y="34" width="173" height="20"/>
    				<textElement/>
    				<textFieldExpression class="java.util.Date"><![CDATA[new java.util.Date()]]></textFieldExpression>
    			</textField>
    			<textField>
    				<reportElement x="426" y="34" width="80" height="20"/>
    				<textElement textAlignment="Right"/>
    				<textFieldExpression class="java.lang.String"><![CDATA["Page "+$V{PAGE_NUMBER}+" of"]]></textFieldExpression>
    			</textField>
    			<textField evaluationTime="Report">
    				<reportElement x="506" y="34" width="40" height="20"/>
    				<textElement/>
    				<textFieldExpression class="java.lang.String"><![CDATA[" " + $V{PAGE_NUMBER}]]></textFieldExpression>
    			</textField>
    		</band>
    	</pageFooter>
    	<summary>
    		<band height="42" splitType="Stretch"/>
    	</summary>
    </jasperReport>
    just to see if it gets the datasource in the modelAndView I output two $F{name} and $F{address} in the Column Header band and this
    works leading me to believe the datasource is visible...

    the controller...
    Code:
    package org.springframework.webflow.samples.jasper;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
    import org.springframework.webflow.samples.booking.Hotel;
    
    public class ReportControllerSvlt extends MultiActionController {
    
    	public ModelAndView handleSimpleReport(HttpServletRequest request,
    			HttpServletResponse response) throws Exception {
                System.out.println("ReportControllerSvlt.handleSimpleReport()");
    		return new ModelAndView("simpleReport", getModel());
    	}
    
    	private Map getModel() {
                System.out.println("ReportControllerSvlt.getModel()");
                    Map<Object,Object> model = new HashMap<Object,Object>();
    		model.put("datasource", getData());
                    System.out.println("model="+model.toString());
    
    		return model;
    	}
    
    	private List getData() {
                System.out.println("ReportControllerSvlt.getData()");
    
                    ArrayList<Hotel> list = new ArrayList<Hotel>();
    
    		for (int x = 0; x < 10; x++) {
    			Hotel hotel = new Hotel();
                            String strInt = ""+x;
    			hotel.setId(Long.parseLong(strInt));
    			hotel.setName("Rob Harrop");
    
    			if (x % 2 == 0) {
    				hotel.setCity("Deux mtgs");
                                    hotel.setAddress("123 10ieme av");
    			}
    			else {
    				hotel.setCity("Pompano beach");
                                    hotel.setAddress("top o world");
    			}
                            System.out.println("hotel="+hotel.toString());
    			list.add(hotel);
    		}
    
    		return list;
    	}
    
    }
    webmvc-config.xml...
    Code:
    	<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
    		<property name="flowRegistry" ref="flowRegistry" />
    		<property name="defaultHandler">
    			<bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
    		</property>
    	</bean>
    
    	<bean id="faceletsViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    		<property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
    		<property name="prefix" value="/WEB-INF/" />
    		<property name="suffix" value=".xhtml" />
                    <property name="order" value="1" />
    	</bean>
    
            <bean id="mvcViewFactoryCreator" class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
    		<property name="viewResolvers">
                       <list>
                           <ref bean="controllerResolver" />                  
                           <ref bean="jasperViewResolver" />                       
                           <ref bean="faceletsViewResolver" />
                       </list>
                     </property>
           </bean>
    
        <bean id="jasperViewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
          <property name="basename" value="views"/>
          <property name="order" value="0" />
        </bean>
                    
      <bean id="controllerResolver" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
     	<property name="mappings">
    	 	<props merge="default">
    			<prop key="*.*">controller</prop>
    		</props>
      	</property>
            <property name="order" value="0" />
      </bean>
    
      <bean id="controller" class="org.springframework.webflow.samples.jasper.ReportControllerSvlt" lazy-init="default" autowire="default" dependency-check="default">
            <property name="methodNameResolver">
                    <ref local="resolver" />
            </property>
      </bean>
      
      <bean id="resolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver" lazy-init="default" autowire="default" dependency-check="default">
     	<property name="mappings">
    	 	<props merge="default">
    		  <prop key="/simpleReport.pdf">handleSimpleReport</prop>
    		</props>
      	</property>
      </bean>
    
    
    </beans>
    views.properties...
    Code:
    simpleReport.(class)=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView
    simpleReport.url=/WEB-INF/reports/report2.jasper
    simpleReport.reportDataKey=datasource
    Why are the fields yielded in the ColumnHeader but not shown in the Details band ( nothing not even the expected Null is printed)??
    Is there any way to get DEBUG msgs when u get the pdf from the jasper compilation?

    Any help at all would be greatly appreciated, i've spent a great deal of time trying to figure this out.

    Cheers to all!

    Code:
    <dead tired>John</dead tired>

  7. #17

    Lightbulb swf-booking-faces jasper reports

    I guess I should elaborate on the situation.

    I'm taking the swf-booking-faces sample bundled in the SWF distribution ver2.0.5 (a recent distr)
    and getting the reviewHotels.xhtml to have a sf:commandLink that will print the Hotels searchResult (as a popup) using
    jasperreports.

    OK so I can produce the report.pdf to a folder on the classpath, no problem. But how could you open the view using webflow?
    (I've tried many classpath locations, settled on
    Code:
    C:\NetBeansProjects\swf-booking-faces_sept18\src\main\webapp\reports\report.pdf
    since that will open with
    Code:
    http://localhost:8084/swf-booking-faces/reports/report2.pdf
    )

    The only way I can open it is with:

    Code:
    <view-state id="report2.view" view="externalRedirect:/reports/report2.pdf">
    but then I get the first cached version produced when the server started and the <view popup=true doesn't work
    with externalRedirects.

    It seems the only way to have the report work is with
    Code:
    <a href="simpleReport.pdf" target="_blank">Printable list</a>
    that will only compile a hardcoded data ( via the JasperReportsPdfView class )with no interaction with current view (ie: you couldn't send the search criteria to the query).

    There must be a way to produce the report in a flow that will have access to flow vars. If you separate the report to a controller with req/resp it won't interact with the flow and xhtml components,... leaves you cold!

    I have managed to popup the report but it creates parse errors since it's a pdf file...

    What to do?

    Has anyone been able to open pdf jasperreports using the swf-booking-faces sample yet?

    Regards,

    John

    P.S. tried everything, separate servlet etc, gets swallowed up/busted by the framework.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •