Announcement Announcement Module
Collapse
No announcement yet.
JasperReport config Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • JasperReport config

    Hi! (new user question)

    I have one webapp configured and using InternalResourceViewResolver
    . Now I want to use jasperreport:
    How to config jasperreport using my InternalResourceViewResolver resolver (I need an example for jasperreport)?
    Will I need to use the ResourceBundleViewResolver?

    Thanks, Gilberto

  • #2
    Gilberto,

    You should read the JasperReports section in the Spring 1.1.3 reference guide.

    Rob

    Comment


    • #3
      Yes! I've read that topic.

      But I don't now how to put the jasperreport view resolver into my InternalResourceViewResolver:
      Code:
         <!-- View Resolver for JSPs -->
          <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
              <property name="requestContextAttribute"><value>rc</value></property>
              <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
              <property name="prefix"><value>/WEB-INF/pages/</value></property>
              <property name="suffix"><value>.jsp</value></property>
          </bean>
      My report is in: /WEB-INF/reports

      Do I need to use the ResourceBundleViewResolver, because they are different views?

      Thanks for help!

      Gilberto

      Comment


      • #4
        Sore, I haven't used ResourceBundleViewResolver before! So, after I looked at the petclinic code I understood how it functions. And now I know I can put InternalResourceViewResolver and ResourceBundleViewResolver in the same xml config file.

        So, for simple test I used your jasperreports test code in my SimpleReportControler:

        I want map:
        http://localhost:8080/estoque/simpleReport.html
        to:
        # Defines view with symbolic name "simpleReport"
        simpleReport.class=org.springframework.web.servlet .view.jasperreports.JasperReportsPdfView
        simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper
        in the views.properties file

        Code:
        public class SimpleReportController implements Controller &#123;
        ...
         private Map getModel&#40;&#41; &#123;
                Map model = new HashMap&#40;&#41;;
                model.put&#40;"ReportTitle", "Dear Lord!"&#41;;
                model.put&#40;"dataSource", new JRBeanCollectionDataSource&#40;getData&#40;&#41;&#41;&#41;;
                return model;
            &#125;
        
            private List getData&#40;&#41; &#123;
                List list = new ArrayList&#40;&#41;;
                for &#40;int x = 0; x < 10; x++&#41; &#123;
                    PersonBean bean = new PersonBean&#40;&#41;;
                    bean.setId&#40;x&#41;;
                    bean.setName&#40;"Rob Harrop"&#41;;
                    bean.setStreet&#40;"foo"&#41;;
                    list.add&#40;bean&#41;;
                &#125;
                return list;
            &#125;   
            public ModelAndView handleRequest&#40;HttpServletRequest request,
                                              HttpServletResponse response&#41;
            throws Exception &#123;
                if &#40;log.isDebugEnabled&#40;&#41;&#41; &#123;
                    log.debug&#40;"entering 'handleRequest' method..."&#41;;
                &#125;
                return new ModelAndView&#40;"simpleReport","model", getModel&#40;&#41;&#41;;
            &#125;
        &#125;
        app-servlet.xml:

        Code:
            <bean id="simpleReportController" class="org.appfuse.webapp.action.SimpleReportController" autowire="byName"/>
            <!-- Put controller mappings here -->
        
            <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
                <property name="mappings">
                    <props>
                        <prop key="/popuplist/pesquisaItem.html">pesquisaItemController</prop>
                        <prop key="/editVendaItem.html">vendaItemFormController</prop>
                           ...
                        <prop key="/simpleReport.html">simpleReportController</prop>
                        <!-- Add additional URL mappings here -->
                    </props>
                </property>
            </bean>
             ...
            <!-- View Resolver for JSPs -->
            <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="requestContextAttribute"><value>rc</value></property>
                <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
                <property name="prefix"><value>/WEB-INF/pages/</value></property>
                <property name="suffix"><value>.jsp</value></property>
            </bean> 
            <!-- JasperReports View Resolver for jasper'S -->
            <bean id="jasperReportsViewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
                <property name="basename">
                    <value>views</value>
                </property>
            </bean>
        After that I compiled and deployed the app. But when I go to the url http://localhost:8080/estoque/simpleReport.html I get this execption:

        Code:
        java.lang.IllegalArgumentException&#58; No report data supplied in model &#123;model=&#123;dataSource=[email protected]8e, ReportTitle=Dear Lord!&#125;&#125;
        	at org.springframework.web.servlet.view.jasperreports.AbstractJasperReportsView.getReportData&#40;AbstractJasperReportsView.java&#58;195&#41;
        	at org.springframework.web.servlet.view.jasperreports.AbstractJasperReportsView.renderMergedOutputModel&#40;AbstractJasperReportsView.java&#58;163&#41;
        	at org.springframework.web.servlet.view.AbstractView.render&#40;AbstractView.java&#58;242&#41;
        	at org.springframework.web.servlet.DispatcherServlet.render&#40;DispatcherServlet.java&#58;784&#41;
        Any idea that caused this?

        Thanks and Sore again!

        Gilberto

        Comment


        • #5
          Also having problems

          Well, I figured out how to configure the view before I found the info bundled in the spring release, but still having issues. It does not appear that the reportDataKey I am setting is actually used to look up the datasource property in the model. I have set:
          viewReport.class=org.springframework.web.servlet.v iew.jasperreports.JasperReportsPdfView
          viewReport.url=/WEB-INF/reports/bookreport.jrxml
          viewReport.reportDataKey=reportData

          and in my controller I have:

          model = new HashMap();
          model.put("reportData", booklist);

          'booklist' is an instance of a JRDataSource and model is returned. Does anyone have an example that also shows how they wire up everything in their spring-servlet.xml? Quite probably I am doing something wrong, but with no working examples to compare to...

          When I try to access my servlet, I get:

          java.lang.IllegalArgumentException: Value [null] cannot be converted to a JRDataSource
          org.springframework.ui.jasperreports.JasperReports Utils.convertReportData(JasperReportsUtils.java:70 )
          org.springframework.web.servlet.view.jasperreports .AbstractJasperReportsView.convertReportData(Abstr actJasperReportsView.java:213)
          org.springframework.web.servlet.view.jasperreports .AbstractJasperReportsView.getReportData(AbstractJ asperReportsView.java:186)
          org.springframework.web.servlet.view.jasperreports .AbstractJasperReportsView.renderMergedOutputModel (AbstractJasperReportsView.java:163)
          org.springframework.web.servlet.view.AbstractView. render(AbstractView.java:247)
          org.springframework.web.servlet.DispatcherServlet. render(DispatcherServlet.java:784)
          org.springframework.web.servlet.DispatcherServlet. doService(DispatcherServlet.java:621)
          org.springframework.web.servlet.FrameworkServlet.s erviceWrapper(FrameworkServlet.java:368)
          org.springframework.web.servlet.FrameworkServlet.d oGet(FrameworkServlet.java:319)
          javax.servlet.http.HttpServlet.service(HttpServlet .java:689)
          javax.servlet.http.HttpServlet.service(HttpServlet .java:802)

          Comment


          • #6
            Got it working, but still some details to work out

            Here are all the pieces that should get someone started. I have not yet figured out how to set parameters for the report yet.

            BookController, which does all the work:
            Code:
            import org.springframework.web.servlet.mvc.Controller;
            import org.springframework.web.servlet.ModelAndView;
            import javax.servlet.http.HttpServletRequest;
            import javax.servlet.http.HttpServletResponse;
            import java.util.HashMap;
            
            public class BookController implements Controller &#123;
                private BookList bookList = new BookList&#40;&#41;;
            
                public ModelAndView handleRequest&#40;HttpServletRequest request, HttpServletResponse response&#41;
                    throws Exception
                &#123;
                    System.out.println&#40;"handle request"&#41;;
                    return new ModelAndView&#40;"viewList", "reportData", getModel&#40;&#41;&#41;;
                &#125;
            
                public BookList getModel&#40;&#41; &#123;
                    HashMap m = new HashMap&#40;&#41;;
                    m.put&#40;"NAME", "Lord of the Rings&#58; Fellowship of the Ring"&#41;;
                    m.put&#40;"BOOK_ID", new Integer&#40;1&#41;&#41;;
                    bookList.add&#40;m&#41;;
            
                    m = new HashMap&#40;&#41;;
                    m.put&#40;"NAME", "Lord of the Rings&#58; The Two Towers"&#41;;
                    m.put&#40;"BOOK_ID", new Integer&#40;2&#41;&#41;;
                    bookList.add&#40;m&#41;;
            
                    m = new HashMap&#40;&#41;;
                    m.put&#40;"NAME", "Lord of the Rings&#58; Return of the King"&#41;;
                    m.put&#40;"BOOK_ID", new Integer&#40;3&#41;&#41;;
                    bookList.add&#40;m&#41;;
            
                    return bookList;
                &#125;
            
                public void setBookList&#40;BookList b&#41; &#123;
                    System.out.println&#40;"setBookList&#40;&#41;"&#41;;
                    this.bookList = b;
                &#125;
            
                public BookList getBookList&#40;&#41; &#123;
                    System.out.println&#40;"getBookList&#40;&#41;"&#41;;
                    return bookList;
                &#125;
            &#125;
            BookList model object:
            Code:
            import java.util.*;
            import net.sf.jasperreports.engine.JRRewindableDataSource;
            import net.sf.jasperreports.engine.JRField;
            import net.sf.jasperreports.engine.JRException;
            
            public class BookList implements JRRewindableDataSource &#123;
                ArrayList books = new ArrayList&#40;&#41;;
                int pos = -1;
            
                public BookList&#40;&#41; &#123;
                    System.out.println&#40;"book data source instantiated"&#41;;
                &#125;
            
                public void add&#40;Map m&#41; &#123;
                    books.add&#40;m&#41;;
                &#125;
            
                public void moveFirst&#40;&#41; throws JRException &#123;
                    System.out.println&#40;"rewind"&#41;;
                    pos = 0;
                &#125;
            
                public Object getFieldValue&#40;JRField field&#41; throws JRException &#123;
                    System.out.println&#40;"requesting field '"+field.getName&#40;&#41;+"'"&#41;;
                    return &#40;&#40;Map&#41;books.get&#40;pos&#41;&#41;.get&#40;field.getName&#40;&#41;&#41;;
                &#125;
            
                public boolean next&#40;&#41; &#123;
                    System.out.println&#40;"next"&#41;;
                    if &#40;pos+1 < books.size&#40;&#41;&#41; &#123;
                        pos++;
                        System.out.println&#40;"next&#58; returning true"&#41;;
                        return true;
                    &#125;
                    System.out.println&#40;"next&#58; returning false"&#41;;
                    return false;
                &#125;
            &#125;
            The spring-servlet.xml:
            Code:
            <?xml version="1.0" encoding="UTF-8"?>
            <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
            
            <!--
              - Application context definition for "springapp" DispatcherServlet.
              -->
            
            <beans>
                <bean id="viewList" class="com.logicalapps.appscreate.BookController">
                    <property name="bookList">
                        <ref bean="bookBean"/>
                    </property>
                </bean>
            
                <bean id="bookBean" class="com.logicalapps.appscreate.BookList"/>
            
                <bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
                    <property name="mappings">
                        <props>
                            <prop key="*.do">viewList</prop>
                        </props>
                    </property>
                </bean>
            
                <!-- The ResourceBundleViewResolver&#58; -->
                <bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
                    <property name="basename"><value>views</value></property>
                </bean>
            </beans>
            The views.properties:
            Code:
            viewList.class=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView
            viewList.url=/WEB-INF/reports/bookreport.jrxml
            viewList.reportDataKey=reportData
            I am sure that there may be another way to do this and perhaps more elegant (I would love to see an example). Maybe those Spring Framework masters out there can help...I myself am a Spring Framework beginner (< few weeks =P). Anyone know how to pass parameters to the jasper report? Perhaps by adding some more wire-up and a couple lines of code...just not sure how. Either way, this doesn't appear to be working exactly how the documentation describes.

            Comment


            • #7
              Passing Parameters to Jasper : Anything that you put in your Model will be interpreted in Jasper as a parameter (note that any parameters you wish to access must also be delcared in your report file).

              For example, if in your controller you put :

              Model model = new Hashmap();
              model.put("pageTitle", new String("Sample Report"));
              model.put("pageAttributes", getPageAttributes()); // getPageAttributes returns some class com.xxx.MyPageAttributes

              in your report, you have then to declare the parameters :
              <parameter name="pageTitle" isForPrompting="false" class="java.lang.String"/>
              <parameter name="pageAttributes" isForPrompting="false" class="com.xxx.MyPageAttributes"/>

              then access them like any other parameters :
              $P{pageTitle}

              $P{pageAttributes}.getPriority() // or any other MyPage attributes method


              Setting the jasper datasource : The datasource is used to populate the rows of the report. For example if you're displaying a list of products, the datasource is this list of products.

              In your controller :

              model = new HashMap();
              model.put("reportData", productList); // productList must be of type Collection, array or JRDataSource or JRBeanCollectionDataSource and cannot be null - i think it also doesn't work if it's empty

              Say productList is an array of Product beans. Product has properties "code" and "description".

              In your report, you declare these properties as fields :

              <field name="code" class="java.lang.Integer"/>
              <field name="description" class="java.lang.String"/>

              then you can access them as you would other fields :
              $F{code}
              $F{description}


              I have it all working fine - the Spring classes work exactly as described.

              Comment


              • #8
                I think it is great that you have everything working, but could you provide information that would help me convert my example above?

                I am aware of what JasperReports needs to populate the report

                I am also aware that any key/value in the model *should* be used as parameters as the documentation as clearly states:

                Report parameters are simple name/value pairs and can be added be to the Map for your model as you would add any name/value pair.
                However, if I do as you suggest and return a model which is an instance of a HashMap that contains the parameters and of course the datasource key mapped to datasource which is an instance of "JRDataSource or Collection" (as the reference documentation describes), I get an error:

                java.lang.IllegalArgumentException: No report data supplied in model {reportData={reportData=com.logicalapps.appscreate .BookList@1603522, param1=value1}}
                Note that this is what I originally tried, since the documentation states this is the way to do it. I have been unable to make this work though. Maybe you can shed some light on the specific adjustments I can make to the above example to get me where I need to be?

                Your example restates what the documentation has stated, but doesn't get me any closer to determining why I can't successfully use a Map as the model for the JasperReportsPdfView. Something in the context of my example would be helpful, or perhaps a new example altogether with all the relevant pieces...

                Cheers

                Comment


                • #9
                  I agree with apuarimus!
                  Your example restates what the documentation has stated, but doesn't get me any closer to determining why I can't successfully use a Map as the model for the JasperReportsPdfView. Something in the context of my example would be helpful, or perhaps a new example altogether with all the relevant pieces...
                  Please, can someone help us with this problem?

                  Thanks, Gilberto

                  Comment


                  • #10
                    All,

                    Sorry for the late reply - been away on holiday. I just got back but I promise I will post a solution to this tomorrow

                    Rob

                    Comment


                    • #11
                      All,

                      The exact semantics for accessing the report data source are slightly incorrect in the Spring reference guide as of 1.1.3. I will fix this in time for 1.1.4.

                      When working with JasperReports views in Spring all the data you place in the model Map is passed to JasperReports in one form or another. Most of the data is passed as report parameters however exactly one value in the Map MUST correspond to the report data source. Spring supports three kinds of report data source: Collections, Object arrays and JRDataSource instances.

                      The simplest way to provide Spring with the report data source is to simply place an instance of Collection or an Object array in the model Map. Spring will convert this into an instance of JRDataSource for you. If you need to place more than one Collection or Object array in the model then you should use a specific key and provide this key to the view via the reportDataKey property - in this way Spring will lookup a particular object in the model when looking for the report data source.

                      The code below shows an example of populating the model with a single report parameters, ReportTitle, and the report data source. In this case the key used for the data source is unimportant and the type returned by getData() could be either Collection (or a subtype), JRDataSource (or a subtype) or Object[].

                      Code:
                         private Map getModel&#40;&#41; &#123;
                      		Map model = new HashMap&#40;&#41;;
                      		model.put&#40;"ReportTitle", "Dear Lord!"&#41;;
                      		model.put&#40;"dataSource", getData&#40;&#41;&#41;;
                      
                      		return model;
                      	&#125;
                      
                      	private List getData&#40;&#41; &#123;
                      		List list = new ArrayList&#40;&#41;;
                      
                      		for &#40;int x = 0; x < 10; x++&#41; &#123;
                      			MyBean bean = new MyBean&#40;&#41;;
                      			bean.setId&#40;x&#41;;
                      			bean.setName&#40;"Rob Harrop"&#41;;
                      			bean.setStreet&#40;"foo"&#41;;
                      
                      			list.add&#40;bean&#41;;
                      		&#125;
                      
                      		return list;
                      	&#125;
                      Rob

                      Comment


                      • #12
                        Thanks Rob!

                        But your code isn't different from ours! We've tried all the combinations of data source and whatever we put in the model, we keep receiving this error:

                        Code:
                        java.lang.IllegalArgumentException&#58; Value &#91;null&#93; cannot be converted to a JRDataSource
                        	at org.springframework.ui.jasperreports.JasperReportsUtils.convertReportData&#40;JasperReportsUtils.java&#58;70&#41;
                        	at org.springframework.web.servlet.view.jasperreports.AbstractJasperReportsView.convertReportData&#40;AbstractJasperReportsView.java&#58;213&#41;
                        	at org.springframework.web.servlet.view.jasperreports.AbstractJasperReportsView.getReportData&#40;AbstractJasperReportsView.java&#58;186&#41;
                        	at org.springframework.web.servlet.view.jasperreports.AbstractJasperReportsView.renderMergedOutputModel&#40;AbstractJasperReportsView.java&#58;163&#41;
                        	at org.springframework.web.servlet.view.AbstractView.render&#40;AbstractView.java&#58;242&#41;
                        Gilberto

                        Comment


                        • #13
                          Gilberto,

                          The code you are using is creating a Map inside a Map for the model. Essentially you have created a model Map with a single entry called model containing the Map returned by the getModel() method. The ModelAndView constructor you are using is a convenience constructor for creating a model with a single entry. Try using new ModelAndView(viewName, getModel()) instead.

                          Rob

                          Comment


                          • #14
                            I did this way before, but without success and with the same error! Here's my code, maybe I made some mistake:

                            Code:
                            public class SimpleReportController implements Controller &#123;
                                private final Log log = LogFactory.getLog&#40;SimpleReportController.class&#41;;
                                private CategoriaManager mgr = null;
                                public void setCategoriaManager&#40;CategoriaManager categoriaManager&#41; &#123;
                                    this.mgr = categoriaManager;
                                &#125;
                            	private Map getModel&#40;&#41; &#123;
                            		Map model = new HashMap&#40;&#41;;
                            		model.put&#40;"ReportTitle", "Dear Lord!"&#41;;
                            		model.put&#40;"dataSource", getData&#40;&#41;&#41;;
                            		return model;
                            	&#125;
                            	private List getData&#40;&#41; &#123;
                            		List list = new ArrayList&#40;&#41;;
                            		for &#40;int x = 0; x < 10; x++&#41; &#123;
                            			PersonBean bean = new PersonBean&#40;&#41;;
                            			bean.setId&#40;x&#41;;
                            			bean.setName&#40;"Rob Harrop"&#41;;
                            			bean.setStreet&#40;"foo"&#41;;
                            			list.add&#40;bean&#41;; 
                            		&#125;
                            		return list;
                            	&#125;
                                public ModelAndView handleRequest&#40;HttpServletRequest request,
                                                                  HttpServletResponse response&#41;throws Exception &#123;
                                    if &#40;log.isDebugEnabled&#40;&#41;&#41; &#123;
                                        log.debug&#40;"entering 'handleRequest' method..."&#41;;
                                    &#125;	
                                    return new ModelAndView&#40;"simpleReport", getModel&#40;&#41;&#41;;
                                &#125;
                            &#125;

                            Comment


                            • #15
                              Gilberto,

                              Here is the full code for a sample controller that I have working correctly on my machine. It is not particularly different to the code you are using here and it works fine on my Mac and my Windows box.

                              Code:
                              package net.cakesolutions.jr;
                              
                              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;
                              
                              /**
                               * @author robh
                               *  
                               */
                              public class ReportController extends MultiActionController &#123;
                              
                              	public ModelAndView handleSimpleReport&#40;HttpServletRequest request,
                              			HttpServletResponse response&#41; throws Exception &#123;
                              		return new ModelAndView&#40;"simpleReport", getModel&#40;&#41;&#41;;
                              	&#125;
                              
                              	public ModelAndView handleSimpleReportCompile&#40;HttpServletRequest request,
                              			HttpServletResponse response&#41; throws Exception &#123;
                              
                              		return new ModelAndView&#40;"simpleReportCompile", getModel&#40;&#41;&#41;;
                              	&#125;
                              
                              	public ModelAndView handleSimpleReportHtml&#40;HttpServletRequest request,
                              			HttpServletResponse response&#41; throws Exception &#123;
                              
                              		return new ModelAndView&#40;"simpleReportHtml", getModel&#40;&#41;&#41;;
                              	&#125;
                              	
                              	public ModelAndView handleSimpleReportCsv&#40;HttpServletRequest request,
                              			HttpServletResponse response&#41; throws Exception &#123;
                              
                              		return new ModelAndView&#40;"simpleReportCsv", getModel&#40;&#41;&#41;;
                              	&#125;
                              	
                              	public ModelAndView handleSimpleReportExcel&#40;HttpServletRequest request,
                              			HttpServletResponse response&#41; throws Exception &#123;
                              
                              		return new ModelAndView&#40;"simpleReportExcel", getModel&#40;&#41;&#41;;
                              	&#125;
                              
                              	private Map getModel&#40;&#41; &#123;
                              		Map model = new HashMap&#40;&#41;;
                              		model.put&#40;"ReportTitle", "Dear Lord!"&#41;;
                              		model.put&#40;"dataSource", getData&#40;&#41;&#41;;
                              
                              		return model;
                              	&#125;
                              
                              	private List getData&#40;&#41; &#123;
                              		List list = new ArrayList&#40;&#41;;
                              
                              		for &#40;int x = 0; x < 10; x++&#41; &#123;
                              			MyBean bean = new MyBean&#40;&#41;;
                              			bean.setId&#40;x&#41;;
                              			bean.setName&#40;"Rob Harrop"&#41;;
                              			bean.setStreet&#40;"foo"&#41;;
                              
                              			list.add&#40;bean&#41;;
                              		&#125;
                              
                              		return list;
                              	&#125;
                              &#125;
                              Are you sure you are getting the exact same error - the code you have should work fine. Make sure that you haven't configured a value for the reportDataKey property of the view class in the views resource bundle.

                              Rob

                              Comment

                              Working...
                              X