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

  • JasperReports configuration headache

    Hello,
    I am trying to get the structure in place to use JasperReports for my web app using spring, but I can't seem to get the URL's to call the right handler methods. The following is my setup:

    Fragment of web.xml
    Code:
    	<servlet>
    		<servlet-name>controllers</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<load-on-startup>2</load-on-startup>
    	</servlet>
    
    	<servlet>
    		<servlet-name>reports</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<load-on-startup>3</load-on-startup>
    	</servlet>
    
    	<servlet-mapping>
    		<servlet-name>controllers</servlet-name>
    		<url-pattern>*.do</url-pattern>
    	</servlet-mapping>
    
    	<servlet-mapping>
    		<servlet-name>reports</servlet-name>
    		<url-pattern>*.html</url-pattern>
    	</servlet-mapping>
    	<servlet-mapping>
    		<servlet-name>reports</servlet-name>
    		<url-pattern>*.pdf</url-pattern>
    	</servlet-mapping>
    	<servlet-mapping>
    		<servlet-name>reports</servlet-name>
    		<url-pattern>*.csv</url-pattern>
    	</servlet-mapping>
    Fragment of reports-servlet.xml:
    Code:
    <beans>
    
    	<!-- ================== Basic Reports Definitions ================= -->
    
        <!-- ResourceBundleViewResolver configures the whole set of JasperReports -->
    	<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
    		<!-- Pointer to classes/reports.properties -->
        	<property name="basename">
            	<value>reports</value>
            </property>
        </bean>
    
    	<!-- Map url's to bean names -->
    <!--	<bean id="defaultHandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>-->
    
        <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        	<property name="mappings">
        		<props>
        			<prop key="/secure/staff/exampleReport.*">exampleReport</prop>
                </props>
            </property>
        </bean>
    
    	<!-- For the report controllers, resolve the method to call based on 
    		 which type of report is requested. -->
        <bean id="resolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
        	<property name="mappings">
            	<props>
                	<prop key="/*.pdf">handlePdf</prop>
                    <prop key="/*.html">handleHtml</prop>
                    <prop key="/*.csv">handleCsv</prop>
                    <prop key="/*.*">handleCsv</prop>
               	</props>
        	</property>
        </bean>
    
    
    	<!-- =============== Controller Definitions ============== -->
    
        <bean id="exampleReport" class="org.dm.daniel.hope.web.report.ExampleReportController">
        	<property name="methodNameResolver"><ref local="resolver"/></property>
        </bean>
    
    </beans>
    Controller code:
    Code:
    public class ExampleReportController extends AbstractReportController &#123;
    
        protected String getReportId&#40;&#41; &#123;
            return "exampleReport";
        &#125;
           
    
    	protected Map getModel&#40;HttpServletRequest request, HttpServletResponse response&#41; throws Exception &#123;
    	    Map model = new HashMap&#40;&#41;;
    	    model.put&#40;"ReportTitle", "title!"&#41;;
    
            return model;
    	&#125;
    
        protected Collection getDataSource&#40;HttpServletRequest request, HttpServletResponse response&#41; throws Exception &#123;
        	List list = new ArrayList&#40;&#41;;
        	return list;
        &#125;
    &#125;
    
    // Simple abstract class for generating reports that specifies
    // the handler methods
    public abstract class AbstractReportController extends MultiActionController &#123;
        protected static final String DATA_SOURCE_KEY = "dataSource"; 
        
        public ModelAndView handleCsv&#40;HttpServletRequest request, HttpServletResponse response&#41; throws Exception &#123;
    
            return new ModelAndView&#40;getReportId&#40;&#41; + "Csv", 
                    getReportModel&#40;request, response&#41;&#41;;
    	&#125;
           
        public ModelAndView handleHtml&#40;HttpServletRequest request, HttpServletResponse response&#41; throws Exception &#123;
    
            return new ModelAndView&#40;getReportId&#40;&#41; + "Html", 
                    getReportModel&#40;request, response&#41;&#41;;
    	&#125;
           
        public ModelAndView handlePdf&#40;HttpServletRequest request, HttpServletResponse response&#41; throws Exception &#123;
    
            return new ModelAndView&#40;getReportId&#40;&#41; + "Pdf", 
                    getReportModel&#40;request, response&#41;&#41;;
    	&#125;
    
        protected Map getReportModel&#40;HttpServletRequest request, HttpServletResponse response&#41; throws Exception &#123;
            // Needs to be a linked hash map to preserve the order of the elements
            Map ret = new LinkedHashMap&#40;&#41;;
    
            // Set the data source first because the first collection needs to be 
            // the data source for Spring to detect it
            ret.put&#40;DATA_SOURCE_KEY, getDataSource&#40;request, response&#41;&#41;;
            
            // Add the rest of the model
            ret.putAll&#40;getModel&#40;request, response&#41;&#41;;
            
            return ret;
        &#125;
        
        protected abstract String getReportId&#40;&#41;;
    
        protected Map getModel&#40;HttpServletRequest request, HttpServletResponse response&#41; throws Exception &#123;
            return new HashMap&#40;&#41;;
        &#125;
    
        protected abstract Collection getDataSource&#40;HttpServletRequest request, HttpServletResponse response&#41; throws Exception;
    &#125;

    However, everytime I try to go to: http://localhost:8080/MyApp/secure/s...mpleReport.pdf

    I get the following in the log:

    2005-04-19 16:31:49,474 DEBUG [org.springframework.web.servlet.DispatcherServlet] Testing handler map [org.springframework.web.servlet.handler.SimpleUrlH andlerMapping@1497b1] in DispatcherServlet with name 'reports'
    2005-04-19 16:31:49,474 DEBUG [org.springframework.web.servlet.handler.SimpleUrlH andlerMapping] Looking up handler for [/secure/staff/exampleReport.pdf]
    2005-04-19 16:31:49,474 DEBUG [org.springframework.web.servlet.DispatcherServlet] Testing handler adapter [org.springframework.web.servlet.mvc.SimpleControll erHandlerAdapter@167acf2]
    2005-04-19 16:31:49,475 DEBUG [org.springframework.web.servlet.DispatcherServlet] Last-Modified value for [/MyApp/secure/staff/exampleReport.pdf] is [-1]
    2005-04-19 16:31:49,475 DEBUG [org.springframework.web.servlet.DispatcherServlet] DispatcherServlet with name 'reports' received request for [/MyApp/secure/staff/exampleReport.pdf]
    2005-04-19 16:31:49,475 DEBUG [org.springframework.web.servlet.DispatcherServlet] Testing handler adapter [org.springframework.web.servlet.mvc.SimpleControll erHandlerAdapter@167acf2]
    2005-04-19 16:31:49,475 WARN [org.springframework.web.servlet.PageNotFound] No handling method can be found for request [org.apache.catalina.connector.RequestFacade@18b4cc b]
    Which then gives me a 404 - Page Not Found. What am I doing wrong? For those who have more experience using the JasperReports framework in Spring, is my approach a good one?

  • #2
    The problem here is that:
    Code:
    <prop key="/*.pdf">handlePdf</prop>
    will not match you report URL, instead you should use:
    Code:
    <prop key="/secure/staff/exampleReport.pdf">handlePdf</prop>
    Rob

    Comment


    • #3
      Rob,
      Thanks for your prompt response. The fix you suggested worked. However, it doesn't make sense to me why my /*.pdf would not work. To quote from the PropertiesMethodNameResolver javadoc comments:


      Supports direct matches, e.g. a registered "/test" matches "/test", and a various Ant-style pattern matches, e.g. a registered "/t*" matches both "/test" and "/team". For details, see the PathMatcher class.
      What am I missing?

      Comment


      • #4
        In addition to my question above, I have been experiencing further problems getting JasperReports working. After changing the line you specified, I now get the following exception when I am using a precompiled report:

        2005-04-21 14:12:05,314 ERROR [StandardWrapper[/Hope:reports]] Servlet.service() for servlet reports threw exception
        java.lang.NoClassDefFoundError
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:164)
        at java.awt.GraphicsEnvironment.getLocalGraphicsEnvir onment(GraphicsEnvironment.java:68)
        at net.sf.jasperreports.engine.util.JRGraphEnvInitial izer.initializeGraphEnv(JRGraphEnvInitializer.java :102)
        at net.sf.jasperreports.engine.fill.JRBaseFiller.<ini t>(JRBaseFiller.java:224)
        at net.sf.jasperreports.engine.fill.JRVerticalFiller. <init>(JRVerticalFiller.java:126)
        at net.sf.jasperreports.engine.fill.JRVerticalFiller. <init>(JRVerticalFiller.java:118)
        at net.sf.jasperreports.engine.fill.JRFiller.fillRepo rt(JRFiller.java:151)
        at net.sf.jasperreports.engine.JasperFillManager.fill Report(JasperFillManager.java:472)
        at org.springframework.web.servlet.view.jasperreports .AbstractJasperReportsSingleFormatView.renderRepor t(AbstractJasperReportsSingleFormatView.java:66)
        at org.springframework.web.servlet.view.jasperreports .AbstractJasperReportsView.renderMergedOutputModel (AbstractJasperReportsView.java:411)
        at org.springframework.web.servlet.view.AbstractView. render(AbstractView.java:250)
        at org.springframework.web.servlet.DispatcherServlet. render(DispatcherServlet.java:917)
        at org.springframework.web.servlet.DispatcherServlet. doDispatch(DispatcherServlet.java:696)
        at
        ...
        When I try to compile a report on the fly, I get:


        2005-04-20 14:20:15,765 INFO [org.springframework.web.servlet.view.jasperreports .JasperReportsPdfView] Compiling Jasper Report loaded from ServletContext resource [/WEB-INF/reports/regsByTrack.jrxml]
        2005-04-20 14:20:17,676 ERROR [StandardWrapper[/Hope:reports]] Servlet.service() for servlet reports threw exception
        java.lang.InternalError: Can't connect to X11 window server using 'ltsp-ws-003.dm.org:0.0' as the value of the DISPLAY variable.
        at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
        at sun.awt.X11GraphicsEnvironment.access$000(X11Graph icsEnvironment.java:53)
        at sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEn vironment.java:142) at java.security.AccessController.doPrivileged(Native Method)
        at sun.awt.X11GraphicsEnvironment.<clinit>(X11Graphic sEnvironment.java:131)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:164)
        at java.awt.GraphicsEnvironment.getLocalGraphicsEnvir onment(GraphicsEnvironment.java:68)
        at net.sf.jasperreports.engine.util.JRGraphEnvInitial izer.initializeGraphEnv(JRGraphEnvInitializer.java :102)
        at net.sf.jasperreports.engine.fill.JRBaseFiller.<ini t>(JRBaseFiller.java:224)
        at net.sf.jasperreports.engine.fill.JRVerticalFiller. <init>(JRVerticalFiller.java:126)
        at net.sf.jasperreports.engine.fill.JRVerticalFiller. <init>(JRVerticalFiller.java:118)
        at net.sf.jasperreports.engine.fill.JRFiller.fillRepo rt(JRFiller.java:151)
        at net.sf.jasperreports.engine.JasperFillManager.fill Report(JasperFillManager.java:472)
        at org.springframework.web.servlet.view.jasperreports .AbstractJasperReportsSingleFormatView.renderRepor t(AbstractJasperReportsSingleFormatView.java:66)
        at org.springframework.web.servlet.view.jasperreports .AbstractJasperReportsView.renderMergedOutputModel (AbstractJasperReportsView.java:411)
        at org.springframework.web.servlet.view.AbstractView. render(AbstractView.java:250)
        ...
        Why is this happening?

        Comment


        • #5
          In answer to your first question /*.pdf will match /foo.pdf and /bar.pdf but not /foo/bar.pdf. In Ant paths that kind of constructs is /**/*.pdf which will match /foo.pdf, /foo/bar.pdf and /foo/abc/bar/pdf.

          For your second question, it loks like you have a problem with the X11 configuration on your Unix box. AWT which is used by JasperReports requires X11 libs when running on Unix. You can try setting -Djava.awt.headless=true when starting your app, but I don't think that will work. If not, you should install an X11 server on your machine (try XFree86).

          Rob

          Comment


          • #6
            Rob,
            You're a life-saver! Thanks for your answers...they cleared up both of my questions, along with my headache!

            I had to add the -Djava.awt.headless=true to the startup script for Tomcat, which means that everyone who wants to run my app will have to do this, but otherwise I am very pleased with the jasperreports framework you have developed. Thanks a lot!

            Comment

            Working...
            X