I am trying to develop a program in JSF where I need to save a file by clicking a button. When the button is clicked I need to get a "Save As" dialog box to save the file. However with the below code I could able to get only "File Download" box which shows Open, Save and Cancel options.
Doesn't the "save" option give options for "Save As"? That "File Download" box is browser specific. Other browsers will have a different one. Other client computers may not even have a browser at all.
Some clients will configure certain extensions to be automatically opened by some programs or automatic download.
The best you can do at the server side is set the right content type and length headers. What happens to the content at the client side is dependent on the client's browser settings (if any).
Do not attempt to obtain direct access to the SerlvetResponse outputstream in JSF code. Do not attempt to set the response headers, content-type or content. JSF owns the ServletResponse and you will interfere with its proper operation, which is to generate an HTML response data stream based on the JSF component model.
If you need to output a file, use a regular servlet. Otherwise you are simply placing yourself in the same position as a carpenter who has an entire toolbox full of hammers but needs to drive a screw.
An IDE is no substitute for an Intelligent Developer.
Writing code that uses framework-specific functions and convoluted logic in place of simple framework-independent standard code is very definitely hammering screws.
JSF is not the Master Control Program from TRON that must handle each and every request coming into the webapp, no matter what type it is. It is extremely good at managing form-based activity. It was never intended to be a document generator or web services client or any other non-form activity.
It was also designed from Day 1 to work with POJO JavaBeans. The best JSF apps have almost no JSF-specific code in them other than JSF Model objects, because JSF was designed to provide most framework-specific functionality via external injection. JSF backing beans are nothing more than standard J2EE request/session/application-scope beans that have been constructed automatically by JSF instead of by manual effort and they may be freely passed back and forth between JSF and non-JSF code.
So, given a choice between a bog-standard servlet to generate my downloadable documents or an arcane construct that forcibly hijacks the JSF processor for the sake of gratuitously using an API which quite likely to become obsolete a lot quicker than the core servlet API does, I'll go with the servlet.
Just because people can do things the hard way doesn't mean that they should. Even if it's published on the Internet (that grand repository of Truth and Wisdom).
Joined: Mar 17, 2012
JSF is a standard now. It's just as likely to become obsolete as the servlet spec itself. There is no force hijaking going on in these examples. Just proper use of the exposed APIs.
Trying to hijack the user's JSF request and forwarding to a file servlet is just as much screw hammering.
Any time you choose a complex solution in place of a simple one, you raise the odds that it will contain components that will break or go obsolete. Not to mention that the more complex a solution is, the more expensive it is to debug and maintain.
JSF is an integral part of the JEE standard, true. However, it is a young platform with lots of warts in it and has already undergone some fairly significant changes. It will undergo more, no doubt.
The base servlet spec hasn't remained constant over the years, either, but it is mature enough that it's fairly unlike to change in ways that cause code breakage - unlike, say, the EL interfaces in JSF's low-level APIs.
Joined: Mar 17, 2012
JSP spec was older than JSF spec. People who preferred JSP spec over JSF are now stuck with code written to an obsolete spec. Newer is not always better either. Whether the spec is older or newer doesn't matter here. It's whether the aspect of the spec you are trying to use is stable or not that should matter.
Both solutions use the spec. Whether one solution is more complex or not is subjective.
The JSF spec is there to shield you away from working with the Servlet APIs in the first place. There are still cases when developers find themselves having to fall back to the servlet APIs. The developers of the JSF spec (linked to above) immediately develop JSF features for those cases to bridge those gaps.
Global error handling and file upload/download were some of those gaps that they have already filled.
[ UD: Please don't quote the entire post for each response. It's clear which post you're referring to in that case. ]
JSF was never intended to supplant servlets. In point of fact, JSF relies on a servlet to act as its master Controller. However, JSF was designed to solve a particular set of problems, not be a universal solution, and one of the things I like about JSF is that unlike older, more unwieldy frameworks, it doesn't have to be in control in cases where its particular strengths don't apply.
JSF is designed to provide an exceptionally clean and simple MVC implementation for JEE. But not every web request requires MVC. There is no benefit to ramming non-MVC transactions through an MVC framework. Instead of coding a simple stock servlet that creates content for downloading and ships it out via techniques well-documented in just about any introductory J2EE book, you're proposing using the FacesServlet to accept an incoming request, which is then going to have to go to all the trouble of constructing a FacesContext, Component Object tree, EL context and various and sundry other artifacts that will exist only for the life of that HTTP request. And then you're going to tell JSF to chuck it all because you're taking over the output stream. The illogic of waste, Mr. Spock.
I practice what I preach. Everything must be as simple as possible, but no simpler. I have very few webapps that exploit JSF internal functions or data structures, because JSF is so good at what it does and because JSF gives me the flexibility to extend outside of itself when the solution is more effective that way.
I did however, get seriously nailed because one of them required hooks into the EL subsystem and that part of JSF changed radically not long ago. Java is not Microsoft where they just up and discard an API in favor of a newer, allegedly better but totally incompatible API, so any change of that magnitude isn't done frivolously. But it was done and it cost me. Just because an architecture is a standard doesn't mean that its lower levels are immutable.