1

I am trying to retrieve csv file from JSF managed bean.

Right now I am doing it this way,

CsvController: Bean which responds output with content type text/csv.

samplecsv.xhtml: A webpage which contains the code:

#{csvController.generateReport()}

When I browse this page on browser, a download dialog opens which enables downloading the csv file.

report.xhtml:

Webpage which downloads that csv:

d3.csv('http://mysite/samplecsv.xhtml');

Is there a way to get rid of samplecsv.xhtml and directly retrieve csv file from bean in report.xhtml? Something like d3.csv('http://mysite/csvController/report') would be perfect

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
coolscitist
  • 2,915
  • 6
  • 37
  • 58
  • I have never used that! The thing is we are not really pro in java. We needed a quick web app and built one by integrating JSF(with primefaces and omnifaces) with spring (thought it would be best of all worlds). It did us good in short term but I am thinking about removing JSF completely and using pure spring mvc. Keeping that transition in mind, would it be good idea to use Spring servlet for csv files and leave the rest with Faces Servlet? – coolscitist Oct 30 '14 at 18:15
  • That is indeed what I am looking for. Now the new implementation will consist of CsvServlet which takes report name as parameter. I am still confused about how to resolve the report and make sure it is properly initialized. Each report is a managed bean accessing other beans with autowired DataSource and other services. I don't want to inject all the reports to CsvServlet. After reading report name from Csv request, how would I call a corresponding report bean which has been automatically initialized with datasource and services? – coolscitist Oct 31 '14 at 02:12
  • This is what I am thinking: 1. CsvServlet: For each request, responds with a csv file by using ReportResolver 2. ReportResolver: CsvServlet passes report name to it and ReportResolver should be able to initialize report and get csv string out of report. 3. Report: Fire sql query, and return csv string as output by calling a service which converts resultset to csv string. (@Autowired should still work for all of them) – coolscitist Oct 31 '14 at 02:17
  • I understood that CsvController would be a servlet which responds with csv file. What I also wanted was automatic mapping of reports. Like a request such as http://site/report/report1 should automatically produce csv for report1. I understand request to /report would be handled by CsvController. Then I would need to code the logic to figure out which report the request is asking for. There will be tons of report, so I was hoping for automated resolving of the report. May be I should use Java Reflection. – coolscitist Oct 31 '14 at 13:10
  • Ok so I will have to code an automated system for resolving reports properly right? – coolscitist Oct 31 '14 at 13:48
  • No. Actually right now, I have generateReport() method in each report. Each report is a managedbean and, I use them as: #report1.generateReport() in report1_csv.xhtml and #report2.generateReport() in report2_csv.xhtml. Those xhtml respond with csv files. Each report has two xhtml files: one to provide csv by calling generateReport() and another xhtml to use that previous one and render charts. – coolscitist Oct 31 '14 at 14:56
  • Lol you should have seen our previous code. You might have hit us with a hammer! I am trying really hard to improve it. We are trying to write new reporting engine. Basic concept is provide data through csv for each report and write all logic for visualization of data at client side. If you have guidance/example for that please help us. We need customized viz so we are using d3, and can't really use any other reporting engine. – coolscitist Oct 31 '14 at 15:09

1 Answers1

1

The pattern you're asking about is not really native to the way JSF works. See JSF 2: invoking managed bean directly

If you still want to download the content directly from the managed bean, here is an example in how to do it. Anyway, the url to the download link in your report.xhtml should be generated with some jsf component like <f:commandLink action="#csvController.download()}" /> See How to provide a file download from a JSF backing bean?

My recommended approach is to create a new @WebServlet("/csvController") or JAX-RS @Path("/csvController") front-end and call your business logic from here. To access the managed bean from the servlet you could do it like this: Possible to inject @ManagedBean as a @ManagedProperty into @WebServlet?

Anyway, i recommed you to take a look at: Backing beans (@ManagedBean) or CDI Beans (@Named)? Are @ManagedBeans obsolete in JavaEE6 because of @Named in CDI/Weld?

Community
  • 1
  • 1
Andrés Oviedo
  • 1,237
  • 12
  • 28
  • Thank you for the reply. We are using an integration between spring and primefaces: https://github.com/michail-nikolaev/primefaces-spring-scopes. We are trying to slowly remove the primefaces part. We use FacesServlet for all the pages. Would it be possible to use Spring's servlet for csv files instead? – coolscitist Oct 27 '14 at 01:58
  • Yes. You can. Here are 2 examples implementing a download controller with Spring: http://www.codejava.net/frameworks/spring/spring-mvc-with-csv-file-download-example http://www.codejava.net/frameworks/spring/spring-mvc-sample-application-for-downloading-files . Anyway, i recommend you to move your #generateRepòrt function to a spring managed bean. – Andrés Oviedo Oct 27 '14 at 07:44
  • Ok. Then I will try with using SpringServlet for csv but FacesServlet for rest of the application. – coolscitist Oct 30 '14 at 17:06