What is the difference between FacesContext and ExternalContext - jsf-2

What is the difference between FacesContext and ExternalContext? When can I use one or other? What has the one and what has the other?
The following sample is from the book JavaServer Faces 3rd edition:
<h:commandButton ... actionListener="#{rushmore.handleMouseClick}" />
Backing bean:
public void handleMouseClick(ActionEvent e) {
FacesContext context = FacesContext.getCurrentInstance();
String clientId = e.getComponent().getClientId(context);
Map<String, String> requestParams = context.getExternalContext().getRequestParameterMap();
// ...
}
Why is request parameter in ExternalContext? What is clientId? Is it generated by JSF when the application is started?

Carefully look in their javadocs to see what methods they offer and what exactly those methods all do.
FacesContext javadoc
ExternalContext javadoc
If you look closer at those methods listed in the javadoc, you'll notice that the FacesContext generally offers access to JSF-specific artifacts which are further in no way related to the "underlying" Servlet or Portlet API for which JSF is been designed to run on top of. E.g. creating converters, validators, components, EL expressions, etcetera and obtaining information about view root, supported locales, etcetera and adding phase listeners, system event listeners, etcetera. Everything which is specific to JSF API.
And, ExternalContext generally offers access to Servlet or Portlet-specific artifacts which JSF is currently using "under the covers". E.g., when running on a Servlet container, the HTTP servlet request, HTTP servlet response, HTTP session and Servlet context and inherently also all of their artifacts. Click those links, you'll see that they in turn offer methods which are also been delegated by the ExternalContext, such as getRequestParameterMap(). See also the javadoc. Yes, also click that link, you'll see that it explicitly mentions the servlet request:
Servlet: This must be the set of parameters available via the javax.servlet.ServletRequest methods getParameter() and getParameterNames().
There's nothing which can be offered by the both contexts. So there would be absolutely no reason to prefer the one or the other. Just use the right one for the job you need to perform.
As to the client ID, it's indeed generated by JSF, but definitely not on server's startup. It's just generated for every single JSF component on a per-view basis. In case of input components like <h:inputText>, which generates a HTML <input> element, it also becomes the name attribute like so
<input type="text" id="formId:inputId" name="formId:inputId" ... />
The formId:inputId is exactly the JSF client ID. It becomes the request parameter name. The HTML representation of the command button has also a name which ends up as request parameter name with the button's value as parameter value.

Related

using <set> tag in grails

I am new to grails. I came across a set tag which we can use in gsp pages itself to set the values which is similar to setting model from the controller.
<g:set var="home" value="something" />
so that when we write ${home} it outputs "something".
Is there any way to set the value in sessions in gsp pages itself and not from controller using set tag?
Yes you can do it in gsp pages as well. You just have to include an extra attribute scope to indicate which scopes(session, flash, page and request) you are setting the value to.
<g:set var="home" value="something" scope="session" />
If you do not include the scope option then it defaults to page.
To display the the value you just have to write ${session.home} or ${request.home} or simply ${home} for request scope. Hope this helps.
For more : https://grails.github.io/grails-doc/3.0.x/ref/Tags/set.html
Well! above answer suffices the need. Just wanted to add one more thing that gsp pages comprises of jsp internally and hence all the 9 implict objects are available on gsp pages as well.
request HttpServletRequest object
response HttpServletResponse object
out PrintWriter object used to send output to the client.
session HttpSession object
application ServletContext object associated with application context.
config ServletConfig object associated with the page.
pageContext server-specific features JspWriters.
page synonym for this
Exception handling exceptions and error page redirects.An instance of javax.servlet.jsp.JspException
You could at any point of time access these in your gsp pages.
More you can read from this.
Hope it helps!

How to disable JSF components programmatically

We have a JSF application with <rich:tab> which shows fields depending of some configuration stored in a database, so the components are not defined in the .xhtml page but have to be generated programmatically such in this example:
Components are generated in a panel:
<rich:tab id="someTab" header="#{msg['someHeader']}" immediate="true">
<rich:messages/>
<h:panelGrid id="generatedComponentsContainer"/>
</rich:tab>
Component generation example (simplified for simplicity):
FacesContext ctx = FacesContext.getCurrentInstance();
UIPanel panel = (UIPanel) ctx.getViewRoot().findComponent("someForm:generatedComponentsContainer");
text = (UIInput) ctx.getApplication().createComponent(ctx, "javax.faces.Input", "javax.faces.component.UIInput");
text.getAttributes().put("label", someLabel);
panel.getChildren().add(text);
Those components have to be shown disabled depending on some condition, so I used the following code to disable each of them if needed:
if (!showEnabled) { text.getAttributes().put("disabled", "true"); }
This method works for UIInput and HtmlInputTextarea but it is not working for UICalendar, throwing a IllegalArgumentException (argument type mismatch).
How can I disable the calendar?
I have been also wondering if this code just disables the component at the client side leaving it enabled at the server. This would probably be a security threat as somebody could enable a component via Javascript and submit the form to the server. I am not sure about this being possible, please advise if I am wrong.
After further research I noticed there are some classes that extend the ones we were using in our project. Those classes have a getter/setter for the disabled attribute which also disables the component in the server side. I tested this disabling the components programmatically and removing the disabled attribute while browsing the page to allow edition and submit. When submitting the form, the values are setted in the request but ignored at the server side. Bean values remain unaltered.
The classes we have used:
HtmlInputTextarea instead of UIInput
HtmlInputText instead of UIInput
We were already using UICalendar, which fits the purpose
A sample of code:
HtmlInputText text = (HtmlInputText) ctx.getApplication().createComponent(
ctx, HtmlInputText.COMPONENT_TYPE, "javax.faces.component.html.HtmlInputText");
if (!showEnabled) { text.setDisabled(true); }
When debugging the contents of the HtmlInputText you can see a ComponentStateHelper object (named stateHelper) which stores the disabled state of the component (among other data). Its superinterface is StateHolder:
public interface StateHolder
This interface is implemented by classes that need to save their state
between requests.
I understand that server-side state of the component is stored in this object, but I am not sure whether it is stored only here or in more points, or even if my interpretation of its purpose is correct. Feedback from an expert would be very useful.

CDI bean List in datatable is null on submit from JSF

Please note: This question is about CDI scopes as we are using CDI scopes in the app and not JSF scopes.
1) Controller Bean (TestController.java) which is in RequestScoped (enterprise context) is called index_cut.xhtml, when we come for first time on this page.
2) On button “Load”, we load the following method to populate the sapFinancialPeriodList which works fine and displays the data
3) After changing the content on the page and submitting, the sapFinancialPeriodList appears as NULL in the following method –
Any suggestions?
Your bean is request scoped and you're loading the data model on action only instead of on (post)construction. When the HTTP response after the action which loaded the data is finished, then the bean is garbaged. The subsequent request would get a brand new instance of the bean with all properties set to default. However, as the same data model isn't been preserved during (post)construct, it remains empty.
In JSF2 you'd solve this with using #ViewScoped. This way the bean will live as long as you're interacting with the same view by postbacks (which return null or void).
In CDI you'd need to solve this using #ConversationScoped, which in turn requires some additional #Inject Conversation boilerplate, complete with begin() and end() calls at the right moments. For a concrete example, see also What scope to use in JSF 2.0 for Wizard pattern?.
An alternative is to pass the parameters responsible for creating the data model to the subsequent request via <f:param> in the command link/button as follows
<h:commandButton value="save" ...>
<f:param name="period" value="#{bean.period}" />
</h:commandButton>
and then recreate exactly the same data model in (post)constructor of the request scoped bean as follows
String period = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("period");
List<SapFinancialPeriod> sapFinancialPeriodList = someservice.list(period);
(the above is by the way nicer to solve with #ManagedProperty if you were using standard JSF; as far as I know CDI doesn't have an annotation which enables you to set a HTTP request parameter as a bean property)
See also:
How to choose the right bean scope?
Unrelated to the concrete problem, the upcoming JSF 2.2 solves this functional requirement in a nicer way using the new "Faces Flow" feature with the new #FlowScoped annotation and the new xmlns:j="http://java.sun.com/jsf/flow" tags.

Show an InputStream as dynamic image in JSF

How can we embed and show an InputStream as dynamic image in JSF 2.0 with OmniFaces?
OmniFaces does not offer any utility for this — yet.
If the image files are located on the disk file system, then you need to create a virtual context in the servletcontainer configuration so that they can be accessed by a normal URL. See also Load images from outside of webapps / webcontext / deploy folder using <h:graphicImage> or <img> tag.
If the image files are stored in the DB, then you need to create a simple servlet which just writes the InputStream of the image from the DB to the OutputStream of the HTTP response. See also How to retrieve and display images from a database in a JSP page? (note that this doesn't require JSP/HTML, you can as good just use <h:graphicImage> as it merely generates a HTML <img> element).
There's the PrimeFaces <p:graphicImage>, but this is a bit unintuitive to implement. See also Display dynamic image from database with p:graphicImage and StreamedContent.
Update: since OmniFaces 2.0 (for JSF 2.2) there's a <o:graphicImage> component which supports among others directly referencing a byte[] or InputStream property in an #ApplicationScoped managed bean in an intuitive way like below:
<o:graphicImage value="#{imageStreamer.getById(bean.imageId)}" />
#Named
#ApplicationScoped
public class ImageStreamer {
#Inject
private ImageService service;
public InputStream getById(Long id) { // byte[] is also supported.
return service.getContent(id);
}
}
In contrary to PrimeFaces <p:graphicImage>, no <f:param> is needed and the EL method arguments are evaluated during render response phase, but the EL method itself is only invoked when the browser actually requests the image. See also the showcase and the blog on the subject.

Difference between the Action Context and ServletActionContext

Hi I have Question we can use both Action Context and Servlet Action Context to access the resources But why Struts2 people implemented two if they work same
They don't work the same; one has web-app-specific functionality.
XWork is not a web app framework--hence the ActionContext. WebWork/Struts 2 added web-specific functionality, hence ServletActionContext, which is a subclass of ActionContext, and adds web-related stuff.
As quoted in:
Servlet Action Description
Servlet Action Context is a sub class of Action Context.
"ServletActionContext is Web-specific context information for actions".This class adds access to web objects like servlet parameters, request attributes and things like the HTTP session. In simple terms one can say Action Context is generic while the servlet action context is more specific in terms of its usage
For Example: GenericServlet and HttpServlet; GenericServlet is for servlets that might not use HTTP, like for instance FTP servlets etc. while HttpServlet is more specific.

Resources