You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Matthew Shaw <Ma...@facet.com.au> on 2009/11/26 00:53:42 UTC

REST and Jasper

Hi,

 

I'd like to integrate jasper reports. All going well, except for how
Jasper locates images in a web environment, using an ImageServlet. The
demo app from jasper requires that I set a map into the http session
which contains a cache of the images as they are called. 

 

Here is a snippet of my code:

 

@Resource

    private HttpServletRequest httpRequest; 

                

                public Response getCustomerList(ReportQuery reportQuery)
{

                                

                                log.debug("Start - getCustomerList");

                                log.debug("Customer Id:
"+reportQuery.getCustomerId());

                                log.debug("Start from controller id:
"+reportQuery.getStartFromControllerId());

                                

                                // TODO: this is an example report only
used to test the framework.

                                ByteArrayOutputStream baos = new
ByteArrayOutputStream();

                                

                                try {

                                                InputStream is =
ResourceUtils.getClasspathResourceStream("/WEB-INF/jasperreports/WebappR
eport.jasper", this.getClass(), BusFactory.getDefaultBus());

                                                JasperReport
jasperReport = (JasperReport)JRLoader.loadObject(is);

                                                

                                                Map parameters = new
HashMap();

 
parameters.put("ReportTitle", "Address Report");

 


                                                JasperPrint jasperPrint
= 

 
JasperFillManager.fillReport(

 
jasperReport, 

 
parameters, 

 
new DataSourceStub()

 
);

                                                

                                                JRHtmlExporter exporter
= new JRHtmlExporter();

 
httpRequest.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_
SESSION_ATTRIBUTE, jasperPrint);

 
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);

 
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);

 
exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI,
"image?image=");

                                                exporter.exportReport();

                                                

                                } catch (JRException e) {

                                                e.printStackTrace();

                                }

                                

                                

                                return Response.ok(baos.toString(),
"text/html").build();

                }

 

Note the @Resource  private HttpServletRequest httpRequest field. Is
this the best way to do this? Is the field thread safe? As I potentially
have a lot of users requesting this service... 

 

Cheers,

Matt.


Re: REST and Jasper

Posted by Sergey Beryozkin <sb...@progress.com>.
Hi Matthew

Please see comments with S.B inlined....

Hi Sergey,

Thanks for your response.

I added the @HttpServletRequest property to my bean and stored the key
in the session that way. As each image is loaded it is stored in the
session key. Then when I call the jasper exporter to produce the report,
jasper produces html with img references which the server then performs
a simple GET for the image to a custom jax-rs service I publish for
fetching the images from the session key.

> S.B. Sounds interesting. What might be of interest in this specific case is that it is possible to configure a
CXF servlet to serve static resources or tell it to redirect to say to a default servlet to do the same...Check "DefaultCXFServlet"
at http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs_dispatch/WEB-INF/web.xml


I'd be quite happy to integrate the code into your
RequestDispatcherProvider in a generic way, perhaps an injected property
to specifiy the session key?

> S.B. As I mentioned earlier on, one can configure a RequestDispatcherProvider to store a given class instance as a request session 
> value under a specified key. It has a classResources map property, name is the class name (say a fully qualified name of the 
> JasperReport class) and the value is the key which will be used to store JasperReport instances (to be returned from a JAXRS 
> resource method). I'm just curious, how RequestDispatcherProvider may be extended so that it can be easily used to handle advanced 
> cases like the one you're dealing with... If you get a chance, please try to experiment with creating a custom MessageBodyWriter, 
> based on the RequestDispatcherProvider code, and see how far you can get in simplifying the actual JAXRS resource method code, it 
> may help in identifying how the RequestDispatcherProvider itself can be extended...

BTW - I am really enjoying using cxf and it's JAX-RS implementation. It
is just so easy, thanks very much for all your effort! I'm enjoying web
programming again! :-)

> S.B thanks a lot. We need to acknowledge the lead of Jersey/RestEasy but of course we're committed to providing a competitive 
> environment in CXF

Cheers, Sergey

Cheers,
Matt.


-----Original Message-----
From: Sergey Beryozkin [mailto:sberyozk@progress.com]
Sent: Thursday, 26 November 2009 19:51
To: users@cxf.apache.org
Subject: Re: REST and Jasper

Hi,

>>Note the @Resource  private HttpServletRequest httpRequest field. Is
>>this the best way to do this? Is the field thread safe?

Yes, it is a thread-safe proxy...

By the way, starting from 2.2.5 it is possible to use a
RequestDispatcherProvider [1] which implements JAXRS MessageBodyWriter
to
redirect to other servlets. You can configure RequestDispatcherProvider
to store the response object either as a request parameter
or request session parameter and you can tell it what is the name of the
key.

Ex, you can have a method returning an instance of jasperPrint and this
provider storing it as an
ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE

I'm not sure if it can help in your specific case, but I'd like to
figure out how RequestDispatcherProvider can be enhanced, if
needed, for users be able to avoid dealing with
ResourceUtils.getClasspathResourceStream, unless you only used it for
testing...

thanks, Sergey




[1] http://cxf.apache.org/docs/jax-rs.html#JAX-RS-Redirection

----- Original Message ----- 
From: "Matthew Shaw" <Ma...@facet.com.au>
To: <us...@cxf.apache.org>
Sent: Wednesday, November 25, 2009 11:53 PM
Subject: REST and Jasper


Hi,


I'd like to integrate jasper reports. All going well, except for how
Jasper locates images in a web environment, using an ImageServlet. The
demo app from jasper requires that I set a map into the http session
which contains a cache of the images as they are called.



Here is a snippet of my code:



@Resource

    private HttpServletRequest httpRequest;



                public Response getCustomerList(ReportQuery reportQuery)
{



                                log.debug("Start - getCustomerList");

                                log.debug("Customer Id:
"+reportQuery.getCustomerId());

                                log.debug("Start from controller id:
"+reportQuery.getStartFromControllerId());



                                // TODO: this is an example report only
used to test the framework.

                                ByteArrayOutputStream baos = new
ByteArrayOutputStream();



                                try {

                                                InputStream is =
ResourceUtils.getClasspathResourceStream("/WEB-INF/jasperreports/WebappR
eport.jasper", this.getClass(), BusFactory.getDefaultBus());

                                                JasperReport
jasperReport = (JasperReport)JRLoader.loadObject(is);



                                                Map parameters = new
HashMap();


parameters.put("ReportTitle", "Address Report");




                                                JasperPrint jasperPrint
=


JasperFillManager.fillReport(


jasperReport,


parameters,


new DataSourceStub()


);



                                                JRHtmlExporter exporter
= new JRHtmlExporter();


httpRequest.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_
SESSION_ATTRIBUTE, jasperPrint);


exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);


exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);


exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI,
"image?image=");

                                                exporter.exportReport();



                                } catch (JRException e) {

                                                e.printStackTrace();

                                }





                                return Response.ok(baos.toString(),
"text/html").build();

                }



Note the @Resource  private HttpServletRequest httpRequest field. Is
this the best way to do this? Is the field thread safe? As I potentially
have a lot of users requesting this service...



Cheers,

Matt.



RE: REST and Jasper

Posted by Matthew Shaw <Ma...@facet.com.au>.
Hi Sergey,

Thanks for your response. 

I added the @HttpServletRequest property to my bean and stored the key
in the session that way. As each image is loaded it is stored in the
session key. Then when I call the jasper exporter to produce the report,
jasper produces html with img references which the server then performs
a simple GET for the image to a custom jax-rs service I publish for
fetching the images from the session key. 

I'd be quite happy to integrate the code into your
RequestDispatcherProvider in a generic way, perhaps an injected property
to specifiy the session key?

BTW - I am really enjoying using cxf and it's JAX-RS implementation. It
is just so easy, thanks very much for all your effort! I'm enjoying web
programming again! :-)

Cheers,
Matt.


-----Original Message-----
From: Sergey Beryozkin [mailto:sberyozk@progress.com] 
Sent: Thursday, 26 November 2009 19:51
To: users@cxf.apache.org
Subject: Re: REST and Jasper

Hi,

>>Note the @Resource  private HttpServletRequest httpRequest field. Is
>>this the best way to do this? Is the field thread safe?

Yes, it is a thread-safe proxy...

By the way, starting from 2.2.5 it is possible to use a
RequestDispatcherProvider [1] which implements JAXRS MessageBodyWriter
to 
redirect to other servlets. You can configure RequestDispatcherProvider
to store the response object either as a request parameter 
or request session parameter and you can tell it what is the name of the
key.

Ex, you can have a method returning an instance of jasperPrint and this
provider storing it as an 
ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE

I'm not sure if it can help in your specific case, but I'd like to
figure out how RequestDispatcherProvider can be enhanced, if 
needed, for users be able to avoid dealing with
ResourceUtils.getClasspathResourceStream, unless you only used it for
testing...

thanks, Sergey




[1] http://cxf.apache.org/docs/jax-rs.html#JAX-RS-Redirection

----- Original Message ----- 
From: "Matthew Shaw" <Ma...@facet.com.au>
To: <us...@cxf.apache.org>
Sent: Wednesday, November 25, 2009 11:53 PM
Subject: REST and Jasper


Hi,


I'd like to integrate jasper reports. All going well, except for how
Jasper locates images in a web environment, using an ImageServlet. The
demo app from jasper requires that I set a map into the http session
which contains a cache of the images as they are called.



Here is a snippet of my code:



@Resource

    private HttpServletRequest httpRequest;



                public Response getCustomerList(ReportQuery reportQuery)
{



                                log.debug("Start - getCustomerList");

                                log.debug("Customer Id:
"+reportQuery.getCustomerId());

                                log.debug("Start from controller id:
"+reportQuery.getStartFromControllerId());



                                // TODO: this is an example report only
used to test the framework.

                                ByteArrayOutputStream baos = new
ByteArrayOutputStream();



                                try {

                                                InputStream is =
ResourceUtils.getClasspathResourceStream("/WEB-INF/jasperreports/WebappR
eport.jasper", this.getClass(), BusFactory.getDefaultBus());

                                                JasperReport
jasperReport = (JasperReport)JRLoader.loadObject(is);



                                                Map parameters = new
HashMap();


parameters.put("ReportTitle", "Address Report");




                                                JasperPrint jasperPrint
=


JasperFillManager.fillReport(


jasperReport,


parameters,


new DataSourceStub()


);



                                                JRHtmlExporter exporter
= new JRHtmlExporter();


httpRequest.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_
SESSION_ATTRIBUTE, jasperPrint);


exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);


exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);


exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI,
"image?image=");

                                                exporter.exportReport();



                                } catch (JRException e) {

                                                e.printStackTrace();

                                }





                                return Response.ok(baos.toString(),
"text/html").build();

                }



Note the @Resource  private HttpServletRequest httpRequest field. Is
this the best way to do this? Is the field thread safe? As I potentially
have a lot of users requesting this service...



Cheers,

Matt.



Re: REST and Jasper

Posted by Sergey Beryozkin <sb...@progress.com>.
Hi,

>>Note the @Resource  private HttpServletRequest httpRequest field. Is
>>this the best way to do this? Is the field thread safe?

Yes, it is a thread-safe proxy...

By the way, starting from 2.2.5 it is possible to use a RequestDispatcherProvider [1] which implements JAXRS MessageBodyWriter to 
redirect to other servlets. You can configure RequestDispatcherProvider to store the response object either as a request parameter 
or request session parameter and you can tell it what is the name of the key.

Ex, you can have a method returning an instance of jasperPrint and this provider storing it as an 
ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE

I'm not sure if it can help in your specific case, but I'd like to figure out how RequestDispatcherProvider can be enhanced, if 
needed, for users be able to avoid dealing with ResourceUtils.getClasspathResourceStream, unless you only used it for testing...

thanks, Sergey




[1] http://cxf.apache.org/docs/jax-rs.html#JAX-RS-Redirection

----- Original Message ----- 
From: "Matthew Shaw" <Ma...@facet.com.au>
To: <us...@cxf.apache.org>
Sent: Wednesday, November 25, 2009 11:53 PM
Subject: REST and Jasper


Hi,


I'd like to integrate jasper reports. All going well, except for how
Jasper locates images in a web environment, using an ImageServlet. The
demo app from jasper requires that I set a map into the http session
which contains a cache of the images as they are called.



Here is a snippet of my code:



@Resource

    private HttpServletRequest httpRequest;



                public Response getCustomerList(ReportQuery reportQuery)
{



                                log.debug("Start - getCustomerList");

                                log.debug("Customer Id:
"+reportQuery.getCustomerId());

                                log.debug("Start from controller id:
"+reportQuery.getStartFromControllerId());



                                // TODO: this is an example report only
used to test the framework.

                                ByteArrayOutputStream baos = new
ByteArrayOutputStream();



                                try {

                                                InputStream is =
ResourceUtils.getClasspathResourceStream("/WEB-INF/jasperreports/WebappR
eport.jasper", this.getClass(), BusFactory.getDefaultBus());

                                                JasperReport
jasperReport = (JasperReport)JRLoader.loadObject(is);



                                                Map parameters = new
HashMap();


parameters.put("ReportTitle", "Address Report");




                                                JasperPrint jasperPrint
=


JasperFillManager.fillReport(


jasperReport,


parameters,


new DataSourceStub()


);



                                                JRHtmlExporter exporter
= new JRHtmlExporter();


httpRequest.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_
SESSION_ATTRIBUTE, jasperPrint);


exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);


exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);


exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI,
"image?image=");

                                                exporter.exportReport();



                                } catch (JRException e) {

                                                e.printStackTrace();

                                }





                                return Response.ok(baos.toString(),
"text/html").build();

                }



Note the @Resource  private HttpServletRequest httpRequest field. Is
this the best way to do this? Is the field thread safe? As I potentially
have a lot of users requesting this service...



Cheers,

Matt.